Version Description
- January 10, 2022 =
Update: Security Update
Download this release
Release Info
Developer | themeum |
Plugin | Tutor LMS – eLearning and online course solution |
Version | 1.9.13 |
Comparing to | |
See all releases |
Code changes from version 1.9.12 to 1.9.13
- classes/Addons.php +65 -109
- classes/Admin.php +10 -10
- classes/Ajax.php +359 -288
- classes/Assets.php +135 -132
- classes/Course.php +693 -638
- classes/Course_Filter.php +157 -148
- classes/Course_Settings_Tabs.php +117 -116
- classes/Course_Widget.php +79 -69
- classes/Dashboard.php +36 -30
- classes/FormHandler.php +51 -48
- classes/Instructors_List.php +105 -94
- classes/Lesson.php +155 -155
- classes/Options.php +12 -11
- classes/Post_types.php +6 -6
- classes/Question_Answers_List.php +58 -53
- classes/Quiz.php +704 -671
- classes/Quiz_Attempts_List.php +95 -90
- classes/Shortcode.php +14 -14
- classes/Student.php +7 -7
- classes/Taxonomies.php +3 -3
- classes/Template.php +3 -3
- classes/TutorEDD.php +1 -1
- classes/Tutor_List_Table.php +264 -183
- classes/Tutor_Setup.php +33 -33
- classes/Upgrader.php +40 -41
- classes/User.php +89 -73
- classes/Utils.php +2382 -1942
- classes/Video_Stream.php +51 -43
- classes/Withdraw.php +122 -118
- classes/Withdraw_Requests_List.php +123 -102
- classes/WooCommerce.php +255 -233
- includes/tinymce_translate.php +4 -3
- includes/tutor-general-functions.php +342 -272
- includes/tutor-template-functions.php +1009 -972
- languages/tutor.pot +888 -896
- readme.txt +5 -1
- templates/archive-course.php +1 -1
- templates/course-filter/filters.php +3 -3
- templates/dashboard.php +194 -186
- templates/dashboard/announcements.php +158 -155
- templates/dashboard/announcements/create.php +4 -4
- templates/dashboard/announcements/update.php +1 -1
- templates/dashboard/assignments.php +63 -96
classes/Addons.php
CHANGED
@@ -11,144 +11,100 @@
|
|
11 |
|
12 |
namespace TUTOR;
|
13 |
|
14 |
-
if ( ! defined( 'ABSPATH' ) )
|
15 |
exit;
|
|
|
16 |
|
17 |
class Addons {
|
18 |
|
19 |
public function __construct() {
|
20 |
-
add_filter('tutor_pro_addons_lists_for_display', array($this, 'tutor_addons_lists_to_show'));
|
21 |
}
|
22 |
|
23 |
-
public function tutor_addons_lists_to_show(){
|
24 |
$addons = array(
|
25 |
-
'buddypress'
|
26 |
-
'name'
|
27 |
-
'description'
|
28 |
),
|
29 |
-
'gradebook'
|
30 |
-
'name'
|
31 |
-
'description'
|
32 |
),
|
33 |
-
'content-drip'
|
34 |
-
'name'
|
35 |
-
'description'
|
36 |
),
|
37 |
-
'enrollments'
|
38 |
-
'name'
|
39 |
-
'description'
|
40 |
),
|
41 |
-
'wc-subscriptions'
|
42 |
-
'name'
|
43 |
-
'description'
|
44 |
),
|
45 |
-
'pmpro'
|
46 |
-
'name'
|
47 |
-
'description'
|
48 |
),
|
49 |
-
'restrict-content-pro'
|
50 |
-
'name'
|
51 |
-
'description'
|
52 |
),
|
53 |
-
'tutor-assignments'
|
54 |
-
'name'
|
55 |
-
'description'
|
56 |
),
|
57 |
-
'tutor-certificate'
|
58 |
-
'name'
|
59 |
-
'description'
|
60 |
),
|
61 |
'tutor-course-attachments' => array(
|
62 |
-
'name'
|
63 |
-
'description'
|
64 |
),
|
65 |
-
'tutor-course-preview'
|
66 |
-
'name'
|
67 |
-
'description'
|
68 |
),
|
69 |
-
'tutor-email'
|
70 |
-
'name'
|
71 |
-
'description'
|
72 |
),
|
73 |
-
'tutor-multi-instructors'
|
74 |
-
'name'
|
75 |
-
'description'
|
76 |
),
|
77 |
-
'tutor-prerequisites'
|
78 |
-
'name'
|
79 |
-
'description'
|
80 |
),
|
81 |
-
'tutor-report'
|
82 |
-
'name'
|
83 |
-
'description'
|
84 |
),
|
85 |
-
'quiz-import-export'
|
86 |
-
'name'
|
87 |
-
'description'
|
88 |
),
|
89 |
-
'tutor-zoom'
|
90 |
-
'name'
|
91 |
-
'description'
|
92 |
),
|
93 |
-
'google-classroom'
|
94 |
-
'name'
|
95 |
-
'description'
|
96 |
),
|
97 |
-
'push-notification'
|
98 |
-
'name'
|
99 |
-
'description'
|
|
|
|
|
|
|
|
|
100 |
),
|
101 |
-
'tutor-wpml' => array(
|
102 |
-
'name' => __('WPML Multilingual CMS', 'tutor'),
|
103 |
-
'description' => __('Create multilingual courses, lessons, dashboard and more for a global audience.', 'tutor')
|
104 |
-
)
|
105 |
);
|
106 |
|
107 |
return $addons;
|
108 |
}
|
109 |
-
|
110 |
-
|
111 |
-
/**
|
112 |
-
* @deprecated from alpha version
|
113 |
-
*/
|
114 |
-
|
115 |
-
public function addons_page(){
|
116 |
-
|
117 |
-
if ( false === ( $addons_themes_data = get_transient( 'tutor_addons_themes_data' ) ) ) {
|
118 |
-
//Request New
|
119 |
-
$api_endpoint = 'https://www.themeum.com/wp-json/addon-serve/v2/get-products';
|
120 |
-
$response = wp_remote_post( $api_endpoint, array(
|
121 |
-
'method' => 'POST',
|
122 |
-
'timeout' => 45,
|
123 |
-
'user-agent' => 'Tutor/'.TUTOR_VERSION.'; '.home_url( '/' ),
|
124 |
-
'headers' => array(
|
125 |
-
'wp_blog' => home_url( '/' )
|
126 |
-
),
|
127 |
-
'body' => array('plugin_slug' => 'tutor', 'wp_blog' => home_url( '/' )),
|
128 |
-
)
|
129 |
-
);
|
130 |
-
|
131 |
-
if ( is_wp_error( $response ) ) {
|
132 |
-
$error_message = $response->get_error_message();
|
133 |
-
echo "Something went wrong: $error_message";
|
134 |
-
} else {
|
135 |
-
if (tutor_utils()->avalue_dot('body', $response) && tutor_utils()->avalue_dot('response.code', $response) == 200 ){
|
136 |
-
$api_data = tutor_utils()->avalue_dot('body', $response);
|
137 |
-
|
138 |
-
$addons_themes_data = array(
|
139 |
-
'last_checked_time' => tutor_time(),
|
140 |
-
'data' => $api_data,
|
141 |
-
);
|
142 |
-
}
|
143 |
-
}
|
144 |
-
|
145 |
-
//Save the Final api call result on the database
|
146 |
-
set_transient( 'tutor_addons_themes_data', $addons_themes_data, 6 * HOUR_IN_SECONDS );
|
147 |
-
}
|
148 |
-
|
149 |
-
|
150 |
-
//Finally Show the View Page
|
151 |
-
include tutor()->path.'views/pages/addons.php';
|
152 |
-
}
|
153 |
-
|
154 |
-
}
|
11 |
|
12 |
namespace TUTOR;
|
13 |
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
exit;
|
16 |
+
}
|
17 |
|
18 |
class Addons {
|
19 |
|
20 |
public function __construct() {
|
21 |
+
add_filter( 'tutor_pro_addons_lists_for_display', array( $this, 'tutor_addons_lists_to_show' ) );
|
22 |
}
|
23 |
|
24 |
+
public function tutor_addons_lists_to_show() {
|
25 |
$addons = array(
|
26 |
+
'buddypress' => array(
|
27 |
+
'name' => __( 'BuddyPress', 'tutor' ),
|
28 |
+
'description' => 'Discuss about course and share your knowledge with your friends through BuddyPress',
|
29 |
),
|
30 |
+
'gradebook' => array(
|
31 |
+
'name' => __( 'Gradebook', 'tutor' ),
|
32 |
+
'description' => 'Shows student progress from assignment and quiz',
|
33 |
),
|
34 |
+
'content-drip' => array(
|
35 |
+
'name' => __( 'Content Drip', 'tutor' ),
|
36 |
+
'description' => 'Unlock lessons by schedule or when the student meets specific condition.',
|
37 |
),
|
38 |
+
'enrollments' => array(
|
39 |
+
'name' => __( 'Enrollments', 'tutor' ),
|
40 |
+
'description' => 'Take advanced control on enrollments. Enroll the student manually.',
|
41 |
),
|
42 |
+
'wc-subscriptions' => array(
|
43 |
+
'name' => __( 'WooCommerce Subscriptions', 'tutor' ),
|
44 |
+
'description' => 'Capture Residual Revenue with Recurring Payments.',
|
45 |
),
|
46 |
+
'pmpro' => array(
|
47 |
+
'name' => __( 'Paid Memberships Pro', 'tutor' ),
|
48 |
+
'description' => 'Maximize revenue by selling membership access to all of your courses.',
|
49 |
),
|
50 |
+
'restrict-content-pro' => array(
|
51 |
+
'name' => __( 'Restrict Content Pro', 'tutor' ),
|
52 |
+
'description' => 'Unlock Course depending on Restrict Content Pro Plugin Permission.',
|
53 |
),
|
54 |
+
'tutor-assignments' => array(
|
55 |
+
'name' => __( 'Tutor Assignments', 'tutor' ),
|
56 |
+
'description' => 'Tutor assignments is a great way to assign tasks to students.',
|
57 |
),
|
58 |
+
'tutor-certificate' => array(
|
59 |
+
'name' => __( 'Tutor Certificate', 'tutor' ),
|
60 |
+
'description' => 'Students will be able to download a certificate after course completion.',
|
61 |
),
|
62 |
'tutor-course-attachments' => array(
|
63 |
+
'name' => __( 'Tutor Course Attachments', 'tutor' ),
|
64 |
+
'description' => 'Add unlimited attachments/ private files to any Tutor course',
|
65 |
),
|
66 |
+
'tutor-course-preview' => array(
|
67 |
+
'name' => __( 'Tutor Course Preview', 'tutor' ),
|
68 |
+
'description' => 'Unlock some lessons for students before enrollment.',
|
69 |
),
|
70 |
+
'tutor-email' => array(
|
71 |
+
'name' => __( 'Tutor E-Mail', 'tutor' ),
|
72 |
+
'description' => 'Send email on various tutor events',
|
73 |
),
|
74 |
+
'tutor-multi-instructors' => array(
|
75 |
+
'name' => __( 'Tutor Multi Instructors', 'tutor' ),
|
76 |
+
'description' => 'Start a course with multiple instructors by Tutor Multi Instructors',
|
77 |
),
|
78 |
+
'tutor-prerequisites' => array(
|
79 |
+
'name' => __( 'Tutor Prerequisites', 'tutor' ),
|
80 |
+
'description' => 'Specific course you must complete before you can enroll new course by Tutor Prerequisites',
|
81 |
),
|
82 |
+
'tutor-report' => array(
|
83 |
+
'name' => __( 'Tutor Report', 'tutor' ),
|
84 |
+
'description' => 'Check your course performance through Tutor Report stats.',
|
85 |
),
|
86 |
+
'quiz-import-export' => array(
|
87 |
+
'name' => __( 'Quiz Export/Import', 'tutor' ),
|
88 |
+
'description' => __( 'Save time by exporting/importing quiz data with easy options.', 'tutor' ),
|
89 |
),
|
90 |
+
'tutor-zoom' => array(
|
91 |
+
'name' => __( 'Tutor Zoom Integration', 'tutor' ),
|
92 |
+
'description' => __( 'Connect Tutor LMS with Zoom to host live online classes. Students can attend live classes right from the lesson page.', 'tutor' ),
|
93 |
),
|
94 |
+
'google-classroom' => array(
|
95 |
+
'name' => __( 'Google Classroom Integration', 'tutor' ),
|
96 |
+
'description' => __( 'Helps connect Google Classrooms with Tutor LMS courses, allowing you to use features like Classroom streams and files directly from the Tutor LMS course.', 'tutor' ),
|
97 |
),
|
98 |
+
'push-notification' => array(
|
99 |
+
'name' => 'Push Notification',
|
100 |
+
'description' => 'Users will get push notification on specified events.',
|
101 |
+
),
|
102 |
+
'tutor-wpml' => array(
|
103 |
+
'name' => __( 'WPML Multilingual CMS', 'tutor' ),
|
104 |
+
'description' => __( 'Create multilingual courses, lessons, dashboard and more for a global audience.', 'tutor' ),
|
105 |
),
|
|
|
|
|
|
|
|
|
106 |
);
|
107 |
|
108 |
return $addons;
|
109 |
}
|
110 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Admin.php
CHANGED
@@ -62,7 +62,7 @@ class Admin{
|
|
62 |
if ($enable_course_marketplace) {
|
63 |
add_submenu_page('tutor', __('Instructors', 'tutor'), __('Instructors', 'tutor'), 'manage_tutor', Instructors_List::INSTRUCTOR_LIST_PAGE, array($this, 'tutor_instructors'));
|
64 |
}
|
65 |
-
|
66 |
add_submenu_page('tutor', __('Announcements', 'tutor'), __('Announcements', 'tutor'), 'manage_tutor_instructor', 'tutor_announcements', array($this, 'tutor_announcements'));
|
67 |
|
68 |
add_submenu_page('tutor', __('Q & A', 'tutor'), __('Q & A ', 'tutor').$unanswered_bubble, 'manage_tutor_instructor', Question_Answers_List::Question_Answer_PAGE, array($this, 'question_answer') );
|
@@ -130,7 +130,7 @@ class Admin{
|
|
130 |
}
|
131 |
|
132 |
public function tutor_tools(){
|
133 |
-
$tutor_admin_tools_page = tutils()->array_get('tutor_admin_tools_page', $_GET);
|
134 |
if ($tutor_admin_tools_page){
|
135 |
include apply_filters('tutor_admin_tools_page', tutor()->path."views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page);
|
136 |
}else{
|
@@ -159,7 +159,7 @@ class Admin{
|
|
159 |
}
|
160 |
|
161 |
public function parent_menu_active( $parent_file ){
|
162 |
-
$taxonomy = tutor_utils()->avalue_dot('taxonomy', $_GET);
|
163 |
if ($taxonomy === 'course-category' || $taxonomy === 'course-tag'){
|
164 |
return 'tutor';
|
165 |
}
|
@@ -168,7 +168,7 @@ class Admin{
|
|
168 |
}
|
169 |
|
170 |
public function submenu_file_active($submenu_file, $parent_file){
|
171 |
-
$taxonomy = tutor_utils()->avalue_dot('taxonomy', $_GET);
|
172 |
$course_post_type = tutor()->course_post_type;
|
173 |
|
174 |
if ($taxonomy === 'course-category'){
|
@@ -193,7 +193,7 @@ class Admin{
|
|
193 |
}
|
194 |
|
195 |
public function posts_clauses_request($clauses){
|
196 |
-
|
197 |
if(!is_admin() || (!isset($_GET['post_type']) || $_GET['post_type']!='courses') || tutor_utils()->has_user_role(array('administrator', 'editor'))) {
|
198 |
return $clauses;
|
199 |
}
|
@@ -205,14 +205,14 @@ class Admin{
|
|
205 |
|
206 |
$get_assigned_courses_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id' AND user_id = %d", $user_id));
|
207 |
$own_courses = is_array($get_assigned_courses_ids) ? $get_assigned_courses_ids : array();
|
208 |
-
|
209 |
$in_query_pre = count($own_courses) ? implode(',', $own_courses) : null;
|
210 |
$in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
|
211 |
|
212 |
$custom_author_query = " AND ({$wpdb->posts}.post_type!='courses' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
|
213 |
-
|
214 |
$clauses['where'] .= $custom_author_query;
|
215 |
-
|
216 |
return $clauses;
|
217 |
}
|
218 |
|
@@ -237,8 +237,8 @@ class Admin{
|
|
237 |
global $wpdb;
|
238 |
|
239 |
$get_assigned_courses_ids = (int) $wpdb->get_var($wpdb->prepare(
|
240 |
-
"SELECT user_id
|
241 |
-
from {$wpdb->usermeta}
|
242 |
WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ", $current_user, $get_post_id));
|
243 |
|
244 |
if ( ! $get_assigned_courses_ids){
|
62 |
if ($enable_course_marketplace) {
|
63 |
add_submenu_page('tutor', __('Instructors', 'tutor'), __('Instructors', 'tutor'), 'manage_tutor', Instructors_List::INSTRUCTOR_LIST_PAGE, array($this, 'tutor_instructors'));
|
64 |
}
|
65 |
+
|
66 |
add_submenu_page('tutor', __('Announcements', 'tutor'), __('Announcements', 'tutor'), 'manage_tutor_instructor', 'tutor_announcements', array($this, 'tutor_announcements'));
|
67 |
|
68 |
add_submenu_page('tutor', __('Q & A', 'tutor'), __('Q & A ', 'tutor').$unanswered_bubble, 'manage_tutor_instructor', Question_Answers_List::Question_Answer_PAGE, array($this, 'question_answer') );
|
130 |
}
|
131 |
|
132 |
public function tutor_tools(){
|
133 |
+
$tutor_admin_tools_page = tutils()->array_get('tutor_admin_tools_page', tutor_sanitize_data($_GET));
|
134 |
if ($tutor_admin_tools_page){
|
135 |
include apply_filters('tutor_admin_tools_page', tutor()->path."views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page);
|
136 |
}else{
|
159 |
}
|
160 |
|
161 |
public function parent_menu_active( $parent_file ){
|
162 |
+
$taxonomy = tutor_utils()->avalue_dot('taxonomy', tutor_sanitize_data($_GET));
|
163 |
if ($taxonomy === 'course-category' || $taxonomy === 'course-tag'){
|
164 |
return 'tutor';
|
165 |
}
|
168 |
}
|
169 |
|
170 |
public function submenu_file_active($submenu_file, $parent_file){
|
171 |
+
$taxonomy = tutor_utils()->avalue_dot('taxonomy', tutor_sanitize_data($_GET));
|
172 |
$course_post_type = tutor()->course_post_type;
|
173 |
|
174 |
if ($taxonomy === 'course-category'){
|
193 |
}
|
194 |
|
195 |
public function posts_clauses_request($clauses){
|
196 |
+
|
197 |
if(!is_admin() || (!isset($_GET['post_type']) || $_GET['post_type']!='courses') || tutor_utils()->has_user_role(array('administrator', 'editor'))) {
|
198 |
return $clauses;
|
199 |
}
|
205 |
|
206 |
$get_assigned_courses_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id' AND user_id = %d", $user_id));
|
207 |
$own_courses = is_array($get_assigned_courses_ids) ? $get_assigned_courses_ids : array();
|
208 |
+
|
209 |
$in_query_pre = count($own_courses) ? implode(',', $own_courses) : null;
|
210 |
$in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
|
211 |
|
212 |
$custom_author_query = " AND ({$wpdb->posts}.post_type!='courses' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
|
213 |
+
|
214 |
$clauses['where'] .= $custom_author_query;
|
215 |
+
|
216 |
return $clauses;
|
217 |
}
|
218 |
|
237 |
global $wpdb;
|
238 |
|
239 |
$get_assigned_courses_ids = (int) $wpdb->get_var($wpdb->prepare(
|
240 |
+
"SELECT user_id
|
241 |
+
from {$wpdb->usermeta}
|
242 |
WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ", $current_user, $get_post_id));
|
243 |
|
244 |
if ( ! $get_assigned_courses_ids){
|
classes/Ajax.php
CHANGED
@@ -1,46 +1,50 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
class Ajax{
|
8 |
public function __construct() {
|
9 |
|
10 |
-
add_action('wp_ajax_sync_video_playback', array($this, 'sync_video_playback'));
|
11 |
-
add_action('wp_ajax_nopriv_sync_video_playback', array($this, 'sync_video_playback_noprev'));
|
12 |
-
add_action('wp_ajax_tutor_place_rating', array($this, 'tutor_place_rating'));
|
13 |
|
14 |
-
add_action('wp_ajax_tutor_ask_question', array($this, 'tutor_ask_question'));
|
15 |
-
add_action('wp_ajax_tutor_add_answer', array($this, 'tutor_add_answer'));
|
16 |
|
17 |
-
add_action('wp_ajax_tutor_course_add_to_wishlist', array($this, 'tutor_course_add_to_wishlist'));
|
18 |
-
add_action('wp_ajax_nopriv_tutor_course_add_to_wishlist', array($this, 'tutor_course_add_to_wishlist'));
|
19 |
|
20 |
/**
|
21 |
* Addon Enable Disable Control
|
22 |
*/
|
23 |
-
add_action('wp_ajax_addon_enable_disable', array($this, 'addon_enable_disable'));
|
24 |
|
25 |
/**
|
26 |
* Update Rating/review
|
|
|
27 |
* @since v.1.4.0
|
28 |
*/
|
29 |
-
add_action('wp_ajax_tutor_load_edit_review_modal', array($this, 'tutor_load_edit_review_modal'));
|
30 |
-
add_action('wp_ajax_tutor_update_review_modal', array($this, 'tutor_update_review_modal'));
|
31 |
|
32 |
/**
|
33 |
* Ajax login
|
|
|
34 |
* @since v.1.6.3
|
35 |
*/
|
36 |
-
add_action('wp_ajax_nopriv_tutor_user_login', array($this, 'process_ajax_login'));
|
37 |
|
38 |
/**
|
39 |
* Announcement
|
|
|
40 |
* @since v.1.7.9
|
41 |
*/
|
42 |
-
add_action(
|
43 |
-
|
44 |
}
|
45 |
|
46 |
|
@@ -50,321 +54,384 @@ class Ajax{
|
|
50 |
*
|
51 |
* @since v.1.0.0
|
52 |
*/
|
53 |
-
public function sync_video_playback(){
|
54 |
tutor_utils()->checking_nonce();
|
55 |
|
56 |
-
$user_id
|
57 |
-
$post_id
|
58 |
-
$duration
|
59 |
-
$currentTime = sanitize_text_field($_POST['currentTime']);
|
60 |
|
61 |
-
if(!tutils()->has_enrolled_content_access('lesson', $post_id)) {
|
62 |
-
wp_send_json_error(array('message'=>__('Access Denied', 'tutor')));
|
63 |
exit;
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
* Update posts attached video
|
68 |
*/
|
69 |
-
$video = tutor_utils()->get_video($post_id);
|
70 |
|
71 |
-
if ($duration) {
|
72 |
-
$video['duration_sec'] = $duration; //secs
|
73 |
$video['playtime'] = tutor_utils()->playtime_string( $duration );
|
74 |
$video['runtime'] = tutor_utils()->playtime_array( $duration );
|
75 |
}
|
76 |
-
tutor_utils()->update_video($post_id, $video);
|
77 |
|
78 |
/**
|
79 |
* Sync Lesson Reading Info by Users
|
80 |
*/
|
81 |
|
82 |
-
$best_watch_time = tutor_utils()->get_lesson_reading_info($post_id, $user_id, 'video_best_watched_time');
|
83 |
-
if ($best_watch_time < $currentTime){
|
84 |
-
tutor_utils()->update_lesson_reading_info($post_id, $user_id, 'video_best_watched_time', $currentTime);
|
85 |
}
|
86 |
|
87 |
-
if (tutor_utils()->avalue_dot('is_ended', $_POST)){
|
88 |
-
tutor_utils()->mark_lesson_complete($post_id);
|
89 |
}
|
90 |
exit();
|
91 |
}
|
92 |
|
93 |
-
public function sync_video_playback_noprev(){
|
94 |
|
95 |
}
|
96 |
|
97 |
|
98 |
-
public function tutor_place_rating(){
|
99 |
global $wpdb;
|
100 |
|
101 |
tutils()->checking_nonce();
|
102 |
|
103 |
-
$rating
|
104 |
-
$course_id = sanitize_text_field(tutor_utils()->avalue_dot('course_id', $_POST));
|
105 |
-
$review
|
106 |
|
107 |
-
|
108 |
-
$rating>5 ? $rating = 5 : 0;
|
109 |
|
110 |
$user_id = get_current_user_id();
|
111 |
-
$user
|
112 |
-
$date
|
113 |
|
114 |
-
if(!tutils()->has_enrolled_content_access('course', $course_id)) {
|
115 |
-
wp_send_json_error(array('message'=>__('Access Denied', 'tutor')));
|
116 |
exit;
|
117 |
}
|
118 |
|
119 |
-
do_action('tutor_before_rating_placed');
|
120 |
|
121 |
-
$previous_rating_id = $wpdb->get_var($wpdb->prepare("select comment_ID from {$wpdb->comments} WHERE comment_post_ID = %d AND user_id = %d AND comment_type = 'tutor_course_rating' LIMIT 1;", $course_id, $user_id));
|
122 |
|
123 |
$review_ID = $previous_rating_id;
|
124 |
-
if ( $previous_rating_id){
|
125 |
-
$wpdb->update(
|
126 |
-
|
|
|
|
|
127 |
);
|
128 |
|
129 |
-
$rating_info = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->commentmeta} WHERE comment_id = %d AND meta_key = 'tutor_rating'; ", $previous_rating_id));
|
130 |
-
if ($rating_info){
|
131 |
-
$wpdb->update(
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
-
}else{
|
136 |
$data = array(
|
137 |
-
'comment_post_ID'
|
138 |
-
'comment_approved'
|
139 |
-
'comment_type'
|
140 |
-
'comment_date'
|
141 |
-
'comment_date_gmt'
|
142 |
-
'user_id'
|
143 |
-
'comment_author'
|
144 |
-
'comment_agent'
|
145 |
);
|
146 |
-
if ($review){
|
147 |
$data['comment_content'] = $review;
|
148 |
}
|
149 |
|
150 |
-
$wpdb->insert($wpdb->comments, $data);
|
151 |
$comment_id = (int) $wpdb->insert_id;
|
152 |
-
$review_ID
|
153 |
-
|
154 |
-
if ($comment_id){
|
155 |
-
$result = $wpdb->insert(
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
162 |
}
|
163 |
}
|
164 |
|
165 |
-
$data = array(
|
166 |
-
|
|
|
|
|
|
|
|
|
167 |
}
|
168 |
|
169 |
-
public function tutor_ask_question(){
|
170 |
tutor_utils()->checking_nonce();
|
171 |
|
172 |
global $wpdb;
|
173 |
|
174 |
-
$course_id
|
175 |
-
$question_title = sanitize_text_field($_POST['question_title']);
|
176 |
-
$question
|
177 |
|
178 |
-
if(!tutils()->has_enrolled_content_access('course', $course_id)) {
|
179 |
-
wp_send_json_error(array('message'=>__('Access Denied', 'tutor')));
|
180 |
exit;
|
181 |
}
|
182 |
|
183 |
-
if (empty($question) || empty($question_title)){
|
184 |
-
wp_send_json_error(__('Empty question title or body', 'tutor'));
|
185 |
}
|
186 |
|
187 |
$user_id = get_current_user_id();
|
188 |
-
$user
|
189 |
-
$date
|
190 |
-
|
191 |
-
do_action('tutor_before_add_question', $course_id);
|
192 |
-
$data = apply_filters(
|
193 |
-
'
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
|
|
|
|
|
|
205 |
$comment_id = (int) $wpdb->insert_id;
|
206 |
|
207 |
-
if ($comment_id){
|
208 |
-
$result = $wpdb->insert(
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
|
|
|
|
|
|
213 |
}
|
214 |
-
do_action('tutor_after_add_question', $course_id, $comment_id);
|
215 |
|
216 |
-
wp_send_json_success(__('Question has been added successfully', 'tutor'));
|
217 |
}
|
218 |
|
219 |
|
220 |
-
public function tutor_add_answer(){
|
221 |
tutor_utils()->checking_nonce();
|
222 |
global $wpdb;
|
223 |
|
224 |
-
$answer = wp_kses_post($_POST['answer']);
|
225 |
-
if ( ! $answer){
|
226 |
-
wp_send_json_error(__('Please write answer', 'tutor'));
|
227 |
}
|
228 |
|
229 |
-
$question_id = (int) sanitize_text_field($_POST['question_id']);
|
230 |
-
$question
|
231 |
|
232 |
$user_id = get_current_user_id();
|
233 |
-
$user
|
234 |
-
$date
|
235 |
|
236 |
-
if(!tutils()->has_enrolled_content_access('qa_question', $question_id)) {
|
237 |
-
wp_send_json_error(array('message'=>__('Access Denied', 'tutor')));
|
238 |
exit;
|
239 |
}
|
240 |
|
241 |
-
do_action('tutor_before_answer_to_question');
|
242 |
-
$data = apply_filters(
|
243 |
-
'
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
|
|
|
|
256 |
$comment_id = (int) $wpdb->insert_id;
|
257 |
-
do_action('tutor_after_answer_to_question', $comment_id);
|
258 |
|
259 |
-
wp_send_json_success(__('Answer has been added successfully', 'tutor'));
|
260 |
}
|
261 |
|
262 |
|
263 |
-
public function tutor_course_add_to_wishlist(){
|
264 |
tutils()->checking_nonce();
|
265 |
|
266 |
-
$course_id = (int) sanitize_text_field($_POST['course_id']);
|
267 |
-
if ( ! is_user_logged_in()){
|
268 |
-
wp_send_json_error(array('redirect_to' => wp_login_url( wp_get_referer() ) ) );
|
269 |
}
|
270 |
global $wpdb;
|
271 |
|
272 |
-
$user_id
|
273 |
-
$if_added_to_list = $wpdb->get_row($wpdb->prepare("SELECT * from {$wpdb->usermeta} WHERE user_id = %d AND meta_key = '_tutor_course_wishlist' AND meta_value = %d;", $user_id, $course_id));
|
274 |
-
|
275 |
-
if ( $if_added_to_list){
|
276 |
-
$wpdb->delete(
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
}
|
282 |
}
|
283 |
|
284 |
/**
|
285 |
* Method for enable / disable addons
|
286 |
*/
|
287 |
-
public function addon_enable_disable(){
|
288 |
|
289 |
-
if(!current_user_can( 'manage_options' )) {
|
290 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
291 |
}
|
292 |
|
293 |
-
$addonsConfig = maybe_unserialize(get_option('tutor_addons_config'));
|
294 |
|
295 |
-
$isEnable
|
296 |
-
$addonFieldName = sanitize_text_field(tutor_utils()->avalue_dot('addonFieldName', $_POST));
|
297 |
|
298 |
-
do_action('tutor_addon_before_enable_disable');
|
299 |
-
if ($isEnable){
|
300 |
-
do_action("tutor_addon_before_enable_{$addonFieldName}");
|
301 |
-
do_action('tutor_addon_before_enable', $addonFieldName);
|
302 |
-
$addonsConfig[$addonFieldName]['is_enable'] = 1;
|
303 |
-
update_option('tutor_addons_config', $addonsConfig);
|
304 |
|
305 |
-
do_action('tutor_addon_after_enable', $addonFieldName);
|
306 |
-
do_action("tutor_addon_after_enable_{$addonFieldName}");
|
307 |
-
}else{
|
308 |
-
do_action("tutor_addon_before_disable_{$addonFieldName}");
|
309 |
-
do_action('tutor_addon_before_disable', $addonFieldName);
|
310 |
-
$addonsConfig[$addonFieldName]['is_enable'] = 0;
|
311 |
-
update_option('tutor_addons_config', $addonsConfig);
|
312 |
|
313 |
-
do_action('tutor_addon_after_disable', $addonFieldName);
|
314 |
-
do_action("tutor_addon_after_disable_{$addonFieldName}");
|
315 |
}
|
316 |
|
317 |
-
do_action('tutor_addon_after_enable_disable');
|
318 |
wp_send_json_success();
|
319 |
}
|
320 |
|
321 |
/**
|
322 |
* Load review edit form
|
|
|
323 |
* @since v.1.4.0
|
324 |
*/
|
325 |
-
public function tutor_load_edit_review_modal(){
|
326 |
tutor_utils()->checking_nonce();
|
327 |
|
328 |
-
$review_id = (int) sanitize_text_field(tutils()->array_get('review_id', $_POST));
|
329 |
-
$rating
|
330 |
|
331 |
-
if(!tutils()->has_enrolled_content_access('review', $review_id)) {
|
332 |
-
wp_send_json_error(array('message'=>__('Access Denied', 'tutor')));
|
333 |
exit;
|
334 |
}
|
335 |
|
336 |
ob_start();
|
337 |
-
tutor_load_template('dashboard.reviews.edit-review-form', array('rating' => $rating));
|
338 |
$output = ob_get_clean();
|
339 |
|
340 |
-
wp_send_json_success(array('output' => $output));
|
341 |
}
|
342 |
|
343 |
-
public function tutor_update_review_modal(){
|
344 |
global $wpdb;
|
345 |
|
346 |
tutor_utils()->checking_nonce();
|
347 |
|
348 |
-
$review_id = (int) sanitize_text_field(tutils()->array_get('review_id', $_POST));
|
349 |
-
$rating
|
350 |
-
$review
|
351 |
|
352 |
-
if(!tutils()->has_enrolled_content_access('review', $review_id)) {
|
353 |
-
wp_send_json_error(array('message'=>__('Access Denied', 'tutor')));
|
354 |
exit;
|
355 |
}
|
356 |
|
357 |
-
$is_exists = $wpdb->get_var($wpdb->prepare("SELECT comment_ID from {$wpdb->comments} WHERE comment_ID=%d AND comment_type = 'tutor_course_rating' ;", $review_id));
|
358 |
|
359 |
-
if ( $is_exists) {
|
360 |
-
$wpdb->update(
|
|
|
|
|
361 |
array( 'comment_ID' => $review_id )
|
362 |
);
|
363 |
-
$wpdb->update(
|
364 |
-
|
|
|
|
|
|
|
|
|
|
|
365 |
);
|
366 |
|
367 |
-
do_action('tutor_after_review_update', $review_id, $is_exists);
|
368 |
|
369 |
wp_send_json_success();
|
370 |
}
|
@@ -373,14 +440,15 @@ class Ajax{
|
|
373 |
|
374 |
/**
|
375 |
* Process ajax login
|
|
|
376 |
* @since v.1.6.3
|
377 |
*/
|
378 |
-
public function process_ajax_login(){
|
379 |
tutils()->checking_nonce();
|
380 |
|
381 |
-
$username
|
382 |
-
$password
|
383 |
-
$redirect_to = tutils()->array_get('redirect_to', $_POST);
|
384 |
|
385 |
try {
|
386 |
$creds = array(
|
@@ -415,131 +483,134 @@ class Ajax{
|
|
415 |
if ( is_wp_error( $user ) ) {
|
416 |
$message = $user->get_error_message();
|
417 |
$message = str_replace( '<strong>' . esc_html( $creds['user_login'] ) . '</strong>', '<strong>' . esc_html( $creds['user_login'] ) . '</strong>', $message );
|
418 |
-
|
419 |
wp_send_json_error( $message );
|
420 |
} else {
|
421 |
-
//since 1.9.8 do enroll if guest attempt to enroll
|
422 |
do_action( 'tutor_do_enroll_after_login_if_attempt', $_POST['tutor_course_enroll_attempt'] );
|
423 |
-
|
424 |
-
wp_send_json_success([
|
425 |
-
'redirect' => apply_filters('tutor_login_redirect_url', $redirect_to)
|
426 |
-
]);
|
427 |
|
|
|
|
|
|
|
|
|
|
|
428 |
|
429 |
}
|
430 |
} catch ( \Exception $e ) {
|
431 |
-
wp_send_json_error( apply_filters( 'login_errors', $e->getMessage()) );
|
432 |
do_action( 'tutor_login_failed' );
|
433 |
}
|
434 |
}
|
435 |
|
436 |
/**
|
437 |
* Create/Update announcement
|
|
|
438 |
* @since v.1.7.9
|
439 |
*/
|
440 |
-
public function create_or_update_annoucement() {
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
tutils()->checking_nonce();
|
450 |
|
451 |
-
$course_id
|
452 |
-
$announcement_title
|
453 |
-
$announcement_summary = sanitize_textarea_field($_POST['tutor_announcement_summary']);
|
454 |
-
|
455 |
-
if(!tutils()->can_user_manage('course', $course_id)) {
|
456 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
457 |
}
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
'post_type'
|
462 |
-
'post_title'
|
463 |
'post_content' => $announcement_summary,
|
464 |
-
'post_parent'
|
465 |
-
'post_status'
|
466 |
-
|
467 |
|
468 |
-
|
469 |
-
|
470 |
-
|
|
|
|
|
|
|
|
|
471 |
|
472 |
-
|
473 |
-
if (empty($form_data['post_parent'])) {
|
474 |
-
$error['post_parent'] = __('Course name required','tutor');
|
475 |
|
|
|
|
|
476 |
}
|
477 |
-
|
478 |
-
|
479 |
-
|
|
|
480 |
}
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
$
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
}
|
513 |
-
wp_send_json($response);
|
514 |
-
}
|
515 |
-
}
|
516 |
-
}
|
517 |
|
518 |
/**
|
519 |
* Delete announcement
|
|
|
520 |
* @since v.1.7.9
|
521 |
*/
|
522 |
-
|
523 |
-
$announcement_id = sanitize_text_field($_POST['announcement_id']);
|
524 |
tutils()->checking_nonce();
|
525 |
|
526 |
-
if(!tutils()->can_user_manage('announcement', $announcement_id)) {
|
527 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
528 |
}
|
529 |
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
class Ajax {
|
9 |
public function __construct() {
|
10 |
|
11 |
+
add_action( 'wp_ajax_sync_video_playback', array( $this, 'sync_video_playback' ) );
|
12 |
+
add_action( 'wp_ajax_nopriv_sync_video_playback', array( $this, 'sync_video_playback_noprev' ) );
|
13 |
+
add_action( 'wp_ajax_tutor_place_rating', array( $this, 'tutor_place_rating' ) );
|
14 |
|
15 |
+
add_action( 'wp_ajax_tutor_ask_question', array( $this, 'tutor_ask_question' ) );
|
16 |
+
add_action( 'wp_ajax_tutor_add_answer', array( $this, 'tutor_add_answer' ) );
|
17 |
|
18 |
+
add_action( 'wp_ajax_tutor_course_add_to_wishlist', array( $this, 'tutor_course_add_to_wishlist' ) );
|
19 |
+
add_action( 'wp_ajax_nopriv_tutor_course_add_to_wishlist', array( $this, 'tutor_course_add_to_wishlist' ) );
|
20 |
|
21 |
/**
|
22 |
* Addon Enable Disable Control
|
23 |
*/
|
24 |
+
add_action( 'wp_ajax_addon_enable_disable', array( $this, 'addon_enable_disable' ) );
|
25 |
|
26 |
/**
|
27 |
* Update Rating/review
|
28 |
+
*
|
29 |
* @since v.1.4.0
|
30 |
*/
|
31 |
+
add_action( 'wp_ajax_tutor_load_edit_review_modal', array( $this, 'tutor_load_edit_review_modal' ) );
|
32 |
+
add_action( 'wp_ajax_tutor_update_review_modal', array( $this, 'tutor_update_review_modal' ) );
|
33 |
|
34 |
/**
|
35 |
* Ajax login
|
36 |
+
*
|
37 |
* @since v.1.6.3
|
38 |
*/
|
39 |
+
add_action( 'wp_ajax_nopriv_tutor_user_login', array( $this, 'process_ajax_login' ) );
|
40 |
|
41 |
/**
|
42 |
* Announcement
|
43 |
+
*
|
44 |
* @since v.1.7.9
|
45 |
*/
|
46 |
+
add_action( 'wp_ajax_tutor_announcement_create', array( $this, 'create_or_update_annoucement' ) );
|
47 |
+
add_action( 'wp_ajax_tutor_announcement_delete', array( $this, 'delete_annoucement' ) );
|
48 |
}
|
49 |
|
50 |
|
54 |
*
|
55 |
* @since v.1.0.0
|
56 |
*/
|
57 |
+
public function sync_video_playback() {
|
58 |
tutor_utils()->checking_nonce();
|
59 |
|
60 |
+
$user_id = get_current_user_id();
|
61 |
+
$post_id = isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : 0;
|
62 |
+
$duration = sanitize_text_field( $_POST['duration'] );
|
63 |
+
$currentTime = sanitize_text_field( $_POST['currentTime'] );
|
64 |
|
65 |
+
if ( ! tutils()->has_enrolled_content_access( 'lesson', $post_id ) ) {
|
66 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
67 |
exit;
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
* Update posts attached video
|
72 |
*/
|
73 |
+
$video = tutor_utils()->get_video( $post_id );
|
74 |
|
75 |
+
if ( $duration ) {
|
76 |
+
$video['duration_sec'] = $duration; // secs
|
77 |
$video['playtime'] = tutor_utils()->playtime_string( $duration );
|
78 |
$video['runtime'] = tutor_utils()->playtime_array( $duration );
|
79 |
}
|
80 |
+
tutor_utils()->update_video( $post_id, $video );
|
81 |
|
82 |
/**
|
83 |
* Sync Lesson Reading Info by Users
|
84 |
*/
|
85 |
|
86 |
+
$best_watch_time = tutor_utils()->get_lesson_reading_info( $post_id, $user_id, 'video_best_watched_time' );
|
87 |
+
if ( $best_watch_time < $currentTime ) {
|
88 |
+
tutor_utils()->update_lesson_reading_info( $post_id, $user_id, 'video_best_watched_time', $currentTime );
|
89 |
}
|
90 |
|
91 |
+
if ( tutor_utils()->avalue_dot( 'is_ended', $_POST ) ) {
|
92 |
+
tutor_utils()->mark_lesson_complete( $post_id );
|
93 |
}
|
94 |
exit();
|
95 |
}
|
96 |
|
97 |
+
public function sync_video_playback_noprev() {
|
98 |
|
99 |
}
|
100 |
|
101 |
|
102 |
+
public function tutor_place_rating() {
|
103 |
global $wpdb;
|
104 |
|
105 |
tutils()->checking_nonce();
|
106 |
|
107 |
+
$rating = sanitize_text_field( tutor_utils()->avalue_dot( 'rating', $_POST ) );
|
108 |
+
$course_id = sanitize_text_field( tutor_utils()->avalue_dot( 'course_id', $_POST ) );
|
109 |
+
$review = sanitize_textarea_field( tutor_utils()->avalue_dot( 'review', $_POST ) );
|
110 |
|
111 |
+
! $rating ? $rating = 0 : 0;
|
112 |
+
$rating > 5 ? $rating = 5 : 0;
|
113 |
|
114 |
$user_id = get_current_user_id();
|
115 |
+
$user = get_userdata( $user_id );
|
116 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
117 |
|
118 |
+
if ( ! tutils()->has_enrolled_content_access( 'course', $course_id ) ) {
|
119 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
120 |
exit;
|
121 |
}
|
122 |
|
123 |
+
do_action( 'tutor_before_rating_placed' );
|
124 |
|
125 |
+
$previous_rating_id = $wpdb->get_var( $wpdb->prepare( "select comment_ID from {$wpdb->comments} WHERE comment_post_ID = %d AND user_id = %d AND comment_type = 'tutor_course_rating' LIMIT 1;", $course_id, $user_id ) );
|
126 |
|
127 |
$review_ID = $previous_rating_id;
|
128 |
+
if ( $previous_rating_id ) {
|
129 |
+
$wpdb->update(
|
130 |
+
$wpdb->comments,
|
131 |
+
array( 'comment_content' => $review ),
|
132 |
+
array( 'comment_ID' => $previous_rating_id )
|
133 |
);
|
134 |
|
135 |
+
$rating_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->commentmeta} WHERE comment_id = %d AND meta_key = 'tutor_rating'; ", $previous_rating_id ) );
|
136 |
+
if ( $rating_info ) {
|
137 |
+
$wpdb->update(
|
138 |
+
$wpdb->commentmeta,
|
139 |
+
array( 'meta_value' => $rating ),
|
140 |
+
array(
|
141 |
+
'comment_id' => $previous_rating_id,
|
142 |
+
'meta_key' => 'tutor_rating',
|
143 |
+
)
|
144 |
+
);
|
145 |
+
} else {
|
146 |
+
$wpdb->insert(
|
147 |
+
$wpdb->commentmeta,
|
148 |
+
array(
|
149 |
+
'comment_id' => $previous_rating_id,
|
150 |
+
'meta_key' => 'tutor_rating',
|
151 |
+
'meta_value' => $rating,
|
152 |
+
)
|
153 |
+
);
|
154 |
}
|
155 |
+
} else {
|
156 |
$data = array(
|
157 |
+
'comment_post_ID' => esc_sql( $course_id ),
|
158 |
+
'comment_approved' => 'approved',
|
159 |
+
'comment_type' => 'tutor_course_rating',
|
160 |
+
'comment_date' => $date,
|
161 |
+
'comment_date_gmt' => get_gmt_from_date( $date ),
|
162 |
+
'user_id' => $user_id,
|
163 |
+
'comment_author' => $user->user_login,
|
164 |
+
'comment_agent' => 'TutorLMSPlugin',
|
165 |
);
|
166 |
+
if ( $review ) {
|
167 |
$data['comment_content'] = $review;
|
168 |
}
|
169 |
|
170 |
+
$wpdb->insert( $wpdb->comments, $data );
|
171 |
$comment_id = (int) $wpdb->insert_id;
|
172 |
+
$review_ID = $comment_id;
|
173 |
+
|
174 |
+
if ( $comment_id ) {
|
175 |
+
$result = $wpdb->insert(
|
176 |
+
$wpdb->commentmeta,
|
177 |
+
array(
|
178 |
+
'comment_id' => $comment_id,
|
179 |
+
'meta_key' => 'tutor_rating',
|
180 |
+
'meta_value' => $rating,
|
181 |
+
)
|
182 |
+
);
|
183 |
+
|
184 |
+
do_action( 'tutor_after_rating_placed', $comment_id );
|
185 |
}
|
186 |
}
|
187 |
|
188 |
+
$data = array(
|
189 |
+
'msg' => __( 'Rating placed success', 'tutor' ),
|
190 |
+
'review_id' => $review_ID,
|
191 |
+
'review' => $review,
|
192 |
+
);
|
193 |
+
wp_send_json_success( $data );
|
194 |
}
|
195 |
|
196 |
+
public function tutor_ask_question() {
|
197 |
tutor_utils()->checking_nonce();
|
198 |
|
199 |
global $wpdb;
|
200 |
|
201 |
+
$course_id = (int) sanitize_text_field( $_POST['tutor_course_id'] );
|
202 |
+
$question_title = sanitize_text_field( $_POST['question_title'] );
|
203 |
+
$question = wp_kses_post( $_POST['question'] );
|
204 |
|
205 |
+
if ( ! tutils()->has_enrolled_content_access( 'course', $course_id ) ) {
|
206 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
207 |
exit;
|
208 |
}
|
209 |
|
210 |
+
if ( empty( $question ) || empty( $question_title ) ) {
|
211 |
+
wp_send_json_error( __( 'Empty question title or body', 'tutor' ) );
|
212 |
}
|
213 |
|
214 |
$user_id = get_current_user_id();
|
215 |
+
$user = get_userdata( $user_id );
|
216 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
217 |
+
|
218 |
+
do_action( 'tutor_before_add_question', $course_id );
|
219 |
+
$data = apply_filters(
|
220 |
+
'tutor_add_question_data',
|
221 |
+
array(
|
222 |
+
'comment_post_ID' => $course_id,
|
223 |
+
'comment_author' => $user->user_login,
|
224 |
+
'comment_date' => $date,
|
225 |
+
'comment_date_gmt' => get_gmt_from_date( $date ),
|
226 |
+
'comment_content' => $question,
|
227 |
+
'comment_approved' => 'waiting_for_answer',
|
228 |
+
'comment_agent' => 'TutorLMSPlugin',
|
229 |
+
'comment_type' => 'tutor_q_and_a',
|
230 |
+
'user_id' => $user_id,
|
231 |
+
)
|
232 |
+
);
|
233 |
+
|
234 |
+
$wpdb->insert( $wpdb->comments, $data );
|
235 |
$comment_id = (int) $wpdb->insert_id;
|
236 |
|
237 |
+
if ( $comment_id ) {
|
238 |
+
$result = $wpdb->insert(
|
239 |
+
$wpdb->commentmeta,
|
240 |
+
array(
|
241 |
+
'comment_id' => $comment_id,
|
242 |
+
'meta_key' => 'tutor_question_title',
|
243 |
+
'meta_value' => $question_title,
|
244 |
+
)
|
245 |
+
);
|
246 |
}
|
247 |
+
do_action( 'tutor_after_add_question', $course_id, $comment_id );
|
248 |
|
249 |
+
wp_send_json_success( __( 'Question has been added successfully', 'tutor' ) );
|
250 |
}
|
251 |
|
252 |
|
253 |
+
public function tutor_add_answer() {
|
254 |
tutor_utils()->checking_nonce();
|
255 |
global $wpdb;
|
256 |
|
257 |
+
$answer = wp_kses_post( $_POST['answer'] );
|
258 |
+
if ( ! $answer ) {
|
259 |
+
wp_send_json_error( __( 'Please write answer', 'tutor' ) );
|
260 |
}
|
261 |
|
262 |
+
$question_id = (int) sanitize_text_field( $_POST['question_id'] );
|
263 |
+
$question = tutor_utils()->get_qa_question( $question_id );
|
264 |
|
265 |
$user_id = get_current_user_id();
|
266 |
+
$user = get_userdata( $user_id );
|
267 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
268 |
|
269 |
+
if ( ! tutils()->has_enrolled_content_access( 'qa_question', $question_id ) ) {
|
270 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
271 |
exit;
|
272 |
}
|
273 |
|
274 |
+
do_action( 'tutor_before_answer_to_question' );
|
275 |
+
$data = apply_filters(
|
276 |
+
'tutor_add_answer_data',
|
277 |
+
array(
|
278 |
+
'comment_post_ID' => $question->comment_post_ID,
|
279 |
+
'comment_author' => $user->user_login,
|
280 |
+
'comment_date' => $date,
|
281 |
+
'comment_date_gmt' => get_gmt_from_date( $date ),
|
282 |
+
'comment_content' => $answer,
|
283 |
+
'comment_approved' => 'approved',
|
284 |
+
'comment_agent' => 'TutorLMSPlugin',
|
285 |
+
'comment_type' => 'tutor_q_and_a',
|
286 |
+
'comment_parent' => $question_id,
|
287 |
+
'user_id' => $user_id,
|
288 |
+
)
|
289 |
+
);
|
290 |
+
|
291 |
+
$wpdb->insert( $wpdb->comments, $data );
|
292 |
$comment_id = (int) $wpdb->insert_id;
|
293 |
+
do_action( 'tutor_after_answer_to_question', $comment_id );
|
294 |
|
295 |
+
wp_send_json_success( __( 'Answer has been added successfully', 'tutor' ) );
|
296 |
}
|
297 |
|
298 |
|
299 |
+
public function tutor_course_add_to_wishlist() {
|
300 |
tutils()->checking_nonce();
|
301 |
|
302 |
+
$course_id = (int) sanitize_text_field( $_POST['course_id'] );
|
303 |
+
if ( ! is_user_logged_in() ) {
|
304 |
+
wp_send_json_error( array( 'redirect_to' => wp_login_url( wp_get_referer() ) ) );
|
305 |
}
|
306 |
global $wpdb;
|
307 |
|
308 |
+
$user_id = get_current_user_id();
|
309 |
+
$if_added_to_list = $wpdb->get_row( $wpdb->prepare( "SELECT * from {$wpdb->usermeta} WHERE user_id = %d AND meta_key = '_tutor_course_wishlist' AND meta_value = %d;", $user_id, $course_id ) );
|
310 |
+
|
311 |
+
if ( $if_added_to_list ) {
|
312 |
+
$wpdb->delete(
|
313 |
+
$wpdb->usermeta,
|
314 |
+
array(
|
315 |
+
'user_id' => $user_id,
|
316 |
+
'meta_key' => '_tutor_course_wishlist',
|
317 |
+
'meta_value' => $course_id,
|
318 |
+
)
|
319 |
+
);
|
320 |
+
wp_send_json_success(
|
321 |
+
array(
|
322 |
+
'status' => 'removed',
|
323 |
+
'msg' => __(
|
324 |
+
'Course removed from wish list',
|
325 |
+
'tutor'
|
326 |
+
),
|
327 |
+
)
|
328 |
+
);
|
329 |
+
} else {
|
330 |
+
add_user_meta( $user_id, '_tutor_course_wishlist', $course_id );
|
331 |
+
wp_send_json_success(
|
332 |
+
array(
|
333 |
+
'status' => 'added',
|
334 |
+
'msg' => __(
|
335 |
+
'Course added to wish list',
|
336 |
+
'tutor'
|
337 |
+
),
|
338 |
+
)
|
339 |
+
);
|
340 |
}
|
341 |
}
|
342 |
|
343 |
/**
|
344 |
* Method for enable / disable addons
|
345 |
*/
|
346 |
+
public function addon_enable_disable() {
|
347 |
|
348 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
349 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
350 |
}
|
351 |
|
352 |
+
$addonsConfig = maybe_unserialize( get_option( 'tutor_addons_config' ) );
|
353 |
|
354 |
+
$isEnable = (bool) sanitize_text_field( tutor_utils()->avalue_dot( 'isEnable', $_POST ) );
|
355 |
+
$addonFieldName = sanitize_text_field( tutor_utils()->avalue_dot( 'addonFieldName', $_POST ) );
|
356 |
|
357 |
+
do_action( 'tutor_addon_before_enable_disable' );
|
358 |
+
if ( $isEnable ) {
|
359 |
+
do_action( "tutor_addon_before_enable_{$addonFieldName}" );
|
360 |
+
do_action( 'tutor_addon_before_enable', $addonFieldName );
|
361 |
+
$addonsConfig[ $addonFieldName ]['is_enable'] = 1;
|
362 |
+
update_option( 'tutor_addons_config', $addonsConfig );
|
363 |
|
364 |
+
do_action( 'tutor_addon_after_enable', $addonFieldName );
|
365 |
+
do_action( "tutor_addon_after_enable_{$addonFieldName}" );
|
366 |
+
} else {
|
367 |
+
do_action( "tutor_addon_before_disable_{$addonFieldName}" );
|
368 |
+
do_action( 'tutor_addon_before_disable', $addonFieldName );
|
369 |
+
$addonsConfig[ $addonFieldName ]['is_enable'] = 0;
|
370 |
+
update_option( 'tutor_addons_config', $addonsConfig );
|
371 |
|
372 |
+
do_action( 'tutor_addon_after_disable', $addonFieldName );
|
373 |
+
do_action( "tutor_addon_after_disable_{$addonFieldName}" );
|
374 |
}
|
375 |
|
376 |
+
do_action( 'tutor_addon_after_enable_disable' );
|
377 |
wp_send_json_success();
|
378 |
}
|
379 |
|
380 |
/**
|
381 |
* Load review edit form
|
382 |
+
*
|
383 |
* @since v.1.4.0
|
384 |
*/
|
385 |
+
public function tutor_load_edit_review_modal() {
|
386 |
tutor_utils()->checking_nonce();
|
387 |
|
388 |
+
$review_id = (int) sanitize_text_field( tutils()->array_get( 'review_id', $_POST ) );
|
389 |
+
$rating = tutils()->get_rating_by_id( $review_id );
|
390 |
|
391 |
+
if ( ! tutils()->has_enrolled_content_access( 'review', $review_id ) ) {
|
392 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
393 |
exit;
|
394 |
}
|
395 |
|
396 |
ob_start();
|
397 |
+
tutor_load_template( 'dashboard.reviews.edit-review-form', array( 'rating' => $rating ) );
|
398 |
$output = ob_get_clean();
|
399 |
|
400 |
+
wp_send_json_success( array( 'output' => $output ) );
|
401 |
}
|
402 |
|
403 |
+
public function tutor_update_review_modal() {
|
404 |
global $wpdb;
|
405 |
|
406 |
tutor_utils()->checking_nonce();
|
407 |
|
408 |
+
$review_id = (int) sanitize_text_field( tutils()->array_get( 'review_id', $_POST ) );
|
409 |
+
$rating = sanitize_text_field( tutor_utils()->avalue_dot( 'rating', $_POST ) );
|
410 |
+
$review = wp_kses_post( tutor_utils()->avalue_dot( 'review', $_POST ) );
|
411 |
|
412 |
+
if ( ! tutils()->has_enrolled_content_access( 'review', $review_id ) ) {
|
413 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
414 |
exit;
|
415 |
}
|
416 |
|
417 |
+
$is_exists = $wpdb->get_var( $wpdb->prepare( "SELECT comment_ID from {$wpdb->comments} WHERE comment_ID=%d AND comment_type = 'tutor_course_rating' ;", $review_id ) );
|
418 |
|
419 |
+
if ( $is_exists ) {
|
420 |
+
$wpdb->update(
|
421 |
+
$wpdb->comments,
|
422 |
+
array( 'comment_content' => $review ),
|
423 |
array( 'comment_ID' => $review_id )
|
424 |
);
|
425 |
+
$wpdb->update(
|
426 |
+
$wpdb->commentmeta,
|
427 |
+
array( 'meta_value' => $rating ),
|
428 |
+
array(
|
429 |
+
'comment_id' => $review_id,
|
430 |
+
'meta_key' => 'tutor_rating',
|
431 |
+
)
|
432 |
);
|
433 |
|
434 |
+
do_action( 'tutor_after_review_update', $review_id, $is_exists );
|
435 |
|
436 |
wp_send_json_success();
|
437 |
}
|
440 |
|
441 |
/**
|
442 |
* Process ajax login
|
443 |
+
*
|
444 |
* @since v.1.6.3
|
445 |
*/
|
446 |
+
public function process_ajax_login() {
|
447 |
tutils()->checking_nonce();
|
448 |
|
449 |
+
$username = sanitize_text_field( tutils()->array_get( 'log', $_POST ) );
|
450 |
+
$password = tutils()->array_get( 'pwd', $_POST ); // Password can not be sanitized because users might use special characters including quotes etc.
|
451 |
+
$redirect_to = esc_url( tutils()->array_get( 'redirect_to', $_POST ) );
|
452 |
|
453 |
try {
|
454 |
$creds = array(
|
483 |
if ( is_wp_error( $user ) ) {
|
484 |
$message = $user->get_error_message();
|
485 |
$message = str_replace( '<strong>' . esc_html( $creds['user_login'] ) . '</strong>', '<strong>' . esc_html( $creds['user_login'] ) . '</strong>', $message );
|
486 |
+
|
487 |
wp_send_json_error( $message );
|
488 |
} else {
|
489 |
+
// since 1.9.8 do enroll if guest attempt to enroll
|
490 |
do_action( 'tutor_do_enroll_after_login_if_attempt', $_POST['tutor_course_enroll_attempt'] );
|
|
|
|
|
|
|
|
|
491 |
|
492 |
+
wp_send_json_success(
|
493 |
+
array(
|
494 |
+
'redirect' => apply_filters( 'tutor_login_redirect_url', $redirect_to ),
|
495 |
+
)
|
496 |
+
);
|
497 |
|
498 |
}
|
499 |
} catch ( \Exception $e ) {
|
500 |
+
wp_send_json_error( apply_filters( 'login_errors', $e->getMessage() ) );
|
501 |
do_action( 'tutor_login_failed' );
|
502 |
}
|
503 |
}
|
504 |
|
505 |
/**
|
506 |
* Create/Update announcement
|
507 |
+
*
|
508 |
* @since v.1.7.9
|
509 |
*/
|
510 |
+
public function create_or_update_annoucement() {
|
511 |
+
// prepare alert message
|
512 |
+
$create_success_msg = __( 'Announcement created successfully', 'tutor' );
|
513 |
+
$update_success_msg = __( 'Announcement updated successfully', 'tutor' );
|
514 |
+
$create_fail_msg = __( 'Announcement creation failed', 'tutor' );
|
515 |
+
$update_fail_msg = __( 'Announcement update failed', 'tutor' );
|
516 |
+
|
517 |
+
$error = array();
|
518 |
+
$response = array();
|
519 |
tutils()->checking_nonce();
|
520 |
|
521 |
+
$course_id = sanitize_text_field( $_POST['tutor_announcement_course'] );
|
522 |
+
$announcement_title = sanitize_text_field( $_POST['tutor_announcement_title'] );
|
523 |
+
$announcement_summary = sanitize_textarea_field( $_POST['tutor_announcement_summary'] );
|
524 |
+
|
525 |
+
if ( ! tutils()->can_user_manage( 'course', $course_id ) ) {
|
526 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
527 |
}
|
528 |
+
|
529 |
+
// set data and sanitize it
|
530 |
+
$form_data = array(
|
531 |
+
'post_type' => 'tutor_announcements',
|
532 |
+
'post_title' => $announcement_title,
|
533 |
'post_content' => $announcement_summary,
|
534 |
+
'post_parent' => $course_id,
|
535 |
+
'post_status' => 'publish',
|
536 |
+
);
|
537 |
|
538 |
+
if ( isset( $_POST['announcement_id'] ) ) {
|
539 |
+
$form_data['ID'] = sanitize_text_field( $_POST['announcement_id'] );
|
540 |
+
}
|
541 |
+
|
542 |
+
// validation message set
|
543 |
+
if ( empty( $form_data['post_parent'] ) ) {
|
544 |
+
$error['post_parent'] = __( 'Course name required', 'tutor' );
|
545 |
|
546 |
+
}
|
|
|
|
|
547 |
|
548 |
+
if ( empty( $form_data['post_title'] ) ) {
|
549 |
+
$error['post_title'] = __( 'Announcement title required', 'tutor' );
|
550 |
}
|
551 |
+
|
552 |
+
if ( empty( $form_data['post_content'] ) ) {
|
553 |
+
$error['post_content'] = __( 'Announcement summary required', 'tutor' );
|
554 |
+
|
555 |
}
|
556 |
+
|
557 |
+
if ( count( $error ) > 0 ) {
|
558 |
+
$response['status'] = 'validation_error';
|
559 |
+
$response['message'] = $error;
|
560 |
+
wp_send_json( $response );
|
561 |
+
} else {
|
562 |
+
// insert or update post
|
563 |
+
$post_id = wp_insert_post( $form_data );
|
564 |
+
if ( $post_id > 0 ) {
|
565 |
+
$announcement = get_post( $post_id );
|
566 |
+
$action_type = sanitize_textarea_field( $_POST['action_type'] );
|
567 |
+
$response['status'] = 'success';
|
568 |
+
// set reponse message as per action type
|
569 |
+
$response['message'] = ( $action_type == 'create' ) ? $create_success_msg : $update_success_msg;
|
570 |
+
|
571 |
+
do_action( 'tutor_announcements/after/save', $post_id, $announcement, $action_type );
|
572 |
+
|
573 |
+
wp_send_json( $response );
|
574 |
+
} else {
|
575 |
+
// failure message
|
576 |
+
$response['status'] = 'fail';
|
577 |
+
if ( $_POST['action_type'] == 'create' ) {
|
578 |
+
$response['message'] = $create_fail_msg;
|
579 |
+
}
|
580 |
+
if ( $_POST['action_type'] == 'update' ) {
|
581 |
+
$response['message'] = $update_fail_msg;
|
582 |
+
}
|
583 |
+
wp_send_json( $response );
|
584 |
+
}
|
585 |
+
}
|
586 |
+
}
|
|
|
|
|
|
|
|
|
|
|
587 |
|
588 |
/**
|
589 |
* Delete announcement
|
590 |
+
*
|
591 |
* @since v.1.7.9
|
592 |
*/
|
593 |
+
public function delete_annoucement() {
|
594 |
+
$announcement_id = sanitize_text_field( $_POST['announcement_id'] );
|
595 |
tutils()->checking_nonce();
|
596 |
|
597 |
+
if ( ! tutils()->can_user_manage( 'announcement', $announcement_id ) ) {
|
598 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
599 |
}
|
600 |
|
601 |
+
$delete = wp_delete_post( $announcement_id );
|
602 |
+
if ( $delete ) {
|
603 |
+
$response = array(
|
604 |
+
'status' => 'success',
|
605 |
+
'message' => __( 'Announcement deleted successfully', 'tutor' ),
|
606 |
+
);
|
607 |
+
wp_send_json( $response );
|
608 |
+
} else {
|
609 |
+
$response = array(
|
610 |
+
'status' => 'fail',
|
611 |
+
'message' => __( 'Announcement delete failed', 'tutor' ),
|
612 |
+
);
|
613 |
+
wp_send_json( $response );
|
614 |
+
}
|
615 |
+
}
|
616 |
+
}
|
classes/Assets.php
CHANGED
@@ -1,79 +1,81 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
class Assets{
|
8 |
|
9 |
public function __construct() {
|
10 |
/**
|
11 |
* Front and backend script enqueue
|
12 |
*/
|
13 |
-
add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
|
14 |
-
add_action('wp_enqueue_scripts', array($this, 'frontend_scripts'));
|
15 |
|
16 |
/**
|
17 |
* Common scripts loading
|
18 |
*/
|
19 |
-
add_action('admin_enqueue_scripts', array($this, 'common_scripts'));
|
20 |
-
add_action('wp_enqueue_scripts', array($this, 'common_scripts'));
|
21 |
|
22 |
/**
|
23 |
* Text domain loading
|
24 |
*/
|
25 |
-
add_action('admin_enqueue_scripts', array($this, 'tutor_script_text_domain'), 100);
|
26 |
-
add_action('wp_enqueue_scripts', array($this, 'tutor_script_text_domain'), 100);
|
27 |
-
add_filter('tutor_localize_data', array($this, 'modify_localize_data') );
|
28 |
|
29 |
/**
|
30 |
* register translateable function to load
|
31 |
* handled script with text domain attached to
|
|
|
32 |
* @since 1.9.0
|
33 |
*/
|
34 |
-
add_action( 'admin_head', array($this, 'tutor_add_mce_button'));
|
35 |
-
add_filter( 'get_the_generator_html', array($this, 'tutor_generator_tag'), 10, 2 );
|
36 |
-
add_filter( 'get_the_generator_xhtml', array($this, 'tutor_generator_tag'), 10, 2 );
|
37 |
|
38 |
/**
|
39 |
* Add translation support for external tinyMCE button
|
40 |
-
*
|
41 |
* @since 1.9.7
|
42 |
*/
|
43 |
add_filter( 'mce_external_languages', array( $this, 'tutor_tinymce_translate' ) );
|
44 |
|
45 |
/**
|
46 |
* Identifier class to body tag
|
47 |
-
*
|
48 |
* @since v1.9.9
|
49 |
*/
|
50 |
-
add_filter( 'body_class', array($this, 'add_identifier_class_to_body') );
|
51 |
-
add_filter( 'admin_body_class', array($this, 'add_identifier_class_to_body') );
|
52 |
}
|
53 |
|
54 |
private function get_default_localized_data() {
|
55 |
return array(
|
56 |
-
'ajaxurl'
|
57 |
-
'home_url'
|
58 |
-
'base_path'
|
59 |
-
'tutor_url'
|
60 |
-
'tutor_pro_url'
|
61 |
-
'nonce_key'
|
62 |
-
tutor()->nonce
|
63 |
-
'loading_icon_url'
|
64 |
-
'placeholder_img_src'
|
65 |
-
'enable_lesson_classic_editor'
|
66 |
-
'tutor_frontend_dashboard_url'
|
67 |
-
'wp_date_format'
|
68 |
-
'is_admin'
|
69 |
-
'is_admin_bar_showing'
|
70 |
);
|
71 |
}
|
72 |
|
73 |
-
public function admin_scripts(){
|
74 |
-
wp_enqueue_style('tutor-select2', tutor()->url.'assets/packages/select2/select2.min.css', array(), tutor()->version);
|
75 |
-
wp_enqueue_style('tutor-admin', tutor()->url.'assets/css/tutor-admin.min.css', array(), tutor()->version);
|
76 |
-
wp_enqueue_style('tutor-icon', tutor()->url.'assets/icons/css/tutor-icon.css', array(), tutor()->version);
|
77 |
|
78 |
/**
|
79 |
* Scripts
|
@@ -83,31 +85,31 @@ class Assets{
|
|
83 |
wp_enqueue_script( 'wp-color-picker' );
|
84 |
wp_enqueue_style( 'wp-color-picker' );
|
85 |
|
86 |
-
wp_enqueue_script('jquery-ui-slider');
|
87 |
-
wp_enqueue_script('jquery-ui-datepicker');
|
88 |
|
89 |
-
wp_enqueue_script('tutor-select2', tutor()->url.'assets/packages/select2/select2.full.min.js', array('jquery'), tutor()->version, true );
|
90 |
-
wp_enqueue_script('tutor-admin', tutor()->url.'assets/js/tutor-admin.js', array('jquery', 'wp-color-picker', 'wp-i18n'), tutor()->version, true );
|
91 |
}
|
92 |
|
93 |
/**
|
94 |
* Load frontend scripts
|
95 |
*/
|
96 |
-
public function frontend_scripts(){
|
97 |
global $post, $wp_query;
|
98 |
|
99 |
$is_script_debug = tutor_utils()->is_script_debug();
|
100 |
-
$suffix
|
101 |
|
102 |
/**
|
103 |
* We checked wp_enqueue_editor() in condition because it conflicting with Divi Builder
|
104 |
* condition updated @since v.1.7.4
|
105 |
*/
|
106 |
|
107 |
-
if (is_single()){
|
108 |
-
if (function_exists('et_pb_is_pagebuilder_used')) {
|
109 |
-
$is_page_builder_used = et_pb_is_pagebuilder_used(get_the_ID());
|
110 |
-
if (
|
111 |
wp_enqueue_editor();
|
112 |
}
|
113 |
} else {
|
@@ -118,102 +120,102 @@ class Assets{
|
|
118 |
/**
|
119 |
* Initializing quicktags script to use in wp_editor();
|
120 |
*/
|
121 |
-
wp_enqueue_script( 'quicktags');
|
122 |
|
123 |
-
$tutor_dashboard_page_id = (int) tutor_utils()->get_option('tutor_dashboard_page_id');
|
124 |
-
if ($tutor_dashboard_page_id === get_the_ID()){
|
125 |
wp_enqueue_media();
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
* Enabling Sorting, draggable, droppable...
|
130 |
*/
|
131 |
-
wp_enqueue_script('jquery-ui-sortable');
|
132 |
/**
|
133 |
* Tutor Icon
|
134 |
*/
|
135 |
-
wp_enqueue_style('tutor-icon', tutor()->url.'assets/icons/css/tutor-icon.css', array(), tutor()->version);
|
136 |
|
137 |
-
|
138 |
-
//Plyr
|
139 |
wp_enqueue_style( 'tutor-plyr', tutor()->url . 'assets/packages/plyr/plyr.css', array(), tutor()->version );
|
140 |
wp_enqueue_script( 'tutor-plyr', tutor()->url . 'assets/packages/plyr/plyr.polyfilled.min.js', array( 'jquery' ), tutor()->version, true );
|
141 |
|
142 |
-
|
143 |
-
|
144 |
|
145 |
/**
|
146 |
* Chart Data
|
147 |
*/
|
148 |
-
if ( ! empty($wp_query->query_vars['tutor_dashboard_page']) ) {
|
149 |
-
wp_enqueue_script('jquery-ui-slider');
|
150 |
|
151 |
-
wp_enqueue_style('tutor-select2', tutor()->url.'assets/packages/select2/select2.min.css', array(), tutor()->version);
|
152 |
-
wp_enqueue_script('tutor-select2', tutor()->url.'assets/packages/select2/select2.full.min.js', array('jquery'), tutor()->version, true );
|
153 |
|
154 |
-
if ($wp_query->query_vars['tutor_dashboard_page'] === 'earning'){
|
155 |
wp_enqueue_script( 'tutor-front-chart-js', tutor()->url . 'assets/js/Chart.bundle.min.js', array(), tutor()->version );
|
156 |
wp_enqueue_script( 'jquery-ui-datepicker' );
|
157 |
}
|
158 |
}
|
159 |
-
//End: chart data
|
160 |
-
|
161 |
-
wp_enqueue_style('tutor-frontend', tutor()->url."assets/css/tutor-front{$suffix}.css", array(), tutor()->version);
|
162 |
-
|
163 |
/**
|
164 |
-
* dependency wp-i18n added for
|
165 |
* translate js file
|
|
|
166 |
* @since 1.9.0
|
167 |
*/
|
168 |
-
wp_enqueue_script( 'tutor-frontend', tutor()->url . 'assets/js/tutor-front.js', array( 'jquery', 'wp-i18n'), tutor()->version, true );
|
169 |
-
|
170 |
|
171 |
/**
|
172 |
* Load frontend dashboard style
|
|
|
173 |
* @since v1.9.8
|
174 |
*/
|
175 |
-
if(tutor_utils()->is_tutor_frontend_dashboard()) {
|
176 |
-
wp_enqueue_style('tutor-frontend-dashboard-css', tutor()->url . 'assets/css/tutor-frontend-dashboard.min.css', tutor()->version);
|
177 |
}
|
178 |
|
179 |
// Load date picker for announcement at frontend
|
180 |
-
wp_enqueue_script('jquery-ui-datepicker');
|
181 |
}
|
182 |
|
183 |
public function modify_localize_data( $localize_data ) {
|
184 |
global $post;
|
185 |
-
|
186 |
if ( is_admin() ) {
|
187 |
-
if ( ! empty($_GET['taxonomy']) && ( $_GET['taxonomy'] === 'course-category' || $_GET['taxonomy'] === 'course-tag') ){
|
188 |
$localize_data['open_tutor_admin_menu'] = true;
|
189 |
}
|
190 |
} else {
|
191 |
|
192 |
// Assign quiz option
|
193 |
-
if ( ! empty($post->post_type) && $post->post_type === 'tutor_quiz'){
|
194 |
-
$single_quiz_options = (array) tutor_utils()->get_quiz_option($post->ID);
|
195 |
-
$saved_quiz_options
|
196 |
-
'quiz_when_time_expires' => tutils()->get_option('quiz_when_time_expires'),
|
197 |
);
|
198 |
-
|
199 |
-
$quiz_options = array_merge($single_quiz_options, $saved_quiz_options);
|
200 |
-
|
201 |
$previous_attempts = tutor_utils()->quiz_attempts();
|
202 |
-
|
203 |
-
if ($previous_attempts && count($previous_attempts)) {
|
204 |
$quiz_options['quiz_auto_start'] = 0;
|
205 |
}
|
206 |
-
|
207 |
$localize_data['quiz_options'] = $quiz_options;
|
208 |
}
|
209 |
|
210 |
-
//Including player assets if video exists
|
211 |
-
if (tutor_utils()->has_video_in_single()) {
|
212 |
-
$localize_data['post_id']
|
213 |
$localize_data['best_watch_time'] = 0;
|
214 |
|
215 |
-
$best_watch_time = tutor_utils()->get_lesson_reading_info(get_the_ID(), 0, 'video_best_watched_time');
|
216 |
-
if ($best_watch_time > 0){
|
217 |
$localize_data['best_watch_time'] = $best_watch_time;
|
218 |
}
|
219 |
}
|
@@ -224,20 +226,20 @@ class Assets{
|
|
224 |
|
225 |
public function common_scripts() {
|
226 |
// Load course builder resources
|
227 |
-
if($this->get_course_builder_screen()) {
|
228 |
-
wp_enqueue_script( 'tutor-course-builder', tutor()->url . 'assets/js/tutor-course-builder.js', array( 'jquery', 'wp-i18n'), tutor()->version, true );
|
229 |
wp_enqueue_style( 'tutor-course-builder-css', tutor()->url . 'assets/css/tutor-course-builder.css', array(), tutor()->version );
|
230 |
}
|
231 |
|
232 |
// Localize scripts
|
233 |
$localize_data = apply_filters( 'tutor_localize_data', $this->get_default_localized_data() );
|
234 |
-
wp_localize_script('tutor-frontend', '_tutorobject', $localize_data);
|
235 |
-
wp_localize_script('tutor-admin', '_tutorobject', $localize_data);
|
236 |
-
wp_localize_script('tutor-course-builder', '_tutorobject', $localize_data);
|
237 |
|
238 |
// Inline styles
|
239 |
-
wp_add_inline_style('tutor-frontend', $this->load_color_palette() );
|
240 |
-
wp_add_inline_style('tutor-admin', $this->load_color_palette() );
|
241 |
}
|
242 |
|
243 |
private function load_color_palette() {
|
@@ -245,50 +247,50 @@ class Assets{
|
|
245 |
/**
|
246 |
* Default Color
|
247 |
*/
|
248 |
-
$tutor_css
|
249 |
-
$tutor_primary_color
|
250 |
-
$tutor_primary_hover_color = tutor_utils()->get_option('tutor_primary_hover_color');
|
251 |
-
$tutor_text_color
|
252 |
-
$tutor_light_color
|
253 |
|
254 |
/**
|
255 |
* tutor buttons style
|
256 |
*/
|
257 |
-
$tutor_button_primary = tutor_utils()->get_option('tutor_button_primary');
|
258 |
-
$tutor_button_danger
|
259 |
-
$tutor_button_success = tutor_utils()->get_option('tutor_button_success');
|
260 |
-
$tutor_button_warning = tutor_utils()->get_option('tutor_button_warning');
|
261 |
|
262 |
-
if ($tutor_primary_color){
|
263 |
$tutor_css .= " --tutor-primary-color: {$tutor_primary_color};";
|
264 |
}
|
265 |
-
if ($tutor_primary_hover_color){
|
266 |
$tutor_css .= " --tutor-primary-hover-color: {$tutor_primary_hover_color};";
|
267 |
}
|
268 |
-
if ($tutor_text_color){
|
269 |
$tutor_css .= " --tutor-text-color: {$tutor_text_color};";
|
270 |
}
|
271 |
-
if ($tutor_light_color){
|
272 |
$tutor_css .= " --tutor-light-color: {$tutor_light_color};";
|
273 |
}
|
274 |
|
275 |
/**
|
276 |
* check if button style setup
|
277 |
*/
|
278 |
-
if($tutor_button_primary){
|
279 |
$tutor_css .= " --tutor-primary-button-color: {$tutor_button_primary}; ";
|
280 |
}
|
281 |
-
if($tutor_button_danger){
|
282 |
$tutor_css .= " --tutor-danger-button-color: {$tutor_button_danger}; ";
|
283 |
}
|
284 |
-
if($tutor_button_success){
|
285 |
$tutor_css .= " --tutor-success-button-color: {$tutor_button_success}; ";
|
286 |
}
|
287 |
-
if($tutor_button_warning){
|
288 |
$tutor_css .= " --tutor-warning-button-color: {$tutor_button_warning}; ";
|
289 |
}
|
290 |
|
291 |
-
$tutor_css .=
|
292 |
|
293 |
return $tutor_css;
|
294 |
}
|
@@ -298,18 +300,18 @@ class Assets{
|
|
298 |
*/
|
299 |
function tutor_add_mce_button() {
|
300 |
// check user permissions
|
301 |
-
if ( !current_user_can( 'edit_posts' ) && !current_user_can( 'edit_pages' ) ) {
|
302 |
return;
|
303 |
}
|
304 |
// check if WYSIWYG is enabled
|
305 |
if ( 'true' == get_user_option( 'rich_editing' ) ) {
|
306 |
-
add_filter( 'mce_external_plugins', array($this, 'tutor_add_tinymce_js') );
|
307 |
-
add_filter( 'mce_buttons', array($this, 'tutor_register_mce_button') );
|
308 |
}
|
309 |
}
|
310 |
// Declare script for new button
|
311 |
function tutor_add_tinymce_js( $plugin_array ) {
|
312 |
-
$plugin_array['tutor_button'] = tutor()->url .'assets/js/mce-button.js';
|
313 |
return $plugin_array;
|
314 |
}
|
315 |
// Register new button in the editor
|
@@ -328,62 +330,63 @@ class Assets{
|
|
328 |
function tutor_generator_tag( $gen, $type ) {
|
329 |
switch ( $type ) {
|
330 |
case 'html':
|
331 |
-
$gen .= "\n" . '<meta name="generator" content="TutorLMS ' .
|
332 |
break;
|
333 |
case 'xhtml':
|
334 |
-
$gen .= "\n" . '<meta name="generator" content="TutorLMS ' .
|
335 |
break;
|
336 |
}
|
337 |
return $gen;
|
338 |
}
|
339 |
|
340 |
/**
|
341 |
-
* load text domain handled script after all enqueue_scripts
|
342 |
* registered functions
|
|
|
343 |
* @since 1.9.0
|
344 |
-
|
345 |
function tutor_script_text_domain() {
|
346 |
-
wp_set_script_translations( 'tutor-frontend', 'tutor', tutor()->path.'languages/' );
|
347 |
-
wp_set_script_translations( 'tutor-admin', 'tutor', tutor()->path.'languages/' );
|
348 |
-
wp_set_script_translations( 'tutor-course-builder', 'tutor', tutor()->path.'languages/' );
|
349 |
}
|
350 |
|
351 |
/**
|
352 |
* Add translation support for external tinyMCE button
|
353 |
-
*
|
354 |
* @since 1.9.7
|
355 |
*/
|
356 |
function tutor_tinymce_translate() {
|
357 |
-
$locales['tutor_button'] = tutor()->path.'includes/tinymce_translate.php';
|
358 |
return $locales;
|
359 |
}
|
360 |
|
361 |
private function get_course_builder_screen() {
|
362 |
|
363 |
// Add course editor identifier class
|
364 |
-
if(is_admin()) {
|
365 |
$screen = get_current_screen();
|
366 |
-
if(is_object($screen) && $screen->base=='post' && $screen->id=='courses') {
|
367 |
return $screen->is_block_editor ? 'gutenberg' : 'classic';
|
368 |
}
|
369 |
-
}
|
370 |
return 'frontend';
|
371 |
}
|
372 |
|
373 |
return null;
|
374 |
}
|
375 |
-
|
376 |
-
public function add_identifier_class_to_body($classes) {
|
377 |
$course_builder_screen = $this->get_course_builder_screen();
|
378 |
-
$to_add
|
379 |
|
380 |
// Add course editor identifier class
|
381 |
-
if($course_builder_screen) {
|
382 |
$to_add[] = ' tutor-screen-course-builder tutor-screen-course-builder-' . $course_builder_screen . ' ';
|
383 |
}
|
384 |
|
385 |
-
is_array($classes) ? $classes=array_merge($classes, $to_add) : $classes.=implode('', $to_add);
|
386 |
|
387 |
return $classes;
|
388 |
}
|
389 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
class Assets {
|
9 |
|
10 |
public function __construct() {
|
11 |
/**
|
12 |
* Front and backend script enqueue
|
13 |
*/
|
14 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
|
15 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
|
16 |
|
17 |
/**
|
18 |
* Common scripts loading
|
19 |
*/
|
20 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'common_scripts' ) );
|
21 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'common_scripts' ) );
|
22 |
|
23 |
/**
|
24 |
* Text domain loading
|
25 |
*/
|
26 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'tutor_script_text_domain' ), 100 );
|
27 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'tutor_script_text_domain' ), 100 );
|
28 |
+
add_filter( 'tutor_localize_data', array( $this, 'modify_localize_data' ) );
|
29 |
|
30 |
/**
|
31 |
* register translateable function to load
|
32 |
* handled script with text domain attached to
|
33 |
+
*
|
34 |
* @since 1.9.0
|
35 |
*/
|
36 |
+
add_action( 'admin_head', array( $this, 'tutor_add_mce_button' ) );
|
37 |
+
add_filter( 'get_the_generator_html', array( $this, 'tutor_generator_tag' ), 10, 2 );
|
38 |
+
add_filter( 'get_the_generator_xhtml', array( $this, 'tutor_generator_tag' ), 10, 2 );
|
39 |
|
40 |
/**
|
41 |
* Add translation support for external tinyMCE button
|
42 |
+
*
|
43 |
* @since 1.9.7
|
44 |
*/
|
45 |
add_filter( 'mce_external_languages', array( $this, 'tutor_tinymce_translate' ) );
|
46 |
|
47 |
/**
|
48 |
* Identifier class to body tag
|
49 |
+
*
|
50 |
* @since v1.9.9
|
51 |
*/
|
52 |
+
add_filter( 'body_class', array( $this, 'add_identifier_class_to_body' ) );
|
53 |
+
add_filter( 'admin_body_class', array( $this, 'add_identifier_class_to_body' ) );
|
54 |
}
|
55 |
|
56 |
private function get_default_localized_data() {
|
57 |
return array(
|
58 |
+
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
59 |
+
'home_url' => get_home_url(),
|
60 |
+
'base_path' => tutor()->basepath,
|
61 |
+
'tutor_url' => tutor()->url,
|
62 |
+
'tutor_pro_url' => function_exists( 'tutor_pro' ) ? tutor_pro()->url : null,
|
63 |
+
'nonce_key' => tutor()->nonce,
|
64 |
+
tutor()->nonce => wp_create_nonce( tutor()->nonce_action ),
|
65 |
+
'loading_icon_url' => get_admin_url() . 'images/wpspin_light.gif',
|
66 |
+
'placeholder_img_src' => tutor_placeholder_img_src(),
|
67 |
+
'enable_lesson_classic_editor' => get_tutor_option( 'enable_lesson_classic_editor' ),
|
68 |
+
'tutor_frontend_dashboard_url' => tutor_utils()->get_tutor_dashboard_page_permalink(),
|
69 |
+
'wp_date_format' => tutor_js_date_format_against_wp(),
|
70 |
+
'is_admin' => is_admin(),
|
71 |
+
'is_admin_bar_showing' => is_admin_bar_showing(),
|
72 |
);
|
73 |
}
|
74 |
|
75 |
+
public function admin_scripts() {
|
76 |
+
wp_enqueue_style( 'tutor-select2', tutor()->url . 'assets/packages/select2/select2.min.css', array(), tutor()->version );
|
77 |
+
wp_enqueue_style( 'tutor-admin', tutor()->url . 'assets/css/tutor-admin.min.css', array(), tutor()->version );
|
78 |
+
wp_enqueue_style( 'tutor-icon', tutor()->url . 'assets/icons/css/tutor-icon.css', array(), tutor()->version );
|
79 |
|
80 |
/**
|
81 |
* Scripts
|
85 |
wp_enqueue_script( 'wp-color-picker' );
|
86 |
wp_enqueue_style( 'wp-color-picker' );
|
87 |
|
88 |
+
wp_enqueue_script( 'jquery-ui-slider' );
|
89 |
+
wp_enqueue_script( 'jquery-ui-datepicker' );
|
90 |
|
91 |
+
wp_enqueue_script( 'tutor-select2', tutor()->url . 'assets/packages/select2/select2.full.min.js', array( 'jquery' ), tutor()->version, true );
|
92 |
+
wp_enqueue_script( 'tutor-admin', tutor()->url . 'assets/js/tutor-admin.js', array( 'jquery', 'wp-color-picker', 'wp-i18n' ), tutor()->version, true );
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
* Load frontend scripts
|
97 |
*/
|
98 |
+
public function frontend_scripts() {
|
99 |
global $post, $wp_query;
|
100 |
|
101 |
$is_script_debug = tutor_utils()->is_script_debug();
|
102 |
+
$suffix = $is_script_debug ? '' : '.min';
|
103 |
|
104 |
/**
|
105 |
* We checked wp_enqueue_editor() in condition because it conflicting with Divi Builder
|
106 |
* condition updated @since v.1.7.4
|
107 |
*/
|
108 |
|
109 |
+
if ( is_single() ) {
|
110 |
+
if ( function_exists( 'et_pb_is_pagebuilder_used' ) ) {
|
111 |
+
$is_page_builder_used = et_pb_is_pagebuilder_used( get_the_ID() );
|
112 |
+
if ( ! $is_page_builder_used ) {
|
113 |
wp_enqueue_editor();
|
114 |
}
|
115 |
} else {
|
120 |
/**
|
121 |
* Initializing quicktags script to use in wp_editor();
|
122 |
*/
|
123 |
+
wp_enqueue_script( 'quicktags' );
|
124 |
|
125 |
+
$tutor_dashboard_page_id = (int) tutor_utils()->get_option( 'tutor_dashboard_page_id' );
|
126 |
+
if ( $tutor_dashboard_page_id === get_the_ID() ) {
|
127 |
wp_enqueue_media();
|
128 |
}
|
129 |
|
130 |
/**
|
131 |
* Enabling Sorting, draggable, droppable...
|
132 |
*/
|
133 |
+
wp_enqueue_script( 'jquery-ui-sortable' );
|
134 |
/**
|
135 |
* Tutor Icon
|
136 |
*/
|
137 |
+
wp_enqueue_style( 'tutor-icon', tutor()->url . 'assets/icons/css/tutor-icon.css', array(), tutor()->version );
|
138 |
|
139 |
+
// Plyr
|
|
|
140 |
wp_enqueue_style( 'tutor-plyr', tutor()->url . 'assets/packages/plyr/plyr.css', array(), tutor()->version );
|
141 |
wp_enqueue_script( 'tutor-plyr', tutor()->url . 'assets/packages/plyr/plyr.polyfilled.min.js', array( 'jquery' ), tutor()->version, true );
|
142 |
|
143 |
+
// Social Share
|
144 |
+
wp_enqueue_script( 'tutor-social-share', tutor()->url . 'assets/packages/SocialShare/SocialShare.min.js', array( 'jquery' ), tutor()->version, true );
|
145 |
|
146 |
/**
|
147 |
* Chart Data
|
148 |
*/
|
149 |
+
if ( ! empty( $wp_query->query_vars['tutor_dashboard_page'] ) ) {
|
150 |
+
wp_enqueue_script( 'jquery-ui-slider' );
|
151 |
|
152 |
+
wp_enqueue_style( 'tutor-select2', tutor()->url . 'assets/packages/select2/select2.min.css', array(), tutor()->version );
|
153 |
+
wp_enqueue_script( 'tutor-select2', tutor()->url . 'assets/packages/select2/select2.full.min.js', array( 'jquery' ), tutor()->version, true );
|
154 |
|
155 |
+
if ( $wp_query->query_vars['tutor_dashboard_page'] === 'earning' ) {
|
156 |
wp_enqueue_script( 'tutor-front-chart-js', tutor()->url . 'assets/js/Chart.bundle.min.js', array(), tutor()->version );
|
157 |
wp_enqueue_script( 'jquery-ui-datepicker' );
|
158 |
}
|
159 |
}
|
160 |
+
// End: chart data
|
161 |
+
|
162 |
+
wp_enqueue_style( 'tutor-frontend', tutor()->url . "assets/css/tutor-front{$suffix}.css", array(), tutor()->version );
|
163 |
+
|
164 |
/**
|
165 |
+
* dependency wp-i18n added for
|
166 |
* translate js file
|
167 |
+
*
|
168 |
* @since 1.9.0
|
169 |
*/
|
170 |
+
wp_enqueue_script( 'tutor-frontend', tutor()->url . 'assets/js/tutor-front.js', array( 'jquery', 'wp-i18n' ), tutor()->version, true );
|
|
|
171 |
|
172 |
/**
|
173 |
* Load frontend dashboard style
|
174 |
+
*
|
175 |
* @since v1.9.8
|
176 |
*/
|
177 |
+
if ( tutor_utils()->is_tutor_frontend_dashboard() ) {
|
178 |
+
wp_enqueue_style( 'tutor-frontend-dashboard-css', tutor()->url . 'assets/css/tutor-frontend-dashboard.min.css', tutor()->version );
|
179 |
}
|
180 |
|
181 |
// Load date picker for announcement at frontend
|
182 |
+
wp_enqueue_script( 'jquery-ui-datepicker' );
|
183 |
}
|
184 |
|
185 |
public function modify_localize_data( $localize_data ) {
|
186 |
global $post;
|
187 |
+
|
188 |
if ( is_admin() ) {
|
189 |
+
if ( ! empty( $_GET['taxonomy'] ) && ( $_GET['taxonomy'] === 'course-category' || $_GET['taxonomy'] === 'course-tag' ) ) {
|
190 |
$localize_data['open_tutor_admin_menu'] = true;
|
191 |
}
|
192 |
} else {
|
193 |
|
194 |
// Assign quiz option
|
195 |
+
if ( ! empty( $post->post_type ) && $post->post_type === 'tutor_quiz' ) {
|
196 |
+
$single_quiz_options = (array) tutor_utils()->get_quiz_option( $post->ID );
|
197 |
+
$saved_quiz_options = array(
|
198 |
+
'quiz_when_time_expires' => tutils()->get_option( 'quiz_when_time_expires' ),
|
199 |
);
|
200 |
+
|
201 |
+
$quiz_options = array_merge( $single_quiz_options, $saved_quiz_options );
|
202 |
+
|
203 |
$previous_attempts = tutor_utils()->quiz_attempts();
|
204 |
+
|
205 |
+
if ( $previous_attempts && count( $previous_attempts ) ) {
|
206 |
$quiz_options['quiz_auto_start'] = 0;
|
207 |
}
|
208 |
+
|
209 |
$localize_data['quiz_options'] = $quiz_options;
|
210 |
}
|
211 |
|
212 |
+
// Including player assets if video exists
|
213 |
+
if ( tutor_utils()->has_video_in_single() ) {
|
214 |
+
$localize_data['post_id'] = get_the_ID();
|
215 |
$localize_data['best_watch_time'] = 0;
|
216 |
|
217 |
+
$best_watch_time = tutor_utils()->get_lesson_reading_info( get_the_ID(), 0, 'video_best_watched_time' );
|
218 |
+
if ( $best_watch_time > 0 ) {
|
219 |
$localize_data['best_watch_time'] = $best_watch_time;
|
220 |
}
|
221 |
}
|
226 |
|
227 |
public function common_scripts() {
|
228 |
// Load course builder resources
|
229 |
+
if ( $this->get_course_builder_screen() ) {
|
230 |
+
wp_enqueue_script( 'tutor-course-builder', tutor()->url . 'assets/js/tutor-course-builder.js', array( 'jquery', 'wp-i18n' ), tutor()->version, true );
|
231 |
wp_enqueue_style( 'tutor-course-builder-css', tutor()->url . 'assets/css/tutor-course-builder.css', array(), tutor()->version );
|
232 |
}
|
233 |
|
234 |
// Localize scripts
|
235 |
$localize_data = apply_filters( 'tutor_localize_data', $this->get_default_localized_data() );
|
236 |
+
wp_localize_script( 'tutor-frontend', '_tutorobject', $localize_data );
|
237 |
+
wp_localize_script( 'tutor-admin', '_tutorobject', $localize_data );
|
238 |
+
wp_localize_script( 'tutor-course-builder', '_tutorobject', $localize_data );
|
239 |
|
240 |
// Inline styles
|
241 |
+
wp_add_inline_style( 'tutor-frontend', $this->load_color_palette() );
|
242 |
+
wp_add_inline_style( 'tutor-admin', $this->load_color_palette() );
|
243 |
}
|
244 |
|
245 |
private function load_color_palette() {
|
247 |
/**
|
248 |
* Default Color
|
249 |
*/
|
250 |
+
$tutor_css = ':root{';
|
251 |
+
$tutor_primary_color = tutor_utils()->get_option( 'tutor_primary_color' );
|
252 |
+
$tutor_primary_hover_color = tutor_utils()->get_option( 'tutor_primary_hover_color' );
|
253 |
+
$tutor_text_color = tutor_utils()->get_option( 'tutor_text_color' );
|
254 |
+
$tutor_light_color = tutor_utils()->get_option( 'tutor_light_color' );
|
255 |
|
256 |
/**
|
257 |
* tutor buttons style
|
258 |
*/
|
259 |
+
$tutor_button_primary = tutor_utils()->get_option( 'tutor_button_primary' );
|
260 |
+
$tutor_button_danger = tutor_utils()->get_option( 'tutor_button_danger' );
|
261 |
+
$tutor_button_success = tutor_utils()->get_option( 'tutor_button_success' );
|
262 |
+
$tutor_button_warning = tutor_utils()->get_option( 'tutor_button_warning' );
|
263 |
|
264 |
+
if ( $tutor_primary_color ) {
|
265 |
$tutor_css .= " --tutor-primary-color: {$tutor_primary_color};";
|
266 |
}
|
267 |
+
if ( $tutor_primary_hover_color ) {
|
268 |
$tutor_css .= " --tutor-primary-hover-color: {$tutor_primary_hover_color};";
|
269 |
}
|
270 |
+
if ( $tutor_text_color ) {
|
271 |
$tutor_css .= " --tutor-text-color: {$tutor_text_color};";
|
272 |
}
|
273 |
+
if ( $tutor_light_color ) {
|
274 |
$tutor_css .= " --tutor-light-color: {$tutor_light_color};";
|
275 |
}
|
276 |
|
277 |
/**
|
278 |
* check if button style setup
|
279 |
*/
|
280 |
+
if ( $tutor_button_primary ) {
|
281 |
$tutor_css .= " --tutor-primary-button-color: {$tutor_button_primary}; ";
|
282 |
}
|
283 |
+
if ( $tutor_button_danger ) {
|
284 |
$tutor_css .= " --tutor-danger-button-color: {$tutor_button_danger}; ";
|
285 |
}
|
286 |
+
if ( $tutor_button_success ) {
|
287 |
$tutor_css .= " --tutor-success-button-color: {$tutor_button_success}; ";
|
288 |
}
|
289 |
+
if ( $tutor_button_warning ) {
|
290 |
$tutor_css .= " --tutor-warning-button-color: {$tutor_button_warning}; ";
|
291 |
}
|
292 |
|
293 |
+
$tutor_css .= '}';
|
294 |
|
295 |
return $tutor_css;
|
296 |
}
|
300 |
*/
|
301 |
function tutor_add_mce_button() {
|
302 |
// check user permissions
|
303 |
+
if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
|
304 |
return;
|
305 |
}
|
306 |
// check if WYSIWYG is enabled
|
307 |
if ( 'true' == get_user_option( 'rich_editing' ) ) {
|
308 |
+
add_filter( 'mce_external_plugins', array( $this, 'tutor_add_tinymce_js' ) );
|
309 |
+
add_filter( 'mce_buttons', array( $this, 'tutor_register_mce_button' ) );
|
310 |
}
|
311 |
}
|
312 |
// Declare script for new button
|
313 |
function tutor_add_tinymce_js( $plugin_array ) {
|
314 |
+
$plugin_array['tutor_button'] = tutor()->url . 'assets/js/mce-button.js';
|
315 |
return $plugin_array;
|
316 |
}
|
317 |
// Register new button in the editor
|
330 |
function tutor_generator_tag( $gen, $type ) {
|
331 |
switch ( $type ) {
|
332 |
case 'html':
|
333 |
+
$gen .= "\n" . '<meta name="generator" content="TutorLMS ' . TUTOR_VERSION . '">';
|
334 |
break;
|
335 |
case 'xhtml':
|
336 |
+
$gen .= "\n" . '<meta name="generator" content="TutorLMS ' . TUTOR_VERSION . '" />';
|
337 |
break;
|
338 |
}
|
339 |
return $gen;
|
340 |
}
|
341 |
|
342 |
/**
|
343 |
+
* load text domain handled script after all enqueue_scripts
|
344 |
* registered functions
|
345 |
+
*
|
346 |
* @since 1.9.0
|
347 |
+
*/
|
348 |
function tutor_script_text_domain() {
|
349 |
+
wp_set_script_translations( 'tutor-frontend', 'tutor', tutor()->path . 'languages/' );
|
350 |
+
wp_set_script_translations( 'tutor-admin', 'tutor', tutor()->path . 'languages/' );
|
351 |
+
wp_set_script_translations( 'tutor-course-builder', 'tutor', tutor()->path . 'languages/' );
|
352 |
}
|
353 |
|
354 |
/**
|
355 |
* Add translation support for external tinyMCE button
|
356 |
+
*
|
357 |
* @since 1.9.7
|
358 |
*/
|
359 |
function tutor_tinymce_translate() {
|
360 |
+
$locales['tutor_button'] = tutor()->path . 'includes/tinymce_translate.php';
|
361 |
return $locales;
|
362 |
}
|
363 |
|
364 |
private function get_course_builder_screen() {
|
365 |
|
366 |
// Add course editor identifier class
|
367 |
+
if ( is_admin() ) {
|
368 |
$screen = get_current_screen();
|
369 |
+
if ( is_object( $screen ) && $screen->base == 'post' && $screen->id == 'courses' ) {
|
370 |
return $screen->is_block_editor ? 'gutenberg' : 'classic';
|
371 |
}
|
372 |
+
} elseif ( tutor_utils()->is_tutor_frontend_dashboard( 'create-course' ) ) {
|
373 |
return 'frontend';
|
374 |
}
|
375 |
|
376 |
return null;
|
377 |
}
|
378 |
+
|
379 |
+
public function add_identifier_class_to_body( $classes ) {
|
380 |
$course_builder_screen = $this->get_course_builder_screen();
|
381 |
+
$to_add = array();
|
382 |
|
383 |
// Add course editor identifier class
|
384 |
+
if ( $course_builder_screen ) {
|
385 |
$to_add[] = ' tutor-screen-course-builder tutor-screen-course-builder-' . $course_builder_screen . ' ';
|
386 |
}
|
387 |
|
388 |
+
is_array( $classes ) ? $classes = array_merge( $classes, $to_add ) : $classes .= implode( '', $to_add );
|
389 |
|
390 |
return $classes;
|
391 |
}
|
392 |
+
}
|
classes/Course.php
CHANGED
@@ -1,69 +1,73 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
class Course extends Tutor_Base {
|
8 |
-
|
9 |
-
private $additional_meta=array(
|
10 |
'_tutor_disable_qa',
|
11 |
-
'_tutor_is_public_course'
|
12 |
);
|
13 |
|
14 |
public function __construct() {
|
15 |
parent::__construct();
|
16 |
-
|
17 |
-
add_action( 'add_meta_boxes', array($this, 'register_meta_box') );
|
18 |
-
add_action('save_post_'.$this->course_post_type, array($this, 'save_course_meta'), 10, 2);
|
19 |
-
add_action('wp_ajax_tutor_add_course_topic', array($this, 'tutor_add_course_topic'));
|
20 |
-
add_action('wp_ajax_tutor_update_topic', array($this, 'tutor_update_topic'));
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
add_action(
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
-
add_action('admin_action_tutor_delete_topic', array($this, 'tutor_delete_topic'));
|
27 |
-
add_action('admin_action_tutor_delete_announcement', array($this, 'tutor_delete_announcement'));
|
28 |
|
29 |
-
//Frontend Action
|
30 |
-
add_action('template_redirect', array($this, 'enroll_now'));
|
31 |
-
add_action('init', array($this, 'mark_course_complete'));
|
32 |
|
33 |
-
//Modal Perform
|
34 |
-
add_action('wp_ajax_tutor_load_instructors_modal', array($this, 'tutor_load_instructors_modal'));
|
35 |
-
add_action('wp_ajax_tutor_add_instructors_to_course', array($this, 'tutor_add_instructors_to_course'));
|
36 |
-
add_action('wp_ajax_detach_instructor_from_course', array($this, 'detach_instructor_from_course'));
|
37 |
|
38 |
/**
|
39 |
* Frontend Dashboard
|
40 |
*/
|
41 |
-
add_action('wp_ajax_tutor_delete_dashboard_course', array($this, 'tutor_delete_dashboard_course'));
|
42 |
|
43 |
/**
|
44 |
* Gutenberg author support
|
45 |
*/
|
46 |
-
add_filter('wp_insert_post_data', array($this, 'tutor_add_gutenberg_author'), '99', 2);
|
47 |
|
48 |
/**
|
49 |
* Frontend metabox supports for course builder
|
|
|
50 |
* @since v.1.3.4
|
51 |
*/
|
52 |
-
add_action('tutor/dashboard_course_builder_form_field_after', array($this, 'register_meta_box_in_frontend'));
|
53 |
|
54 |
/**
|
55 |
* Do Stuff for the course save from frontend
|
56 |
*/
|
57 |
-
add_action('save_tutor_course', array($this, 'attach_product_with_course'), 10, 2);
|
58 |
|
59 |
/**
|
60 |
* Add course level to course settings
|
|
|
61 |
* @since v.1.4.1
|
62 |
*/
|
63 |
-
add_action('tutor_course/settings_tab_content/after/general', array($this, 'add_course_level_to_settings'));
|
64 |
|
65 |
/**
|
66 |
* Enable Disable Course Details Page Feature
|
|
|
67 |
* @since v.1.4.8
|
68 |
*/
|
69 |
$this->course_elements_enable_disable();
|
@@ -72,7 +76,7 @@ class Course extends Tutor_Base {
|
|
72 |
* @since v.1.4.8
|
73 |
* Check if course starting, set meta if starting
|
74 |
*/
|
75 |
-
add_action('tutor_lesson_load_before', array($this, 'tutor_lesson_load_before'));
|
76 |
|
77 |
/**
|
78 |
* @since v.1.4.9
|
@@ -80,187 +84,198 @@ class Course extends Tutor_Base {
|
|
80 |
*/
|
81 |
$this->filter_product_in_shop_page();
|
82 |
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
|
|
|
|
|
|
108 |
|
109 |
/**
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
114 |
|
115 |
/**
|
116 |
* Show only own uploads in media library if user is instructor
|
|
|
117 |
* @since v1.8.9
|
118 |
*/
|
119 |
-
add_filter('posts_where', array($this, 'restrict_media' ) );
|
120 |
|
121 |
/**
|
122 |
* Restrict new enrol/purchase button if course member limit reached
|
|
|
123 |
* @since v1.9.0
|
124 |
*/
|
125 |
-
add_filter('tutor_course_restrict_new_entry', array($this, 'restrict_new_student_entry'));
|
126 |
|
127 |
/**
|
128 |
* Reset course progress on retake
|
|
|
129 |
* @since v1.9.5
|
130 |
*/
|
131 |
-
add_action( 'wp_ajax_tutor_reset_course_progress', array($this, 'tutor_reset_course_progress') );
|
132 |
-
|
133 |
/**
|
134 |
* Popup for review
|
|
|
135 |
* @since v1.9.7
|
136 |
*/
|
137 |
-
add_action( 'wp_footer', array($this, 'popup_review_form') );
|
138 |
|
139 |
/**
|
140 |
* Do enroll after login if guest take enroll attempt
|
141 |
-
*
|
142 |
* @since 1.9.8
|
143 |
*/
|
144 |
-
add_action(
|
145 |
}
|
146 |
|
147 |
-
public function restrict_new_student_entry($content) {
|
148 |
|
149 |
-
if(!tutils()->is_course_fully_booked()) {
|
150 |
// No restriction if not fully booked
|
151 |
return $content;
|
152 |
}
|
153 |
-
|
154 |
return '<span class="tutor-course-booked-fully">
|
155 |
-
<img src="' . tutor()->url . '/assets/images/icon-warning-info.svg"/>
|
156 |
-
<span>' . __('Fully booked', 'tutor') . '</span>
|
157 |
</span>';
|
158 |
}
|
159 |
|
160 |
-
function restrict_media( $where ){
|
161 |
-
|
162 |
-
if( isset( $_POST['action'] ) && $_POST['action'] == 'query-attachments' && tutor_utils()->is_instructor()){
|
163 |
-
if(!tutor_utils()->has_user_role(array('administrator', 'editor'))) {
|
164 |
$where .= ' AND post_author=' . get_current_user_id();
|
165 |
}
|
166 |
}
|
167 |
-
|
168 |
return $where;
|
169 |
}
|
170 |
|
171 |
/**
|
172 |
* Registering metabox
|
173 |
*/
|
174 |
-
public function register_meta_box(){
|
175 |
-
$coursePostType
|
176 |
-
$course_marketplace = tutor_utils()->get_option('enable_course_marketplace');
|
177 |
-
|
178 |
-
add_meta_box( 'tutor-course-topics', __( 'Course Builder', 'tutor' ), array($this, 'course_meta_box'), $coursePostType );
|
179 |
-
add_meta_box( 'tutor-course-additional-data', __( 'Additional Data', 'tutor' ), array($this, 'course_additional_data_meta_box'), $coursePostType );
|
180 |
-
add_meta_box( 'tutor-course-videos', __( 'Video', 'tutor' ), array($this, 'video_metabox'), $coursePostType );
|
181 |
-
if ($course_marketplace) {
|
182 |
add_meta_box( 'tutor-instructors', __( 'Instructors', 'tutor' ), array( $this, 'instructors_metabox' ), $coursePostType );
|
183 |
}
|
184 |
|
185 |
/**
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
|
|
190 |
}
|
191 |
|
192 |
-
public function course_meta_box($echo = true){
|
193 |
ob_start();
|
194 |
-
include
|
195 |
$content = ob_get_clean();
|
196 |
|
197 |
-
if ($echo){
|
198 |
-
echo $content;
|
199 |
-
}else{
|
200 |
return $content;
|
201 |
}
|
202 |
}
|
203 |
|
204 |
-
public function course_additional_data_meta_box($echo = true){
|
205 |
|
206 |
ob_start();
|
207 |
-
include
|
208 |
$content = ob_get_clean();
|
209 |
|
210 |
-
if ($echo){
|
211 |
-
echo $content;
|
212 |
-
}else{
|
213 |
return $content;
|
214 |
}
|
215 |
}
|
216 |
|
217 |
-
public function video_metabox($echo = true){
|
218 |
ob_start();
|
219 |
-
include
|
220 |
$content = ob_get_clean();
|
221 |
|
222 |
-
if ($echo){
|
223 |
-
echo $content;
|
224 |
-
}else{
|
225 |
return $content;
|
226 |
}
|
227 |
}
|
228 |
|
229 |
-
public function course_level_metabox($echo = true){
|
230 |
ob_start();
|
231 |
-
include
|
232 |
$content = ob_get_clean();
|
233 |
|
234 |
-
if ($echo){
|
235 |
-
echo $content;
|
236 |
-
}else{
|
237 |
return $content;
|
238 |
}
|
239 |
}
|
240 |
|
241 |
-
public function instructors_metabox($echo = true){
|
242 |
ob_start();
|
243 |
include tutor()->path . 'views/metabox/instructors-metabox.php';
|
244 |
$content = ob_get_clean();
|
245 |
|
246 |
-
if ($echo){
|
247 |
-
echo $content;
|
248 |
-
}else{
|
249 |
return $content;
|
250 |
}
|
251 |
}
|
252 |
|
253 |
/**
|
254 |
* Register metabox in course builder tutor
|
|
|
255 |
* @since v.1.3.4
|
256 |
*/
|
257 |
-
public function register_meta_box_in_frontend(){
|
258 |
-
do_action('tutor_course_builder_metabox_before', get_the_ID());
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
do_action('tutor_course_builder_metabox_after', get_the_ID());
|
264 |
}
|
265 |
|
266 |
/**
|
@@ -268,77 +283,76 @@ class Course extends Tutor_Base {
|
|
268 |
*
|
269 |
* Insert Topic and attached it with Course
|
270 |
*/
|
271 |
-
public function save_course_meta($post_ID, $post){
|
272 |
global $wpdb;
|
273 |
|
274 |
-
do_action(
|
275 |
-
|
276 |
/**
|
277 |
* Save course price type
|
278 |
*/
|
279 |
-
$price_type = tutils()->array_get('tutor_course_price_type', $_POST);
|
280 |
-
if ($price_type){
|
281 |
-
update_post_meta($post_ID, '_tutor_course_price_type', $price_type);
|
282 |
}
|
283 |
|
284 |
-
//Course Duration
|
285 |
-
if ( ! empty($_POST['course_duration'])){
|
286 |
-
$video = tutils()->sanitize_array($_POST['course_duration']);
|
287 |
-
update_post_meta($post_ID, '_course_duration', $video);
|
288 |
}
|
289 |
|
290 |
-
if ( ! empty($_POST['course_level'])){
|
291 |
-
$course_level = sanitize_text_field($_POST['course_level']);
|
292 |
-
update_post_meta($post_ID, '_tutor_course_level', $course_level);
|
293 |
}
|
294 |
|
295 |
-
$additional_data_edit = tutils()->avalue_dot('_tutor_course_additional_data_edit', $_POST);
|
296 |
-
if ($additional_data_edit) {
|
297 |
-
if (!empty($_POST['course_benefits'])) {
|
298 |
-
$course_benefits = wp_kses_post($_POST['course_benefits']);
|
299 |
-
update_post_meta($post_ID, '_tutor_course_benefits', $course_benefits);
|
300 |
} else {
|
301 |
-
delete_post_meta($post_ID, '_tutor_course_benefits');
|
302 |
}
|
303 |
|
304 |
-
if (!empty($_POST['course_requirements'])) {
|
305 |
-
$requirements = wp_kses_post($_POST['course_requirements']);
|
306 |
-
update_post_meta($post_ID, '_tutor_course_requirements', $requirements);
|
307 |
} else {
|
308 |
-
delete_post_meta($post_ID, '_tutor_course_requirements');
|
309 |
}
|
310 |
|
311 |
-
if (!empty($_POST['course_target_audience'])) {
|
312 |
-
$target_audience = wp_kses_post($_POST['course_target_audience']);
|
313 |
-
update_post_meta($post_ID, '_tutor_course_target_audience', $target_audience);
|
314 |
} else {
|
315 |
-
delete_post_meta($post_ID, '_tutor_course_target_audience');
|
316 |
}
|
317 |
|
318 |
-
if (!empty($_POST['course_material_includes'])) {
|
319 |
-
$material_includes = wp_kses_post($_POST['course_material_includes']);
|
320 |
-
update_post_meta($post_ID, '_tutor_course_material_includes', $material_includes);
|
321 |
} else {
|
322 |
-
delete_post_meta($post_ID, '_tutor_course_material_includes');
|
323 |
}
|
324 |
}
|
325 |
|
326 |
-
|
327 |
/**
|
328 |
* Sorting Topics and lesson
|
329 |
*/
|
330 |
-
if ( ! empty($_POST['tutor_topics_lessons_sorting'])){
|
331 |
-
$new_order = sanitize_text_field(stripslashes($_POST['tutor_topics_lessons_sorting']));
|
332 |
-
$order
|
333 |
|
334 |
-
if (is_array($order) && count($order)){
|
335 |
$i = 0;
|
336 |
-
foreach ($order as $topic ){
|
337 |
$i++;
|
338 |
$wpdb->update(
|
339 |
$wpdb->posts,
|
340 |
-
array('menu_order' => $i),
|
341 |
-
array('ID' => $topic['topic_id'])
|
342 |
);
|
343 |
|
344 |
/**
|
@@ -347,38 +361,41 @@ class Course extends Tutor_Base {
|
|
347 |
|
348 |
$wpdb->update(
|
349 |
$wpdb->posts,
|
350 |
-
array('post_parent' => 0),
|
351 |
-
array('post_parent' => $topic['topic_id'])
|
352 |
);
|
353 |
|
354 |
/**
|
355 |
* Lesson Attaching with topic ID
|
356 |
* sorting lesson
|
357 |
*/
|
358 |
-
if (isset($topic['lesson_ids'])){
|
359 |
$lesson_ids = $topic['lesson_ids'];
|
360 |
-
}else{
|
361 |
$lesson_ids = array();
|
362 |
}
|
363 |
-
if (count($lesson_ids)){
|
364 |
-
foreach ($lesson_ids as $lesson_key => $lesson_id ){
|
365 |
$wpdb->update(
|
366 |
$wpdb->posts,
|
367 |
-
array(
|
368 |
-
|
|
|
|
|
|
|
369 |
);
|
370 |
}
|
371 |
}
|
372 |
}
|
373 |
}
|
374 |
}
|
375 |
-
|
376 |
-
if ($additional_data_edit) {
|
377 |
-
if ( ! empty($_POST['video']['source'])) { //Video
|
378 |
-
$video = tutor_utils()->array_get('video', $_POST);
|
379 |
-
update_post_meta($post_ID, '_video', $video);
|
380 |
-
}else{
|
381 |
-
delete_post_meta($post_ID, '_video');
|
382 |
}
|
383 |
}
|
384 |
|
@@ -387,76 +404,82 @@ class Course extends Tutor_Base {
|
|
387 |
*/
|
388 |
|
389 |
$author_id = $post->post_author;
|
390 |
-
$attached
|
391 |
-
|
392 |
-
|
|
|
|
|
|
|
|
|
|
|
393 |
|
394 |
-
if ( ! $attached){
|
395 |
-
add_user_meta($author_id, '_tutor_instructor_course_id', $post_ID);
|
396 |
}
|
397 |
|
398 |
/**
|
399 |
* Disable question and answer for this course
|
|
|
400 |
* @since 1.7.0
|
401 |
*/
|
402 |
-
if ($additional_data_edit) {
|
403 |
-
foreach($this->additional_meta as $key){
|
404 |
-
update_post_meta($post_ID, $key, (isset($_POST[$key]) ? 'yes' : 'no'));
|
405 |
}
|
406 |
}
|
407 |
|
408 |
-
do_action(
|
409 |
}
|
410 |
|
411 |
/**
|
412 |
* Tutor add course topic
|
413 |
*/
|
414 |
-
public function tutor_add_course_topic(){
|
415 |
tutils()->checking_nonce();
|
416 |
|
417 |
-
if (empty($_POST['topic_title']) ) {
|
418 |
wp_send_json_error();
|
419 |
}
|
420 |
-
$course_id
|
421 |
-
$next_topic_order_id = tutor_utils()->get_next_topic_order_id($course_id);
|
422 |
-
|
423 |
-
if(!tutils()->can_user_manage('course', $course_id)) {
|
424 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
425 |
}
|
426 |
|
427 |
$topic_title = sanitize_text_field( $_POST['topic_title'] );
|
428 |
$topic_summery = wp_kses_post( $_POST['topic_summery'] );
|
429 |
|
430 |
-
$post_arr
|
431 |
'post_type' => 'topics',
|
432 |
'post_title' => $topic_title,
|
433 |
'post_content' => $topic_summery,
|
434 |
'post_status' => 'publish',
|
435 |
'post_author' => get_current_user_id(),
|
436 |
'post_parent' => $course_id,
|
437 |
-
'menu_order'
|
438 |
);
|
439 |
$current_topic_id = wp_insert_post( $post_arr );
|
440 |
|
441 |
ob_start();
|
442 |
-
include
|
443 |
$course_contents = ob_get_clean();
|
444 |
|
445 |
-
wp_send_json_success(array('course_contents' => $course_contents));
|
446 |
}
|
447 |
|
448 |
/**
|
449 |
* Update the topic
|
450 |
*/
|
451 |
-
public function tutor_update_topic(){
|
452 |
tutils()->checking_nonce();
|
453 |
|
454 |
-
$topic_id
|
455 |
-
$topic_title
|
456 |
-
$topic_summery = wp_kses_post($_POST['topic_summery']);
|
457 |
|
458 |
-
if(!tutils()->can_user_manage('topic', $topic_id)) {
|
459 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
460 |
}
|
461 |
|
462 |
$topic_attr = array(
|
@@ -466,7 +489,7 @@ class Course extends Tutor_Base {
|
|
466 |
);
|
467 |
wp_update_post( $topic_attr );
|
468 |
|
469 |
-
wp_send_json_success(array('msg' => __('Topic has been updated', 'tutor') ));
|
470 |
}
|
471 |
|
472 |
|
@@ -477,13 +500,13 @@ class Course extends Tutor_Base {
|
|
477 |
*
|
478 |
* Add Lesson column
|
479 |
*/
|
480 |
-
public function add_column($columns){
|
481 |
$date_col = $columns['date'];
|
482 |
-
unset($columns['date']);
|
483 |
-
$columns['lessons']
|
484 |
-
$columns['students'] = __('Students', 'tutor');
|
485 |
-
$columns['price']
|
486 |
-
$columns['date']
|
487 |
|
488 |
return $columns;
|
489 |
}
|
@@ -491,88 +514,87 @@ class Course extends Tutor_Base {
|
|
491 |
/**
|
492 |
* @param $column
|
493 |
* @param $post_id
|
494 |
-
*
|
495 |
*/
|
496 |
-
public function custom_lesson_column($column, $post_id ){
|
497 |
-
if ($column === 'lessons'){
|
498 |
-
echo tutor_utils()->get_lesson_count_by_course($post_id);
|
499 |
}
|
500 |
|
501 |
-
if ($column === 'students'){
|
502 |
-
echo tutor_utils()->count_enrolled_users_by_course($post_id);
|
503 |
}
|
504 |
|
505 |
-
if ($column === 'price'){
|
506 |
-
$price = tutor_utils()->get_course_price($post_id);
|
507 |
-
if ($price){
|
508 |
-
$monetize_by = tutils()->get_option('monetize_by');
|
509 |
-
if (function_exists('wc_price') && $monetize_by === 'wc'){
|
510 |
-
echo '<span class="tutor-label-success">'.wc_price($price).'</span>';
|
511 |
-
}else{
|
512 |
-
echo '<span class="tutor-label-success">'
|
513 |
}
|
514 |
-
}else{
|
515 |
-
echo apply_filters('tutor-loop-default-price', __( 'free', 'tutor' ));
|
516 |
}
|
517 |
}
|
518 |
}
|
519 |
|
520 |
|
521 |
-
public function tutor_delete_topic(){
|
522 |
|
523 |
-
tutils()->checking_nonce('get');
|
524 |
-
|
525 |
-
!isset($_GET['topic_id']) ? exit() : 0;
|
526 |
|
527 |
global $wpdb;
|
528 |
|
529 |
-
$topic_id = (int) sanitize_text_field($_GET['topic_id']);
|
530 |
$wpdb->update(
|
531 |
$wpdb->posts,
|
532 |
-
array('post_parent' => 0),
|
533 |
-
array('post_parent' => $topic_id)
|
534 |
);
|
535 |
|
536 |
$wpdb->delete(
|
537 |
$wpdb->postmeta,
|
538 |
-
array('post_id' => $topic_id)
|
539 |
);
|
540 |
|
541 |
-
wp_delete_post($topic_id);
|
542 |
-
wp_safe_redirect(wp_get_referer());
|
543 |
}
|
544 |
|
545 |
-
public function tutor_delete_announcement(){
|
546 |
-
tutor_utils()->checking_nonce('get');
|
547 |
|
548 |
-
$announcement_id = (int) sanitize_text_field($_GET['topic_id']);
|
549 |
|
550 |
-
wp_delete_post($announcement_id);
|
551 |
-
wp_safe_redirect(wp_get_referer());
|
552 |
}
|
553 |
|
554 |
-
public function enroll_now(){
|
555 |
|
556 |
-
//Checking if action comes from Enroll form
|
557 |
-
if (tutor_utils()->array_get('tutor_course_action', $_POST) !== '_tutor_course_enroll_now' || ! isset($_POST['tutor_course_id']) ){
|
558 |
return;
|
559 |
}
|
560 |
-
//Checking Nonce
|
561 |
tutor_utils()->checking_nonce();
|
562 |
|
563 |
$user_id = get_current_user_id();
|
564 |
-
if ( ! $user_id){
|
565 |
-
exit(__('Please Sign In first', 'tutor'));
|
566 |
}
|
567 |
|
568 |
-
$course_id = (int) sanitize_text_field($_POST['tutor_course_id']);
|
569 |
-
$user_id
|
570 |
|
571 |
/**
|
572 |
* TODO: need to check purchase information
|
573 |
*/
|
574 |
|
575 |
-
$is_purchasable = tutor_utils()->is_course_purchasable($course_id);
|
576 |
|
577 |
/**
|
578 |
* If is is not purchasable, it's free, and enroll right now
|
@@ -581,16 +603,16 @@ class Course extends Tutor_Base {
|
|
581 |
*
|
582 |
* @since: v.1.0.0
|
583 |
*/
|
584 |
-
if ($is_purchasable){
|
585 |
-
//process purchase
|
586 |
|
587 |
-
}else{
|
588 |
-
//Free enroll
|
589 |
-
tutor_utils()->do_enroll($course_id);
|
590 |
}
|
591 |
|
592 |
$referer_url = wp_get_referer();
|
593 |
-
wp_redirect($referer_url);
|
594 |
}
|
595 |
|
596 |
/**
|
@@ -599,169 +621,178 @@ class Course extends Tutor_Base {
|
|
599 |
*
|
600 |
* @since v.1.0.0
|
601 |
*/
|
602 |
-
public function mark_course_complete(){
|
603 |
-
if ( ! isset($_POST['tutor_action'])
|
604 |
return;
|
605 |
}
|
606 |
-
//Checking nonce
|
607 |
tutor_utils()->checking_nonce();
|
608 |
|
609 |
$user_id = get_current_user_id();
|
610 |
|
611 |
-
//TODO: need to show view if not signed_in
|
612 |
-
if ( ! $user_id){
|
613 |
-
die(__('Please Sign-In', 'tutor'));
|
614 |
}
|
615 |
|
616 |
-
$course_id = (int) sanitize_text_field($_POST['course_id']);
|
617 |
|
618 |
-
do_action('tutor_course_complete_before', $course_id);
|
619 |
/**
|
620 |
* Marking course completed at Comment
|
621 |
*/
|
622 |
|
623 |
global $wpdb;
|
624 |
|
625 |
-
$date = date(
|
626 |
|
627 |
-
//Making sure that, hash is unique
|
628 |
-
do{
|
629 |
-
$hash
|
630 |
-
$hasHash = (int) $wpdb->get_var(
|
631 |
-
|
632 |
-
|
|
|
|
|
|
|
|
|
633 |
|
634 |
-
}while($hasHash > 0);
|
635 |
|
636 |
$data = array(
|
637 |
-
'comment_post_ID'
|
638 |
-
'comment_author'
|
639 |
-
'comment_date'
|
640 |
-
'comment_date_gmt'
|
641 |
-
'comment_content'
|
642 |
-
'comment_approved'
|
643 |
-
'comment_agent'
|
644 |
-
'comment_type'
|
645 |
-
'user_id'
|
646 |
);
|
647 |
|
648 |
-
$wpdb->insert($wpdb->comments, $data);
|
649 |
|
650 |
-
do_action('tutor_course_complete_after', $course_id, $user_id);
|
651 |
|
652 |
-
$permalink = get_the_permalink($course_id);
|
653 |
|
654 |
// Set temporary identifier to show review pop up
|
655 |
-
if(!get_tutor_option( 'disable_course_review' )) {
|
656 |
-
$rating = tutor_utils()->get_course_rating_by_user($course_id, $user_id);
|
657 |
-
if(
|
658 |
-
update_option(
|
659 |
-
'
|
660 |
-
|
661 |
-
|
662 |
-
|
|
|
|
|
|
|
663 |
}
|
664 |
}
|
665 |
-
|
666 |
-
wp_redirect($permalink);
|
667 |
exit;
|
668 |
}
|
669 |
|
670 |
public function popup_review_form() {
|
671 |
-
if(is_user_logged_in()) {
|
672 |
-
$key
|
673 |
$popup = get_option( $key );
|
674 |
|
675 |
-
if(is_array($popup)) {
|
676 |
|
677 |
-
if($popup['expires']>time()) {
|
678 |
$course_id = $popup['course_id'];
|
679 |
-
include tutor()->path.'views/modal/review.php';
|
680 |
}
|
681 |
|
682 |
-
delete_option($key);
|
683 |
}
|
684 |
}
|
685 |
}
|
686 |
-
|
687 |
-
public function tutor_load_instructors_modal(){
|
688 |
tutils()->checking_nonce();
|
689 |
-
|
690 |
global $wpdb;
|
691 |
|
692 |
-
$course_id
|
693 |
-
$search_terms = sanitize_text_field(tutor_utils()->avalue_dot('search_terms', $_POST));
|
694 |
|
695 |
-
if(!tutils()->can_user_manage('course', $course_id)) {
|
696 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
697 |
}
|
698 |
-
|
699 |
-
$saved_instructors = tutor_utils()->get_instructors_by_course($course_id);
|
700 |
-
$instructors = array();
|
701 |
|
702 |
-
$
|
|
|
|
|
|
|
703 |
|
704 |
-
if ($saved_instructors){
|
705 |
-
$saved_instructors_ids = wp_list_pluck($saved_instructors, 'ID');
|
706 |
-
$instructor_not_in_ids = implode(',', $saved_instructors_ids);
|
707 |
-
$not_in_sql
|
708 |
}
|
709 |
|
710 |
$search_sql = '';
|
711 |
-
if ($search_terms){
|
712 |
$search_sql = "AND (user.user_login like '%{$search_terms}%' or user.user_nicename like '%{$search_terms}%' or user.display_name like '%{$search_terms}%') ";
|
713 |
}
|
714 |
|
715 |
-
$instructors = $wpdb->get_results(
|
|
|
716 |
INNER JOIN {$wpdb->usermeta} meta ON user.ID = meta.user_id AND meta.meta_key = '_tutor_instructor_status' AND meta.meta_value = 'approved'
|
717 |
-
WHERE 1=1 {$not_in_sql} {$search_sql} limit 10 "
|
|
|
718 |
|
719 |
$output = '';
|
720 |
-
if (is_array($instructors) && count($instructors)){
|
721 |
$instructor_output = '';
|
722 |
-
foreach ($instructors as $instructor){
|
723 |
-
$instructor_output .=
|
724 |
}
|
725 |
|
726 |
-
$output .= apply_filters('tutor_course_instructors_html', $instructor_output, $instructors);
|
727 |
|
728 |
-
}else{
|
729 |
-
$output .=
|
|
|
730 |
}
|
731 |
|
732 |
-
|
733 |
-
|
734 |
-
$output .= '<p class="tutor-notice-warning" style="margin-top: 50px; font-size: 14px;">'. sprintf( __('To add unlimited multiple instructors in your course, get %sTutor LMS Pro%s', 'tutor'), '<a href="https://www.themeum.com/product/tutor-lms" target="_blank">', "</a>" ) .'</p>';
|
735 |
}
|
736 |
|
737 |
-
wp_send_json_success(array('output' => $output));
|
738 |
}
|
739 |
|
740 |
-
public function tutor_add_instructors_to_course(){
|
741 |
tutils()->checking_nonce();
|
742 |
|
743 |
-
$course_id
|
744 |
-
$instructor_ids = tutor_utils()->avalue_dot('tutor_instructor_ids', $_POST);
|
745 |
-
|
746 |
-
if(!tutils()->can_user_manage('course', $course_id)) {
|
747 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
748 |
}
|
749 |
|
750 |
-
if (is_array($instructor_ids) && count($instructor_ids)){
|
751 |
-
foreach ($instructor_ids as $instructor_id){
|
752 |
-
add_user_meta($instructor_id, '_tutor_instructor_course_id', $course_id);
|
753 |
}
|
754 |
}
|
755 |
|
756 |
-
$saved_instructors = tutor_utils()->get_instructors_by_course($course_id);
|
757 |
-
$output
|
758 |
|
759 |
-
if ($saved_instructors){
|
760 |
-
foreach ($saved_instructors as $t){
|
761 |
|
762 |
-
$output .= '<div id="added-instructor-id-'
|
763 |
-
<span class="instructor-icon">'.get_avatar($t->ID, 30).'</span>
|
764 |
-
<span class="instructor-name"> '
|
765 |
<span class="instructor-control">
|
766 |
<a href="javascript:;" class="tutor-instructor-delete-btn"><i class="tutor-icon-line-cross"></i></a>
|
767 |
</span>
|
@@ -769,55 +800,62 @@ class Course extends Tutor_Base {
|
|
769 |
}
|
770 |
}
|
771 |
|
772 |
-
wp_send_json_success(array('output' => $output));
|
773 |
}
|
774 |
|
775 |
-
public function detach_instructor_from_course(){
|
776 |
tutils()->checking_nonce();
|
777 |
|
778 |
global $wpdb;
|
779 |
|
780 |
-
$instructor_id = (int) sanitize_text_field($_POST['instructor_id']);
|
781 |
-
$course_id
|
782 |
|
783 |
-
if(!tutils()->can_user_manage('course', $course_id)) {
|
784 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
785 |
}
|
786 |
-
|
787 |
-
$wpdb->delete(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
wp_send_json_success();
|
789 |
}
|
790 |
|
791 |
-
public function tutor_delete_dashboard_course(){
|
792 |
tutils()->checking_nonce();
|
793 |
|
794 |
-
$course_id = intval(sanitize_text_field($_POST['course_id']));
|
795 |
|
796 |
-
if(!tutils()->can_user_manage('course', $course_id)) {
|
797 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
798 |
}
|
799 |
|
800 |
-
wp_trash_post($course_id);
|
801 |
-
wp_send_json_success(
|
802 |
}
|
803 |
|
804 |
|
805 |
-
public function tutor_add_gutenberg_author($data
|
806 |
global $wpdb;
|
807 |
|
808 |
$courses_post_type = tutor()->course_post_type;
|
809 |
-
$post_type
|
810 |
|
811 |
-
if ($courses_post_type === $post_type){
|
812 |
-
|
813 |
-
|
814 |
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
|
822 |
return $data;
|
823 |
}
|
@@ -828,53 +866,53 @@ class Course extends Tutor_Base {
|
|
828 |
* @param $postData
|
829 |
*
|
830 |
* Attach product during save course from the frontend course dashboard.
|
831 |
-
*
|
832 |
* @return string
|
833 |
*
|
834 |
* @since v.1.3.4
|
835 |
*/
|
836 |
-
public function attach_product_with_course($post_ID, $postData){
|
837 |
-
$attached_product_id = tutor_utils()->get_course_product_id($post_ID);
|
838 |
-
$course_price
|
839 |
|
840 |
-
if ( ! $course_price){
|
841 |
return;
|
842 |
}
|
843 |
|
844 |
-
$monetize_by = tutor_utils()->get_option('monetize_by');
|
845 |
-
$course
|
846 |
|
847 |
-
if ($monetize_by === 'wc'){
|
848 |
|
849 |
$is_update = false;
|
850 |
-
if ($attached_product_id){
|
851 |
-
$wc_product = get_post_meta($attached_product_id, '_product_version', true);
|
852 |
-
if ($wc_product){
|
853 |
$is_update = true;
|
854 |
}
|
855 |
}
|
856 |
|
857 |
-
if ($is_update) {
|
858 |
-
$productObj = wc_get_product($attached_product_id);
|
859 |
-
$productObj->set_price($course_price); // set product price
|
860 |
-
$productObj->set_regular_price($course_price); // set product regular price
|
861 |
-
$productObj->set_sold_individually(true);
|
862 |
$product_id = $productObj->save();
|
863 |
-
if($productObj->is_type('subscription')) {
|
864 |
update_post_meta( $attached_product_id, '_subscription_price', $course_price );
|
865 |
}
|
866 |
} else {
|
867 |
$productObj = new \WC_Product();
|
868 |
-
$productObj->set_name($course->post_title);
|
869 |
-
$productObj->set_status('publish');
|
870 |
-
$productObj->set_price($course_price); // set product price
|
871 |
-
$productObj->set_regular_price($course_price); // set product regular price
|
872 |
-
$productObj->set_sold_individually(true);
|
873 |
|
874 |
$product_id = $productObj->save();
|
875 |
-
if ($product_id) {
|
876 |
update_post_meta( $post_ID, '_tutor_course_product_id', $product_id );
|
877 |
-
//Mark product for woocommerce
|
878 |
update_post_meta( $product_id, '_virtual', 'yes' );
|
879 |
update_post_meta( $product_id, '_tutor_product', 'yes' );
|
880 |
|
@@ -884,49 +922,44 @@ class Course extends Tutor_Base {
|
|
884 |
}
|
885 |
}
|
886 |
}
|
887 |
-
|
888 |
-
}elseif ($monetize_by === 'edd'){
|
889 |
|
890 |
$is_update = false;
|
891 |
-
|
892 |
-
if ($attached_product_id){
|
893 |
-
$edd_price = get_post_meta($attached_product_id, 'edd_price', true);
|
894 |
-
if ($edd_price){
|
895 |
$is_update = true;
|
896 |
}
|
897 |
}
|
898 |
|
899 |
-
if ($is_update){
|
900 |
-
//Update the product
|
901 |
update_post_meta( $attached_product_id, 'edd_price', $course_price );
|
902 |
-
}else{
|
903 |
-
//Create new product
|
904 |
-
|
905 |
-
$post_arr
|
906 |
-
'post_type'
|
907 |
-
'post_title'
|
908 |
-
'post_status'
|
909 |
-
'post_author'
|
910 |
);
|
911 |
$download_id = wp_insert_post( $post_arr );
|
912 |
-
if ($download_id ) {
|
913 |
-
//edd_price
|
914 |
update_post_meta( $download_id, 'edd_price', $course_price );
|
915 |
|
916 |
update_post_meta( $post_ID, '_tutor_course_product_id', $download_id );
|
917 |
-
//Mark product for EDD
|
918 |
update_post_meta( $download_id, '_tutor_product', 'yes' );
|
919 |
|
920 |
$coursePostThumbnail = get_post_meta( $post_ID, '_thumbnail_id', true );
|
921 |
if ( $coursePostThumbnail ) {
|
922 |
set_post_thumbnail( $download_id, $coursePostThumbnail );
|
923 |
}
|
924 |
-
|
925 |
}
|
926 |
-
|
927 |
}
|
928 |
-
|
929 |
-
|
930 |
}
|
931 |
|
932 |
}
|
@@ -934,10 +967,11 @@ class Course extends Tutor_Base {
|
|
934 |
|
935 |
/**
|
936 |
* Add Course level to course settings
|
|
|
937 |
* @since v.1.4.1
|
938 |
*/
|
939 |
-
public function add_course_level_to_settings(){
|
940 |
-
include
|
941 |
}
|
942 |
|
943 |
/**
|
@@ -945,39 +979,41 @@ class Course extends Tutor_Base {
|
|
945 |
*
|
946 |
* @since v.1.4.8
|
947 |
*/
|
948 |
-
public function tutor_lesson_load_before(){
|
949 |
-
$course_id
|
950 |
-
$completed_lessons = tutor_utils()->get_completed_lesson_count_by_course($course_id);
|
951 |
-
if (is_user_logged_in()){
|
952 |
-
$is_course_started = get_post_meta($course_id, '_tutor_course_started', true);
|
953 |
-
if ( ! $completed_lessons && ! $is_course_started){
|
954 |
-
update_post_meta($course_id, '_tutor_course_started', tutor_time());
|
955 |
-
do_action('tutor/course/started', $course_id);
|
956 |
}
|
957 |
}
|
958 |
}
|
959 |
|
960 |
/**
|
961 |
* Add Course level to course settings
|
|
|
962 |
* @since v.1.4.8
|
963 |
*/
|
964 |
-
public function course_elements_enable_disable(){
|
965 |
-
add_filter('tutor_course/single/completing-progress-bar', array($this, 'enable_disable_course_progress_bar') );
|
966 |
-
add_filter('tutor_course/single/material_includes', array($this, 'enable_disable_material_includes') );
|
967 |
-
add_filter('tutor_course/single/content', array($this, 'enable_disable_course_content') );
|
968 |
-
add_filter('tutor_course/single/benefits_html', array($this, 'enable_disable_course_benefits') );
|
969 |
-
add_filter('tutor_course/single/requirements_html', array($this, 'enable_disable_course_requirements') );
|
970 |
-
add_filter('tutor_course/single/audience_html', array($this, 'enable_disable_course_target_audience') );
|
971 |
-
add_filter('tutor_course/single/enrolled/nav_items', array($this, 'enable_disable_course_nav_items') );
|
972 |
}
|
973 |
|
974 |
/**
|
975 |
* Enable disable course progress bar
|
|
|
976 |
* @since v.1.4.8
|
977 |
*/
|
978 |
-
public function enable_disable_course_progress_bar($html){
|
979 |
-
$disable_option = (bool) get_tutor_option('disable_course_progress_bar');
|
980 |
-
if($disable_option){
|
981 |
return '';
|
982 |
}
|
983 |
return $html;
|
@@ -985,11 +1021,12 @@ class Course extends Tutor_Base {
|
|
985 |
|
986 |
/**
|
987 |
* Enable disable material includes
|
|
|
988 |
* @since v.1.4.8
|
989 |
*/
|
990 |
-
public function enable_disable_material_includes($html){
|
991 |
-
$disable_option = (bool) get_tutor_option('disable_course_material');
|
992 |
-
if($disable_option){
|
993 |
return '';
|
994 |
}
|
995 |
return $html;
|
@@ -997,11 +1034,12 @@ class Course extends Tutor_Base {
|
|
997 |
|
998 |
/**
|
999 |
* Enable disable course content
|
|
|
1000 |
* @since v.1.4.8
|
1001 |
*/
|
1002 |
-
public function enable_disable_course_content($html){
|
1003 |
-
$disable_option = (bool) get_tutor_option('disable_course_description');
|
1004 |
-
if($disable_option){
|
1005 |
return '';
|
1006 |
}
|
1007 |
return $html;
|
@@ -1009,11 +1047,12 @@ class Course extends Tutor_Base {
|
|
1009 |
|
1010 |
/**
|
1011 |
* Enable disable course benefits
|
|
|
1012 |
* @since v.1.4.8
|
1013 |
*/
|
1014 |
-
public function enable_disable_course_benefits($html){
|
1015 |
-
$disable_option = (bool) get_tutor_option('disable_course_benefits');
|
1016 |
-
if($disable_option){
|
1017 |
return '';
|
1018 |
}
|
1019 |
return $html;
|
@@ -1021,11 +1060,12 @@ class Course extends Tutor_Base {
|
|
1021 |
|
1022 |
/**
|
1023 |
* Enable disable course requirements
|
|
|
1024 |
* @since v.1.4.8
|
1025 |
*/
|
1026 |
-
public function enable_disable_course_requirements($html){
|
1027 |
-
$disable_option = (bool) get_tutor_option('disable_course_requirements');
|
1028 |
-
if($disable_option){
|
1029 |
return '';
|
1030 |
}
|
1031 |
return $html;
|
@@ -1033,35 +1073,37 @@ class Course extends Tutor_Base {
|
|
1033 |
|
1034 |
/**
|
1035 |
* Enable disable course target audience
|
|
|
1036 |
* @since v.1.4.8
|
1037 |
*/
|
1038 |
-
public function enable_disable_course_target_audience($html){
|
1039 |
-
$disable_option = (bool) get_tutor_option('disable_course_target_audience');
|
1040 |
-
if($disable_option){
|
1041 |
return '';
|
1042 |
}
|
1043 |
return $html;
|
1044 |
}
|
1045 |
-
|
1046 |
/**
|
1047 |
* Enable disable course nav items
|
|
|
1048 |
* @since v.1.4.8
|
1049 |
*/
|
1050 |
-
public function enable_disable_course_nav_items($items){
|
1051 |
global $wp_query, $post;
|
1052 |
-
$enable_q_and_a_on_course
|
1053 |
-
$disable_course_announcements = (bool) get_tutor_option('disable_course_announcements');
|
1054 |
|
1055 |
-
$disable_qa_for_this_course = ($wp_query->is_single && !empty($post)) ? get_post_meta($post->ID, '_tutor_disable_qa', true) : '';
|
1056 |
|
1057 |
-
if(
|
1058 |
-
if(tutils()->array_get('questions', $items)) {
|
1059 |
-
unset($items['questions']);
|
1060 |
}
|
1061 |
}
|
1062 |
-
if($disable_course_announcements){
|
1063 |
-
if(tutils()->array_get('announcements', $items)) {
|
1064 |
-
unset($items['announcements']);
|
1065 |
}
|
1066 |
}
|
1067 |
return $items;
|
@@ -1069,219 +1111,228 @@ class Course extends Tutor_Base {
|
|
1069 |
|
1070 |
/**
|
1071 |
* Filter product in shop page
|
|
|
1072 |
* @since v.1.4.9
|
1073 |
*/
|
1074 |
-
public function filter_product_in_shop_page(){
|
1075 |
-
$hide_course_from_shop_page = (bool) get_tutor_option('hide_course_from_shop_page');
|
1076 |
-
if(
|
1077 |
return;
|
1078 |
}
|
1079 |
-
add_action('woocommerce_product_query', array($this, 'filter_woocommerce_product_query'));
|
1080 |
-
add_filter('edd_downloads_query', array($this, 'filter_edd_downloads_query'), 10, 2);
|
1081 |
-
add_action('pre_get_posts', array($this, 'filter_archive_meta_query'), 1);
|
1082 |
}
|
1083 |
|
1084 |
/**
|
1085 |
* Tutor product meta query
|
|
|
1086 |
* @since v.1.4.9
|
1087 |
*/
|
1088 |
-
public function tutor_product_meta_query(){
|
1089 |
$meta_query = array(
|
1090 |
-
'key'
|
1091 |
-
'compare'
|
1092 |
);
|
1093 |
return $meta_query;
|
1094 |
}
|
1095 |
|
1096 |
/**
|
1097 |
* Filter product in woocommerce shop page
|
|
|
1098 |
* @since v.1.4.9
|
1099 |
*/
|
1100 |
-
public function filter_woocommerce_product_query($wp_query){
|
1101 |
-
$wp_query->set('meta_query', array($this->tutor_product_meta_query()));
|
1102 |
return $wp_query;
|
1103 |
}
|
1104 |
|
1105 |
/**
|
1106 |
* Filter product in edd downloads shortcode page
|
|
|
1107 |
* @since v.1.4.9
|
1108 |
*/
|
1109 |
-
public function filter_edd_downloads_query($query){
|
1110 |
$query['meta_query'][] = $this->tutor_product_meta_query();
|
1111 |
return $query;
|
1112 |
}
|
1113 |
|
1114 |
/**
|
1115 |
* Filter product in edd downloads archive page
|
|
|
1116 |
* @since v.1.4.9
|
1117 |
*/
|
1118 |
-
public function filter_archive_meta_query($wp_query){
|
1119 |
-
if(!is_admin() && $wp_query->is_archive && $wp_query->get('post_type') === 'download'){
|
1120 |
-
$wp_query->set('meta_query', array($this->tutor_product_meta_query()));
|
1121 |
}
|
1122 |
return $wp_query;
|
1123 |
}
|
1124 |
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
public function remove_price_if_enrolled($html){
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
}
|
1212 |
|
1213 |
/**
|
1214 |
* Add social share content in header
|
|
|
1215 |
* @since v.1.6.3
|
1216 |
*/
|
1217 |
-
|
1218 |
global $wp_query, $post;
|
1219 |
-
if ($wp_query->is_single && ! empty($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] === $this->course_post_type) { ?>
|
1220 |
<!--Facebook-->
|
1221 |
<meta property="og:type" content="website"/>
|
1222 |
-
<meta property="og:image" content="<?php echo get_tutor_course_thumbnail_src(); ?>" />
|
1223 |
-
<meta property="og:description" content="<?php echo esc_html($post->post_content); ?>" />
|
1224 |
<!--Twitter-->
|
1225 |
-
<meta name="twitter:image" content="<?php echo get_tutor_course_thumbnail_src(); ?>">
|
1226 |
-
<meta name="twitter:description" content="<?php echo esc_html($post->post_content); ?>">
|
1227 |
<!--Google+-->
|
1228 |
-
<meta itemprop="image" content="<?php echo get_tutor_course_thumbnail_src(); ?>">
|
1229 |
-
<meta itemprop="description" content="<?php echo esc_html($post->post_content); ?>">
|
|
|
1230 |
}
|
1231 |
}
|
1232 |
|
1233 |
/**
|
1234 |
* Get posts by type and parent
|
|
|
1235 |
* @since v.1.6.6
|
1236 |
*/
|
1237 |
-
public function tutor_get_post_ids($post_type, $post_parent) {
|
1238 |
$args = array(
|
1239 |
-
'fields'
|
1240 |
'post_type' => $post_type,
|
1241 |
'post_parent' => $post_parent,
|
1242 |
'post_status' => 'any',
|
1243 |
'posts_per_page' => -1,
|
1244 |
);
|
1245 |
-
return get_posts($args);
|
1246 |
}
|
1247 |
-
|
1248 |
/**
|
1249 |
* Delete course data when permanently deleting a course.
|
|
|
1250 |
* @since v.1.6.6
|
1251 |
*/
|
1252 |
function delete_tutor_course_data( $post_id ) {
|
1253 |
$course_post_type = tutor()->course_post_type;
|
1254 |
$lesson_post_type = tutor()->lesson_post_type;
|
1255 |
|
1256 |
-
if (get_post_type($post_id) == $course_post_type) {
|
1257 |
global $wpdb;
|
1258 |
-
$topic_ids = $this->tutor_get_post_ids('topics', $post_id);
|
1259 |
-
if ( !empty($topic_ids) ) {
|
1260 |
-
foreach ($topic_ids as $topic_id) {
|
1261 |
-
$content_post_type = apply_filters('tutor_course_contents_post_types', array($lesson_post_type, 'tutor_quiz'));
|
1262 |
-
$topic_content_ids = $this->tutor_get_post_ids($content_post_type, $topic_id);
|
1263 |
-
|
1264 |
-
foreach ($topic_content_ids as $content_id) {
|
1265 |
-
if( get_post_type($content_id) == 'tutor_quiz') {
|
1266 |
-
$wpdb->delete($wpdb->prefix.'tutor_quiz_attempts', array('quiz_id' => $content_id));
|
1267 |
-
$wpdb->delete($wpdb->prefix.'tutor_quiz_attempt_answers', array('quiz_id' => $content_id));
|
1268 |
-
|
1269 |
-
$questions_ids = $wpdb->get_col($wpdb->prepare("SELECT question_id FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = %d ", $content_id));
|
1270 |
-
if (is_array($questions_ids) && count($questions_ids)){
|
1271 |
-
$in_question_ids = "'".implode("','", $questions_ids)."'";
|
1272 |
-
$wpdb->query("DELETE FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id IN({$in_question_ids}) ");
|
1273 |
}
|
1274 |
-
$wpdb->delete($wpdb->prefix.'tutor_quiz_questions', array('quiz_id' => $content_id));
|
1275 |
}
|
1276 |
-
wp_delete_post($content_id, true);
|
1277 |
}
|
1278 |
-
wp_delete_post($topic_id, true);
|
1279 |
}
|
1280 |
}
|
1281 |
-
$child_post_ids = $this->tutor_get_post_ids(array('tutor_announcements', 'tutor_enrolled'), $post_id);
|
1282 |
-
if ( !empty($child_post_ids) ) {
|
1283 |
-
foreach ($child_post_ids as $child_post_id) {
|
1284 |
-
wp_delete_post($child_post_id, true);
|
1285 |
}
|
1286 |
}
|
1287 |
}
|
@@ -1289,48 +1340,49 @@ class Course extends Tutor_Base {
|
|
1289 |
|
1290 |
/**
|
1291 |
* tutor course setting metabox
|
|
|
1292 |
* @since v.1.7.0
|
1293 |
*/
|
1294 |
function tutor_course_setting_metabox( $post ) {
|
1295 |
-
|
1296 |
$disable_qa = $this->additional_meta[0];
|
1297 |
-
$is_public
|
1298 |
|
1299 |
-
$disable_qa_checked = get_post_meta($post->ID, $disable_qa, true)=='yes' ? 'checked="checked"' : '';
|
1300 |
-
$is_public_checked
|
1301 |
|
1302 |
-
do_action('tutor_before_course_sidebar_settings_metabox', $post);
|
1303 |
?>
|
1304 |
<div class="tutor-course-sidebar-settings-item" id="_tutor_is_course_public_meta_checkbox" style="display:none">
|
1305 |
-
<label for="<?php echo $is_public; ?>">
|
1306 |
-
<input id="<?php echo $is_public; ?>" type="checkbox" name="<?php echo $is_public; ?>" value="yes" <?php echo $is_public_checked; ?> />
|
1307 |
-
<?php _e('Make This Course Public', 'tutor'); ?>
|
1308 |
<small style="display:block;padding-left:24px">
|
1309 |
-
<?php _e('No enrollment required.', 'tutor'); ?>
|
1310 |
</small>
|
1311 |
</label>
|
1312 |
</div>
|
1313 |
<div class="tutor-course-sidebar-settings-item">
|
1314 |
-
<label for="<?php echo $disable_qa; ?>">
|
1315 |
<input type="hidden" name="_tutor_course_additional_data_edit" value="true" />
|
1316 |
-
<input id="<?php echo $disable_qa; ?>" type="checkbox" name="<?php echo $disable_qa; ?>" value="yes" <?php echo $disable_qa_checked; ?> />
|
1317 |
-
<?php _e('Disable Q&A', 'tutor'); ?>
|
1318 |
</label>
|
1319 |
</div>
|
1320 |
<?php
|
1321 |
-
do_action('tutor_after_course_sidebar_settings_metabox', $post);
|
1322 |
}
|
1323 |
|
1324 |
-
function tutor_course_setting_metabox_frontend( $post ){
|
1325 |
-
?>
|
1326 |
<div class="tutor-course-builder-section tutor-course-builder-info">
|
1327 |
<div class="tutor-course-builder-section-title">
|
1328 |
-
<h3><i class="tutor-icon-down"></i><span><?php esc_html_e('Tutor Settings', 'tutor'); ?></span></h3>
|
1329 |
</div>
|
1330 |
<div class="tutor-course-builder-section-content">
|
1331 |
<div class="tutor-frontend-builder-item-scope">
|
1332 |
<div class="tutor-form-group">
|
1333 |
-
<?php $this->tutor_course_setting_metabox($post); ?>
|
1334 |
</div>
|
1335 |
</div>
|
1336 |
</div>
|
@@ -1340,60 +1392,63 @@ class Course extends Tutor_Base {
|
|
1340 |
|
1341 |
/**
|
1342 |
* Delete associated enrollment
|
|
|
1343 |
* @since v.1.8.2
|
1344 |
*/
|
1345 |
-
public function delete_associated_enrollment($post_id) {
|
1346 |
-
|
1347 |
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
|
|
1352 |
{$wpdb->postmeta}
|
1353 |
-
WHERE
|
1354 |
-
meta_key='_tutor_enrolled_by_order_id'
|
1355 |
AND meta_value = %d
|
1356 |
-
",
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
|
|
1361 |
|
1362 |
-
|
1363 |
-
|
1364 |
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
|
1369 |
public function tutor_reset_course_progress() {
|
1370 |
tutils()->checking_nonce();
|
1371 |
-
$course_id = tutor_utils()->array_get('course_id', $_POST);
|
1372 |
|
1373 |
-
if(
|
1374 |
-
wp_send_json_error(array('message' => __('Invalid Course ID or Access Denied.', 'tutor')));
|
1375 |
return;
|
1376 |
}
|
1377 |
|
1378 |
-
tutor_utils()->delete_course_progress($course_id);
|
1379 |
-
wp_send_json_success(array('redirect_to' => tutor_utils()->get_course_first_lesson( $course_id ) ));
|
1380 |
}
|
1381 |
|
1382 |
/**
|
1383 |
* Do enroll if guest attempt to enroll and course is free
|
1384 |
-
*
|
1385 |
* @param $course_id
|
1386 |
-
*
|
1387 |
* @since 1.9.8
|
1388 |
*/
|
1389 |
public function enroll_after_login_if_attempt( $course_id ) {
|
1390 |
$course_id = sanitize_text_field( $course_id );
|
1391 |
if ( $course_id ) {
|
1392 |
-
$is_purchasable = tutor_utils()->is_course_purchasable($course_id);
|
1393 |
-
if (
|
1394 |
-
tutor_utils()->do_enroll($course_id);
|
1395 |
do_action( 'guest_attempt_after_enrollment', $course_id );
|
1396 |
}
|
1397 |
}
|
1398 |
}
|
1399 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
class Course extends Tutor_Base {
|
9 |
+
|
10 |
+
private $additional_meta = array(
|
11 |
'_tutor_disable_qa',
|
12 |
+
'_tutor_is_public_course',
|
13 |
);
|
14 |
|
15 |
public function __construct() {
|
16 |
parent::__construct();
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
add_action( 'add_meta_boxes', array( $this, 'register_meta_box' ) );
|
19 |
+
add_action( 'save_post_' . $this->course_post_type, array( $this, 'save_course_meta' ), 10, 2 );
|
20 |
+
add_action( 'wp_ajax_tutor_add_course_topic', array( $this, 'tutor_add_course_topic' ) );
|
21 |
+
add_action( 'wp_ajax_tutor_update_topic', array( $this, 'tutor_update_topic' ) );
|
22 |
+
|
23 |
+
// Add Column
|
24 |
+
add_filter( "manage_{$this->course_post_type}_posts_columns", array( $this, 'add_column' ), 10, 1 );
|
25 |
+
add_action( "manage_{$this->course_post_type}_posts_custom_column", array( $this, 'custom_lesson_column' ), 10, 2 );
|
26 |
|
27 |
+
add_action( 'admin_action_tutor_delete_topic', array( $this, 'tutor_delete_topic' ) );
|
28 |
+
add_action( 'admin_action_tutor_delete_announcement', array( $this, 'tutor_delete_announcement' ) );
|
29 |
|
30 |
+
// Frontend Action
|
31 |
+
add_action( 'template_redirect', array( $this, 'enroll_now' ) );
|
32 |
+
add_action( 'init', array( $this, 'mark_course_complete' ) );
|
33 |
|
34 |
+
// Modal Perform
|
35 |
+
add_action( 'wp_ajax_tutor_load_instructors_modal', array( $this, 'tutor_load_instructors_modal' ) );
|
36 |
+
add_action( 'wp_ajax_tutor_add_instructors_to_course', array( $this, 'tutor_add_instructors_to_course' ) );
|
37 |
+
add_action( 'wp_ajax_detach_instructor_from_course', array( $this, 'detach_instructor_from_course' ) );
|
38 |
|
39 |
/**
|
40 |
* Frontend Dashboard
|
41 |
*/
|
42 |
+
add_action( 'wp_ajax_tutor_delete_dashboard_course', array( $this, 'tutor_delete_dashboard_course' ) );
|
43 |
|
44 |
/**
|
45 |
* Gutenberg author support
|
46 |
*/
|
47 |
+
add_filter( 'wp_insert_post_data', array( $this, 'tutor_add_gutenberg_author' ), '99', 2 );
|
48 |
|
49 |
/**
|
50 |
* Frontend metabox supports for course builder
|
51 |
+
*
|
52 |
* @since v.1.3.4
|
53 |
*/
|
54 |
+
add_action( 'tutor/dashboard_course_builder_form_field_after', array( $this, 'register_meta_box_in_frontend' ) );
|
55 |
|
56 |
/**
|
57 |
* Do Stuff for the course save from frontend
|
58 |
*/
|
59 |
+
add_action( 'save_tutor_course', array( $this, 'attach_product_with_course' ), 10, 2 );
|
60 |
|
61 |
/**
|
62 |
* Add course level to course settings
|
63 |
+
*
|
64 |
* @since v.1.4.1
|
65 |
*/
|
66 |
+
add_action( 'tutor_course/settings_tab_content/after/general', array( $this, 'add_course_level_to_settings' ) );
|
67 |
|
68 |
/**
|
69 |
* Enable Disable Course Details Page Feature
|
70 |
+
*
|
71 |
* @since v.1.4.8
|
72 |
*/
|
73 |
$this->course_elements_enable_disable();
|
76 |
* @since v.1.4.8
|
77 |
* Check if course starting, set meta if starting
|
78 |
*/
|
79 |
+
add_action( 'tutor_lesson_load_before', array( $this, 'tutor_lesson_load_before' ) );
|
80 |
|
81 |
/**
|
82 |
* @since v.1.4.9
|
84 |
*/
|
85 |
$this->filter_product_in_shop_page();
|
86 |
|
87 |
+
/**
|
88 |
+
* Remove the course price if enrolled
|
89 |
+
*
|
90 |
+
* @since 1.5.8
|
91 |
+
*/
|
92 |
+
add_filter( 'tutor_course_price', array( $this, 'remove_price_if_enrolled' ) );
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Remove course complete button if course completion is strict mode
|
96 |
+
*
|
97 |
+
* @since v.1.6.1
|
98 |
+
*/
|
99 |
+
add_filter( 'tutor_course/single/complete_form', array( $this, 'tutor_lms_hide_course_complete_btn' ) );
|
100 |
+
add_filter( 'get_gradebook_generate_form_html', array( $this, 'get_generate_greadbook' ) );
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Add social share content in header
|
104 |
+
*
|
105 |
+
* @since v.1.6.3
|
106 |
+
*/
|
107 |
+
add_action( 'wp_head', array( $this, 'social_share_content' ) );
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Delete course data after deleted course
|
111 |
+
*
|
112 |
+
* @since v.1.6.6
|
113 |
+
*/
|
114 |
+
add_action( 'deleted_post', array( $this, 'delete_tutor_course_data' ) );
|
115 |
+
add_action( 'tutor/dashboard_course_builder_form_field_after', array( $this, 'tutor_course_setting_metabox_frontend' ) );
|
116 |
|
117 |
/**
|
118 |
+
* Delete course data after deleted course
|
119 |
+
*
|
120 |
+
* @since v.1.8.2
|
121 |
+
*/
|
122 |
+
add_action( 'before_delete_post', array( $this, 'delete_associated_enrollment' ) );
|
123 |
|
124 |
/**
|
125 |
* Show only own uploads in media library if user is instructor
|
126 |
+
*
|
127 |
* @since v1.8.9
|
128 |
*/
|
129 |
+
add_filter( 'posts_where', array( $this, 'restrict_media' ) );
|
130 |
|
131 |
/**
|
132 |
* Restrict new enrol/purchase button if course member limit reached
|
133 |
+
*
|
134 |
* @since v1.9.0
|
135 |
*/
|
136 |
+
add_filter( 'tutor_course_restrict_new_entry', array( $this, 'restrict_new_student_entry' ) );
|
137 |
|
138 |
/**
|
139 |
* Reset course progress on retake
|
140 |
+
*
|
141 |
* @since v1.9.5
|
142 |
*/
|
143 |
+
add_action( 'wp_ajax_tutor_reset_course_progress', array( $this, 'tutor_reset_course_progress' ) );
|
144 |
+
|
145 |
/**
|
146 |
* Popup for review
|
147 |
+
*
|
148 |
* @since v1.9.7
|
149 |
*/
|
150 |
+
add_action( 'wp_footer', array( $this, 'popup_review_form' ) );
|
151 |
|
152 |
/**
|
153 |
* Do enroll after login if guest take enroll attempt
|
154 |
+
*
|
155 |
* @since 1.9.8
|
156 |
*/
|
157 |
+
add_action( 'tutor_do_enroll_after_login_if_attempt', array( $this, 'enroll_after_login_if_attempt' ), 10, 1 );
|
158 |
}
|
159 |
|
160 |
+
public function restrict_new_student_entry( $content ) {
|
161 |
|
162 |
+
if ( ! tutils()->is_course_fully_booked() ) {
|
163 |
// No restriction if not fully booked
|
164 |
return $content;
|
165 |
}
|
166 |
+
|
167 |
return '<span class="tutor-course-booked-fully">
|
168 |
+
<img src="' . esc_url( tutor()->url . '/assets/images/icon-warning-info.svg' ) . '"/>
|
169 |
+
<span>' . __( 'Fully booked', 'tutor' ) . '</span>
|
170 |
</span>';
|
171 |
}
|
172 |
|
173 |
+
function restrict_media( $where ) {
|
174 |
+
|
175 |
+
if ( isset( $_POST['action'] ) && $_POST['action'] == 'query-attachments' && tutor_utils()->is_instructor() ) {
|
176 |
+
if ( ! tutor_utils()->has_user_role( array( 'administrator', 'editor' ) ) ) {
|
177 |
$where .= ' AND post_author=' . get_current_user_id();
|
178 |
}
|
179 |
}
|
180 |
+
|
181 |
return $where;
|
182 |
}
|
183 |
|
184 |
/**
|
185 |
* Registering metabox
|
186 |
*/
|
187 |
+
public function register_meta_box() {
|
188 |
+
$coursePostType = tutor()->course_post_type;
|
189 |
+
$course_marketplace = tutor_utils()->get_option( 'enable_course_marketplace' );
|
190 |
+
// add_meta_box( 'tutor-course-levels', __( 'Course Level', 'tutor' ), array($this, 'course_level_metabox'), $coursePostType );
|
191 |
+
add_meta_box( 'tutor-course-topics', __( 'Course Builder', 'tutor' ), array( $this, 'course_meta_box' ), $coursePostType );
|
192 |
+
add_meta_box( 'tutor-course-additional-data', __( 'Additional Data', 'tutor' ), array( $this, 'course_additional_data_meta_box' ), $coursePostType );
|
193 |
+
add_meta_box( 'tutor-course-videos', __( 'Video', 'tutor' ), array( $this, 'video_metabox' ), $coursePostType );
|
194 |
+
if ( $course_marketplace ) {
|
195 |
add_meta_box( 'tutor-instructors', __( 'Instructors', 'tutor' ), array( $this, 'instructors_metabox' ), $coursePostType );
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
+
* Tutor course sidebar settings metabox
|
200 |
+
*
|
201 |
+
* @since v.1.7.0
|
202 |
+
*/
|
203 |
+
add_meta_box( 'tutor-course-sidebar-settings', __( 'Tutor Settings', 'tutor' ), array( $this, 'tutor_course_setting_metabox' ), $coursePostType, 'side' );
|
204 |
}
|
205 |
|
206 |
+
public function course_meta_box( $echo = true ) {
|
207 |
ob_start();
|
208 |
+
include tutor()->path . 'views/metabox/course-topics.php';
|
209 |
$content = ob_get_clean();
|
210 |
|
211 |
+
if ( $echo ) {
|
212 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
213 |
+
} else {
|
214 |
return $content;
|
215 |
}
|
216 |
}
|
217 |
|
218 |
+
public function course_additional_data_meta_box( $echo = true ) {
|
219 |
|
220 |
ob_start();
|
221 |
+
include tutor()->path . 'views/metabox/course-additional-data.php';
|
222 |
$content = ob_get_clean();
|
223 |
|
224 |
+
if ( $echo ) {
|
225 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
226 |
+
} else {
|
227 |
return $content;
|
228 |
}
|
229 |
}
|
230 |
|
231 |
+
public function video_metabox( $echo = true ) {
|
232 |
ob_start();
|
233 |
+
include tutor()->path . 'views/metabox/video-metabox.php';
|
234 |
$content = ob_get_clean();
|
235 |
|
236 |
+
if ( $echo ) {
|
237 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
238 |
+
} else {
|
239 |
return $content;
|
240 |
}
|
241 |
}
|
242 |
|
243 |
+
public function course_level_metabox( $echo = true ) {
|
244 |
ob_start();
|
245 |
+
include tutor()->path . 'views/metabox/course-level-metabox.php';
|
246 |
$content = ob_get_clean();
|
247 |
|
248 |
+
if ( $echo ) {
|
249 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
250 |
+
} else {
|
251 |
return $content;
|
252 |
}
|
253 |
}
|
254 |
|
255 |
+
public function instructors_metabox( $echo = true ) {
|
256 |
ob_start();
|
257 |
include tutor()->path . 'views/metabox/instructors-metabox.php';
|
258 |
$content = ob_get_clean();
|
259 |
|
260 |
+
if ( $echo ) {
|
261 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
262 |
+
} else {
|
263 |
return $content;
|
264 |
}
|
265 |
}
|
266 |
|
267 |
/**
|
268 |
* Register metabox in course builder tutor
|
269 |
+
*
|
270 |
* @since v.1.3.4
|
271 |
*/
|
272 |
+
public function register_meta_box_in_frontend() {
|
273 |
+
do_action( 'tutor_course_builder_metabox_before', get_the_ID() );
|
274 |
+
course_builder_section_wrap( $this->video_metabox( $echo = false ), __( 'Video', 'tutor' ) );
|
275 |
+
course_builder_section_wrap( $this->course_meta_box( $echo = false ), __( 'Course Builder', 'tutor' ) );
|
276 |
+
course_builder_section_wrap( $this->instructors_metabox( $echo = false ), __( 'Instructors', 'tutor' ) );
|
277 |
+
course_builder_section_wrap( $this->course_additional_data_meta_box( $echo = false ), __( 'Additional Data', 'tutor' ) );
|
278 |
+
do_action( 'tutor_course_builder_metabox_after', get_the_ID() );
|
279 |
}
|
280 |
|
281 |
/**
|
283 |
*
|
284 |
* Insert Topic and attached it with Course
|
285 |
*/
|
286 |
+
public function save_course_meta( $post_ID, $post ) {
|
287 |
global $wpdb;
|
288 |
|
289 |
+
do_action( 'tutor_save_course', $post_ID, $post );
|
290 |
+
|
291 |
/**
|
292 |
* Save course price type
|
293 |
*/
|
294 |
+
$price_type = tutils()->array_get( 'tutor_course_price_type', tutor_sanitize_data($_POST) );
|
295 |
+
if ( $price_type ) {
|
296 |
+
update_post_meta( $post_ID, '_tutor_course_price_type', $price_type );
|
297 |
}
|
298 |
|
299 |
+
// Course Duration
|
300 |
+
if ( ! empty( $_POST['course_duration'] ) ) {
|
301 |
+
$video = tutils()->sanitize_array( $_POST['course_duration'] );
|
302 |
+
update_post_meta( $post_ID, '_course_duration', $video );
|
303 |
}
|
304 |
|
305 |
+
if ( ! empty( $_POST['course_level'] ) ) {
|
306 |
+
$course_level = sanitize_text_field( $_POST['course_level'] );
|
307 |
+
update_post_meta( $post_ID, '_tutor_course_level', $course_level );
|
308 |
}
|
309 |
|
310 |
+
$additional_data_edit = tutils()->avalue_dot( '_tutor_course_additional_data_edit', tutor_sanitize_data($_POST) );
|
311 |
+
if ( $additional_data_edit ) {
|
312 |
+
if ( ! empty( $_POST['course_benefits'] ) ) {
|
313 |
+
$course_benefits = wp_kses_post( $_POST['course_benefits'] );
|
314 |
+
update_post_meta( $post_ID, '_tutor_course_benefits', $course_benefits );
|
315 |
} else {
|
316 |
+
delete_post_meta( $post_ID, '_tutor_course_benefits' );
|
317 |
}
|
318 |
|
319 |
+
if ( ! empty( $_POST['course_requirements'] ) ) {
|
320 |
+
$requirements = wp_kses_post( $_POST['course_requirements'] );
|
321 |
+
update_post_meta( $post_ID, '_tutor_course_requirements', $requirements );
|
322 |
} else {
|
323 |
+
delete_post_meta( $post_ID, '_tutor_course_requirements' );
|
324 |
}
|
325 |
|
326 |
+
if ( ! empty( $_POST['course_target_audience'] ) ) {
|
327 |
+
$target_audience = wp_kses_post( $_POST['course_target_audience'] );
|
328 |
+
update_post_meta( $post_ID, '_tutor_course_target_audience', $target_audience );
|
329 |
} else {
|
330 |
+
delete_post_meta( $post_ID, '_tutor_course_target_audience' );
|
331 |
}
|
332 |
|
333 |
+
if ( ! empty( $_POST['course_material_includes'] ) ) {
|
334 |
+
$material_includes = wp_kses_post( $_POST['course_material_includes'] );
|
335 |
+
update_post_meta( $post_ID, '_tutor_course_material_includes', $material_includes );
|
336 |
} else {
|
337 |
+
delete_post_meta( $post_ID, '_tutor_course_material_includes' );
|
338 |
}
|
339 |
}
|
340 |
|
|
|
341 |
/**
|
342 |
* Sorting Topics and lesson
|
343 |
*/
|
344 |
+
if ( ! empty( $_POST['tutor_topics_lessons_sorting'] ) ) {
|
345 |
+
$new_order = sanitize_text_field( stripslashes( $_POST['tutor_topics_lessons_sorting'] ) );
|
346 |
+
$order = json_decode( $new_order, true );
|
347 |
|
348 |
+
if ( is_array( $order ) && count( $order ) ) {
|
349 |
$i = 0;
|
350 |
+
foreach ( $order as $topic ) {
|
351 |
$i++;
|
352 |
$wpdb->update(
|
353 |
$wpdb->posts,
|
354 |
+
array( 'menu_order' => $i ),
|
355 |
+
array( 'ID' => $topic['topic_id'] )
|
356 |
);
|
357 |
|
358 |
/**
|
361 |
|
362 |
$wpdb->update(
|
363 |
$wpdb->posts,
|
364 |
+
array( 'post_parent' => 0 ),
|
365 |
+
array( 'post_parent' => $topic['topic_id'] )
|
366 |
);
|
367 |
|
368 |
/**
|
369 |
* Lesson Attaching with topic ID
|
370 |
* sorting lesson
|
371 |
*/
|
372 |
+
if ( isset( $topic['lesson_ids'] ) ) {
|
373 |
$lesson_ids = $topic['lesson_ids'];
|
374 |
+
} else {
|
375 |
$lesson_ids = array();
|
376 |
}
|
377 |
+
if ( count( $lesson_ids ) ) {
|
378 |
+
foreach ( $lesson_ids as $lesson_key => $lesson_id ) {
|
379 |
$wpdb->update(
|
380 |
$wpdb->posts,
|
381 |
+
array(
|
382 |
+
'post_parent' => $topic['topic_id'],
|
383 |
+
'menu_order' => $lesson_key,
|
384 |
+
),
|
385 |
+
array( 'ID' => $lesson_id )
|
386 |
);
|
387 |
}
|
388 |
}
|
389 |
}
|
390 |
}
|
391 |
}
|
392 |
+
|
393 |
+
if ( $additional_data_edit ) {
|
394 |
+
if ( ! empty( $_POST['video']['source'] ) ) { // Video
|
395 |
+
$video = tutor_utils()->array_get( 'video', tutor_sanitize_data($_POST) );
|
396 |
+
update_post_meta( $post_ID, '_video', $video );
|
397 |
+
} else {
|
398 |
+
delete_post_meta( $post_ID, '_video' );
|
399 |
}
|
400 |
}
|
401 |
|
404 |
*/
|
405 |
|
406 |
$author_id = $post->post_author;
|
407 |
+
$attached = (int) $wpdb->get_var(
|
408 |
+
$wpdb->prepare(
|
409 |
+
"SELECT COUNT(umeta_id) FROM {$wpdb->usermeta}
|
410 |
+
WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ",
|
411 |
+
$author_id,
|
412 |
+
$post_ID
|
413 |
+
)
|
414 |
+
);
|
415 |
|
416 |
+
if ( ! $attached ) {
|
417 |
+
add_user_meta( $author_id, '_tutor_instructor_course_id', $post_ID );
|
418 |
}
|
419 |
|
420 |
/**
|
421 |
* Disable question and answer for this course
|
422 |
+
*
|
423 |
* @since 1.7.0
|
424 |
*/
|
425 |
+
if ( $additional_data_edit ) {
|
426 |
+
foreach ( $this->additional_meta as $key ) {
|
427 |
+
update_post_meta( $post_ID, $key, ( isset( $_POST[ $key ] ) ? 'yes' : 'no' ) );
|
428 |
}
|
429 |
}
|
430 |
|
431 |
+
do_action( 'tutor_save_course_after', $post_ID, $post );
|
432 |
}
|
433 |
|
434 |
/**
|
435 |
* Tutor add course topic
|
436 |
*/
|
437 |
+
public function tutor_add_course_topic() {
|
438 |
tutils()->checking_nonce();
|
439 |
|
440 |
+
if ( empty( $_POST['topic_title'] ) ) {
|
441 |
wp_send_json_error();
|
442 |
}
|
443 |
+
$course_id = (int) tutor_utils()->avalue_dot( 'tutor_topic_course_ID', tutor_sanitize_data($_POST) );
|
444 |
+
$next_topic_order_id = tutor_utils()->get_next_topic_order_id( $course_id );
|
445 |
+
|
446 |
+
if ( ! tutils()->can_user_manage( 'course', $course_id ) ) {
|
447 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
448 |
}
|
449 |
|
450 |
$topic_title = sanitize_text_field( $_POST['topic_title'] );
|
451 |
$topic_summery = wp_kses_post( $_POST['topic_summery'] );
|
452 |
|
453 |
+
$post_arr = array(
|
454 |
'post_type' => 'topics',
|
455 |
'post_title' => $topic_title,
|
456 |
'post_content' => $topic_summery,
|
457 |
'post_status' => 'publish',
|
458 |
'post_author' => get_current_user_id(),
|
459 |
'post_parent' => $course_id,
|
460 |
+
'menu_order' => $next_topic_order_id,
|
461 |
);
|
462 |
$current_topic_id = wp_insert_post( $post_arr );
|
463 |
|
464 |
ob_start();
|
465 |
+
include tutor()->path . 'views/metabox/course-contents.php';
|
466 |
$course_contents = ob_get_clean();
|
467 |
|
468 |
+
wp_send_json_success( array( 'course_contents' => $course_contents ) );
|
469 |
}
|
470 |
|
471 |
/**
|
472 |
* Update the topic
|
473 |
*/
|
474 |
+
public function tutor_update_topic() {
|
475 |
tutils()->checking_nonce();
|
476 |
|
477 |
+
$topic_id = (int) sanitize_text_field( $_POST['topic_id'] );
|
478 |
+
$topic_title = sanitize_text_field( $_POST['topic_title'] );
|
479 |
+
$topic_summery = wp_kses_post( $_POST['topic_summery'] );
|
480 |
|
481 |
+
if ( ! tutils()->can_user_manage( 'topic', $topic_id ) ) {
|
482 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
483 |
}
|
484 |
|
485 |
$topic_attr = array(
|
489 |
);
|
490 |
wp_update_post( $topic_attr );
|
491 |
|
492 |
+
wp_send_json_success( array( 'msg' => __( 'Topic has been updated', 'tutor' ) ) );
|
493 |
}
|
494 |
|
495 |
|
500 |
*
|
501 |
* Add Lesson column
|
502 |
*/
|
503 |
+
public function add_column( $columns ) {
|
504 |
$date_col = $columns['date'];
|
505 |
+
unset( $columns['date'] );
|
506 |
+
$columns['lessons'] = __( 'Lessons', 'tutor' );
|
507 |
+
$columns['students'] = __( 'Students', 'tutor' );
|
508 |
+
$columns['price'] = __( 'Price', 'tutor' );
|
509 |
+
$columns['date'] = $date_col;
|
510 |
|
511 |
return $columns;
|
512 |
}
|
514 |
/**
|
515 |
* @param $column
|
516 |
* @param $post_id
|
|
|
517 |
*/
|
518 |
+
public function custom_lesson_column( $column, $post_id ) {
|
519 |
+
if ( $column === 'lessons' ) {
|
520 |
+
echo tutor_utils()->get_lesson_count_by_course( $post_id );
|
521 |
}
|
522 |
|
523 |
+
if ( $column === 'students' ) {
|
524 |
+
echo tutor_utils()->count_enrolled_users_by_course( $post_id );
|
525 |
}
|
526 |
|
527 |
+
if ( $column === 'price' ) {
|
528 |
+
$price = tutor_utils()->get_course_price( $post_id );
|
529 |
+
if ( $price ) {
|
530 |
+
$monetize_by = tutils()->get_option( 'monetize_by' );
|
531 |
+
if ( function_exists( 'wc_price' ) && $monetize_by === 'wc' ) {
|
532 |
+
echo '<span class="tutor-label-success">' . wc_price( $price ) . '</span>';
|
533 |
+
} else {
|
534 |
+
echo '<span class="tutor-label-success">' . $price . '</span>';
|
535 |
}
|
536 |
+
} else {
|
537 |
+
echo apply_filters( 'tutor-loop-default-price', __( 'free', 'tutor' ) );
|
538 |
}
|
539 |
}
|
540 |
}
|
541 |
|
542 |
|
543 |
+
public function tutor_delete_topic() {
|
544 |
|
545 |
+
tutils()->checking_nonce( 'get' );
|
546 |
+
|
547 |
+
! isset( $_GET['topic_id'] ) ? exit() : 0;
|
548 |
|
549 |
global $wpdb;
|
550 |
|
551 |
+
$topic_id = (int) sanitize_text_field( $_GET['topic_id'] );
|
552 |
$wpdb->update(
|
553 |
$wpdb->posts,
|
554 |
+
array( 'post_parent' => 0 ),
|
555 |
+
array( 'post_parent' => $topic_id )
|
556 |
);
|
557 |
|
558 |
$wpdb->delete(
|
559 |
$wpdb->postmeta,
|
560 |
+
array( 'post_id' => $topic_id )
|
561 |
);
|
562 |
|
563 |
+
wp_delete_post( $topic_id );
|
564 |
+
wp_safe_redirect( wp_get_referer() );
|
565 |
}
|
566 |
|
567 |
+
public function tutor_delete_announcement() {
|
568 |
+
tutor_utils()->checking_nonce( 'get' );
|
569 |
|
570 |
+
$announcement_id = (int) sanitize_text_field( $_GET['topic_id'] );
|
571 |
|
572 |
+
wp_delete_post( $announcement_id );
|
573 |
+
wp_safe_redirect( wp_get_referer() );
|
574 |
}
|
575 |
|
576 |
+
public function enroll_now() {
|
577 |
|
578 |
+
// Checking if action comes from Enroll form
|
579 |
+
if ( tutor_utils()->array_get( 'tutor_course_action', tutor_sanitize_data($_POST) ) !== '_tutor_course_enroll_now' || ! isset( $_POST['tutor_course_id'] ) ) {
|
580 |
return;
|
581 |
}
|
582 |
+
// Checking Nonce
|
583 |
tutor_utils()->checking_nonce();
|
584 |
|
585 |
$user_id = get_current_user_id();
|
586 |
+
if ( ! $user_id ) {
|
587 |
+
exit( __( 'Please Sign In first', 'tutor' ) );
|
588 |
}
|
589 |
|
590 |
+
$course_id = (int) sanitize_text_field( $_POST['tutor_course_id'] );
|
591 |
+
$user_id = get_current_user_id();
|
592 |
|
593 |
/**
|
594 |
* TODO: need to check purchase information
|
595 |
*/
|
596 |
|
597 |
+
$is_purchasable = tutor_utils()->is_course_purchasable( $course_id );
|
598 |
|
599 |
/**
|
600 |
* If is is not purchasable, it's free, and enroll right now
|
603 |
*
|
604 |
* @since: v.1.0.0
|
605 |
*/
|
606 |
+
if ( $is_purchasable ) {
|
607 |
+
// process purchase
|
608 |
|
609 |
+
} else {
|
610 |
+
// Free enroll
|
611 |
+
tutor_utils()->do_enroll( $course_id );
|
612 |
}
|
613 |
|
614 |
$referer_url = wp_get_referer();
|
615 |
+
wp_redirect( $referer_url );
|
616 |
}
|
617 |
|
618 |
/**
|
621 |
*
|
622 |
* @since v.1.0.0
|
623 |
*/
|
624 |
+
public function mark_course_complete() {
|
625 |
+
if ( ! isset( $_POST['tutor_action'] ) || $_POST['tutor_action'] !== 'tutor_complete_course' ) {
|
626 |
return;
|
627 |
}
|
628 |
+
// Checking nonce
|
629 |
tutor_utils()->checking_nonce();
|
630 |
|
631 |
$user_id = get_current_user_id();
|
632 |
|
633 |
+
// TODO: need to show view if not signed_in
|
634 |
+
if ( ! $user_id ) {
|
635 |
+
die( __( 'Please Sign-In', 'tutor' ) );
|
636 |
}
|
637 |
|
638 |
+
$course_id = (int) sanitize_text_field( $_POST['course_id'] );
|
639 |
|
640 |
+
do_action( 'tutor_course_complete_before', $course_id );
|
641 |
/**
|
642 |
* Marking course completed at Comment
|
643 |
*/
|
644 |
|
645 |
global $wpdb;
|
646 |
|
647 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
648 |
|
649 |
+
// Making sure that, hash is unique
|
650 |
+
do {
|
651 |
+
$hash = substr( md5( wp_generate_password( 32 ) . $date . $course_id . $user_id ), 0, 16 );
|
652 |
+
$hasHash = (int) $wpdb->get_var(
|
653 |
+
$wpdb->prepare(
|
654 |
+
"SELECT COUNT(comment_ID) from {$wpdb->comments}
|
655 |
+
WHERE comment_agent = 'TutorLMSPlugin' AND comment_type = 'course_completed' AND comment_content = %s ",
|
656 |
+
$hash
|
657 |
+
)
|
658 |
+
);
|
659 |
|
660 |
+
} while ( $hasHash > 0 );
|
661 |
|
662 |
$data = array(
|
663 |
+
'comment_post_ID' => $course_id,
|
664 |
+
'comment_author' => $user_id,
|
665 |
+
'comment_date' => $date,
|
666 |
+
'comment_date_gmt' => get_gmt_from_date( $date ),
|
667 |
+
'comment_content' => $hash, // Identification Hash
|
668 |
+
'comment_approved' => 'approved',
|
669 |
+
'comment_agent' => 'TutorLMSPlugin',
|
670 |
+
'comment_type' => 'course_completed',
|
671 |
+
'user_id' => $user_id,
|
672 |
);
|
673 |
|
674 |
+
$wpdb->insert( $wpdb->comments, $data );
|
675 |
|
676 |
+
do_action( 'tutor_course_complete_after', $course_id, $user_id );
|
677 |
|
678 |
+
$permalink = get_the_permalink( $course_id );
|
679 |
|
680 |
// Set temporary identifier to show review pop up
|
681 |
+
if ( ! get_tutor_option( 'disable_course_review' ) ) {
|
682 |
+
$rating = tutor_utils()->get_course_rating_by_user( $course_id, $user_id );
|
683 |
+
if ( ! $rating || ( empty( $rating->rating ) && empty( $rating->review ) ) ) {
|
684 |
+
update_option(
|
685 |
+
'tutor_course_complete_popup_' . $user_id,
|
686 |
+
array(
|
687 |
+
'course_id' => $course_id,
|
688 |
+
'course_url' => $permalink,
|
689 |
+
'expires' => time() + 10,
|
690 |
+
)
|
691 |
+
);
|
692 |
}
|
693 |
}
|
694 |
+
|
695 |
+
wp_redirect( $permalink );
|
696 |
exit;
|
697 |
}
|
698 |
|
699 |
public function popup_review_form() {
|
700 |
+
if ( is_user_logged_in() ) {
|
701 |
+
$key = 'tutor_course_complete_popup_' . get_current_user_id();
|
702 |
$popup = get_option( $key );
|
703 |
|
704 |
+
if ( is_array( $popup ) ) {
|
705 |
|
706 |
+
if ( $popup['expires'] > time() ) {
|
707 |
$course_id = $popup['course_id'];
|
708 |
+
include tutor()->path . 'views/modal/review.php';
|
709 |
}
|
710 |
|
711 |
+
delete_option( $key );
|
712 |
}
|
713 |
}
|
714 |
}
|
715 |
+
|
716 |
+
public function tutor_load_instructors_modal() {
|
717 |
tutils()->checking_nonce();
|
718 |
+
|
719 |
global $wpdb;
|
720 |
|
721 |
+
$course_id = (int) sanitize_text_field( $_POST['course_id'] );
|
722 |
+
$search_terms = sanitize_text_field( tutor_utils()->avalue_dot( 'search_terms', tutor_sanitize_data($_POST) ) );
|
723 |
|
724 |
+
if ( ! tutils()->can_user_manage( 'course', $course_id ) ) {
|
725 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
726 |
}
|
|
|
|
|
|
|
727 |
|
728 |
+
$saved_instructors = tutor_utils()->get_instructors_by_course( $course_id );
|
729 |
+
$instructors = array();
|
730 |
+
|
731 |
+
$not_in_sql = apply_filters( 'tutor_instructor_query_when_exists', ' AND ID <1 ' );
|
732 |
|
733 |
+
if ( $saved_instructors ) {
|
734 |
+
$saved_instructors_ids = wp_list_pluck( $saved_instructors, 'ID' );
|
735 |
+
$instructor_not_in_ids = implode( ',', $saved_instructors_ids );
|
736 |
+
$not_in_sql .= "AND user.ID NOT IN($instructor_not_in_ids) ";
|
737 |
}
|
738 |
|
739 |
$search_sql = '';
|
740 |
+
if ( $search_terms ) {
|
741 |
$search_sql = "AND (user.user_login like '%{$search_terms}%' or user.user_nicename like '%{$search_terms}%' or user.display_name like '%{$search_terms}%') ";
|
742 |
}
|
743 |
|
744 |
+
$instructors = $wpdb->get_results(
|
745 |
+
"SELECT user.ID, user.display_name from {$wpdb->users} user
|
746 |
INNER JOIN {$wpdb->usermeta} meta ON user.ID = meta.user_id AND meta.meta_key = '_tutor_instructor_status' AND meta.meta_value = 'approved'
|
747 |
+
WHERE 1=1 {$not_in_sql} {$search_sql} limit 10 "
|
748 |
+
);
|
749 |
|
750 |
$output = '';
|
751 |
+
if ( is_array( $instructors ) && count( $instructors ) ) {
|
752 |
$instructor_output = '';
|
753 |
+
foreach ( $instructors as $instructor ) {
|
754 |
+
$instructor_output .= '<p><label><input type="radio" name="tutor_instructor_ids[]" value="' . $instructor->ID . '" > ' . $instructor->display_name . ' </label></p>';
|
755 |
}
|
756 |
|
757 |
+
$output .= apply_filters( 'tutor_course_instructors_html', $instructor_output, $instructors );
|
758 |
|
759 |
+
} else {
|
760 |
+
$output .= '<p>' . __( 'No instructor available or you have already added maximum instructors' ) . '</p>';
|
761 |
+
$output .= '<p>' . __( 'No instructor available or you have already added maximum instructors', 'tutor' ) . '</p>';
|
762 |
}
|
763 |
|
764 |
+
if ( ! defined( 'TUTOR_MT_VERSION' ) ) {
|
765 |
+
$output .= '<p class="tutor-notice-warning" style="margin-top: 50px; font-size: 14px;">' . sprintf( __( 'To add unlimited multiple instructors in your course, get %1$sTutor LMS Pro%2$s', 'tutor' ), '<a href="https://www.themeum.com/product/tutor-lms" target="_blank">', '</a>' ) . '</p>';
|
|
|
766 |
}
|
767 |
|
768 |
+
wp_send_json_success( array( 'output' => $output ) );
|
769 |
}
|
770 |
|
771 |
+
public function tutor_add_instructors_to_course() {
|
772 |
tutils()->checking_nonce();
|
773 |
|
774 |
+
$course_id = (int) sanitize_text_field( $_POST['course_id'] );
|
775 |
+
$instructor_ids = tutor_utils()->avalue_dot( 'tutor_instructor_ids', tutor_sanitize_data($_POST) );
|
776 |
+
|
777 |
+
if ( ! tutils()->can_user_manage( 'course', $course_id ) ) {
|
778 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
779 |
}
|
780 |
|
781 |
+
if ( is_array( $instructor_ids ) && count( $instructor_ids ) ) {
|
782 |
+
foreach ( $instructor_ids as $instructor_id ) {
|
783 |
+
add_user_meta( $instructor_id, '_tutor_instructor_course_id', $course_id );
|
784 |
}
|
785 |
}
|
786 |
|
787 |
+
$saved_instructors = tutor_utils()->get_instructors_by_course( $course_id );
|
788 |
+
$output = '';
|
789 |
|
790 |
+
if ( $saved_instructors ) {
|
791 |
+
foreach ( $saved_instructors as $t ) {
|
792 |
|
793 |
+
$output .= '<div id="added-instructor-id-' . $t->ID . '" class="added-instructor-item added-instructor-item-' . $t->ID . '" data-instructor-id="' . $t->ID . '">
|
794 |
+
<span class="instructor-icon">' . str_replace( "'", '"', get_avatar( $t->ID, 30 ) ) . '</span>
|
795 |
+
<span class="instructor-name"> ' . $t->display_name . ' </span>
|
796 |
<span class="instructor-control">
|
797 |
<a href="javascript:;" class="tutor-instructor-delete-btn"><i class="tutor-icon-line-cross"></i></a>
|
798 |
</span>
|
800 |
}
|
801 |
}
|
802 |
|
803 |
+
wp_send_json_success( array( 'output' => $output ) );
|
804 |
}
|
805 |
|
806 |
+
public function detach_instructor_from_course() {
|
807 |
tutils()->checking_nonce();
|
808 |
|
809 |
global $wpdb;
|
810 |
|
811 |
+
$instructor_id = (int) sanitize_text_field( $_POST['instructor_id'] );
|
812 |
+
$course_id = (int) sanitize_text_field( $_POST['course_id'] );
|
813 |
|
814 |
+
if ( ! tutils()->can_user_manage( 'course', $course_id ) ) {
|
815 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
816 |
}
|
817 |
+
|
818 |
+
$wpdb->delete(
|
819 |
+
$wpdb->usermeta,
|
820 |
+
array(
|
821 |
+
'user_id' => $instructor_id,
|
822 |
+
'meta_key' => '_tutor_instructor_course_id',
|
823 |
+
'meta_value' => $course_id,
|
824 |
+
)
|
825 |
+
);
|
826 |
wp_send_json_success();
|
827 |
}
|
828 |
|
829 |
+
public function tutor_delete_dashboard_course() {
|
830 |
tutils()->checking_nonce();
|
831 |
|
832 |
+
$course_id = intval( sanitize_text_field( $_POST['course_id'] ) );
|
833 |
|
834 |
+
if ( ! tutils()->can_user_manage( 'course', $course_id ) ) {
|
835 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
836 |
}
|
837 |
|
838 |
+
wp_trash_post( $course_id );
|
839 |
+
wp_send_json_success( array( 'element' => 'course' ) );
|
840 |
}
|
841 |
|
842 |
|
843 |
+
public function tutor_add_gutenberg_author( $data, $postarr ) {
|
844 |
global $wpdb;
|
845 |
|
846 |
$courses_post_type = tutor()->course_post_type;
|
847 |
+
$post_type = tutils()->array_get( 'post_type', $postarr );
|
848 |
|
849 |
+
if ( $courses_post_type === $post_type ) {
|
850 |
+
$post_ID = (int) tutor_utils()->avalue_dot( 'ID', $postarr );
|
851 |
+
$post_author = (int) $wpdb->get_var( $wpdb->prepare( "SELECT post_author FROM {$wpdb->posts} WHERE ID = %d ", $post_ID ) );
|
852 |
|
853 |
+
if ( $post_author > 0 ) {
|
854 |
+
$data['post_author'] = $post_author;
|
855 |
+
} else {
|
856 |
+
$data['post_author'] = get_current_user_id();
|
857 |
+
}
|
858 |
+
}
|
859 |
|
860 |
return $data;
|
861 |
}
|
866 |
* @param $postData
|
867 |
*
|
868 |
* Attach product during save course from the frontend course dashboard.
|
869 |
+
*
|
870 |
* @return string
|
871 |
*
|
872 |
* @since v.1.3.4
|
873 |
*/
|
874 |
+
public function attach_product_with_course( $post_ID, $postData ) {
|
875 |
+
$attached_product_id = tutor_utils()->get_course_product_id( $post_ID );
|
876 |
+
$course_price = sanitize_text_field( tutor_utils()->array_get( 'course_price', $_POST ) );
|
877 |
|
878 |
+
if ( ! $course_price ) {
|
879 |
return;
|
880 |
}
|
881 |
|
882 |
+
$monetize_by = tutor_utils()->get_option( 'monetize_by' );
|
883 |
+
$course = get_post( $post_ID );
|
884 |
|
885 |
+
if ( $monetize_by === 'wc' ) {
|
886 |
|
887 |
$is_update = false;
|
888 |
+
if ( $attached_product_id ) {
|
889 |
+
$wc_product = get_post_meta( $attached_product_id, '_product_version', true );
|
890 |
+
if ( $wc_product ) {
|
891 |
$is_update = true;
|
892 |
}
|
893 |
}
|
894 |
|
895 |
+
if ( $is_update ) {
|
896 |
+
$productObj = wc_get_product( $attached_product_id );
|
897 |
+
$productObj->set_price( $course_price ); // set product price
|
898 |
+
$productObj->set_regular_price( $course_price ); // set product regular price
|
899 |
+
$productObj->set_sold_individually( true );
|
900 |
$product_id = $productObj->save();
|
901 |
+
if ( $productObj->is_type( 'subscription' ) ) {
|
902 |
update_post_meta( $attached_product_id, '_subscription_price', $course_price );
|
903 |
}
|
904 |
} else {
|
905 |
$productObj = new \WC_Product();
|
906 |
+
$productObj->set_name( $course->post_title );
|
907 |
+
$productObj->set_status( 'publish' );
|
908 |
+
$productObj->set_price( $course_price ); // set product price
|
909 |
+
$productObj->set_regular_price( $course_price ); // set product regular price
|
910 |
+
$productObj->set_sold_individually( true );
|
911 |
|
912 |
$product_id = $productObj->save();
|
913 |
+
if ( $product_id ) {
|
914 |
update_post_meta( $post_ID, '_tutor_course_product_id', $product_id );
|
915 |
+
// Mark product for woocommerce
|
916 |
update_post_meta( $product_id, '_virtual', 'yes' );
|
917 |
update_post_meta( $product_id, '_tutor_product', 'yes' );
|
918 |
|
922 |
}
|
923 |
}
|
924 |
}
|
925 |
+
} elseif ( $monetize_by === 'edd' ) {
|
|
|
926 |
|
927 |
$is_update = false;
|
928 |
+
|
929 |
+
if ( $attached_product_id ) {
|
930 |
+
$edd_price = get_post_meta( $attached_product_id, 'edd_price', true );
|
931 |
+
if ( $edd_price ) {
|
932 |
$is_update = true;
|
933 |
}
|
934 |
}
|
935 |
|
936 |
+
if ( $is_update ) {
|
937 |
+
// Update the product
|
938 |
update_post_meta( $attached_product_id, 'edd_price', $course_price );
|
939 |
+
} else {
|
940 |
+
// Create new product
|
941 |
+
|
942 |
+
$post_arr = array(
|
943 |
+
'post_type' => 'download',
|
944 |
+
'post_title' => $course->post_title,
|
945 |
+
'post_status' => 'publish',
|
946 |
+
'post_author' => get_current_user_id(),
|
947 |
);
|
948 |
$download_id = wp_insert_post( $post_arr );
|
949 |
+
if ( $download_id ) {
|
950 |
+
// edd_price
|
951 |
update_post_meta( $download_id, 'edd_price', $course_price );
|
952 |
|
953 |
update_post_meta( $post_ID, '_tutor_course_product_id', $download_id );
|
954 |
+
// Mark product for EDD
|
955 |
update_post_meta( $download_id, '_tutor_product', 'yes' );
|
956 |
|
957 |
$coursePostThumbnail = get_post_meta( $post_ID, '_thumbnail_id', true );
|
958 |
if ( $coursePostThumbnail ) {
|
959 |
set_post_thumbnail( $download_id, $coursePostThumbnail );
|
960 |
}
|
|
|
961 |
}
|
|
|
962 |
}
|
|
|
|
|
963 |
}
|
964 |
|
965 |
}
|
967 |
|
968 |
/**
|
969 |
* Add Course level to course settings
|
970 |
+
*
|
971 |
* @since v.1.4.1
|
972 |
*/
|
973 |
+
public function add_course_level_to_settings() {
|
974 |
+
include tutor()->path . 'views/metabox/course-level-metabox.php';
|
975 |
}
|
976 |
|
977 |
/**
|
979 |
*
|
980 |
* @since v.1.4.8
|
981 |
*/
|
982 |
+
public function tutor_lesson_load_before() {
|
983 |
+
$course_id = tutils()->get_course_id_by_content( get_the_ID() );
|
984 |
+
$completed_lessons = tutor_utils()->get_completed_lesson_count_by_course( $course_id );
|
985 |
+
if ( is_user_logged_in() ) {
|
986 |
+
$is_course_started = get_post_meta( $course_id, '_tutor_course_started', true );
|
987 |
+
if ( ! $completed_lessons && ! $is_course_started ) {
|
988 |
+
update_post_meta( $course_id, '_tutor_course_started', tutor_time() );
|
989 |
+
do_action( 'tutor/course/started', $course_id );
|
990 |
}
|
991 |
}
|
992 |
}
|
993 |
|
994 |
/**
|
995 |
* Add Course level to course settings
|
996 |
+
*
|
997 |
* @since v.1.4.8
|
998 |
*/
|
999 |
+
public function course_elements_enable_disable() {
|
1000 |
+
add_filter( 'tutor_course/single/completing-progress-bar', array( $this, 'enable_disable_course_progress_bar' ) );
|
1001 |
+
add_filter( 'tutor_course/single/material_includes', array( $this, 'enable_disable_material_includes' ) );
|
1002 |
+
add_filter( 'tutor_course/single/content', array( $this, 'enable_disable_course_content' ) );
|
1003 |
+
add_filter( 'tutor_course/single/benefits_html', array( $this, 'enable_disable_course_benefits' ) );
|
1004 |
+
add_filter( 'tutor_course/single/requirements_html', array( $this, 'enable_disable_course_requirements' ) );
|
1005 |
+
add_filter( 'tutor_course/single/audience_html', array( $this, 'enable_disable_course_target_audience' ) );
|
1006 |
+
add_filter( 'tutor_course/single/enrolled/nav_items', array( $this, 'enable_disable_course_nav_items' ) );
|
1007 |
}
|
1008 |
|
1009 |
/**
|
1010 |
* Enable disable course progress bar
|
1011 |
+
*
|
1012 |
* @since v.1.4.8
|
1013 |
*/
|
1014 |
+
public function enable_disable_course_progress_bar( $html ) {
|
1015 |
+
$disable_option = (bool) get_tutor_option( 'disable_course_progress_bar' );
|
1016 |
+
if ( $disable_option ) {
|
1017 |
return '';
|
1018 |
}
|
1019 |
return $html;
|
1021 |
|
1022 |
/**
|
1023 |
* Enable disable material includes
|
1024 |
+
*
|
1025 |
* @since v.1.4.8
|
1026 |
*/
|
1027 |
+
public function enable_disable_material_includes( $html ) {
|
1028 |
+
$disable_option = (bool) get_tutor_option( 'disable_course_material' );
|
1029 |
+
if ( $disable_option ) {
|
1030 |
return '';
|
1031 |
}
|
1032 |
return $html;
|
1034 |
|
1035 |
/**
|
1036 |
* Enable disable course content
|
1037 |
+
*
|
1038 |
* @since v.1.4.8
|
1039 |
*/
|
1040 |
+
public function enable_disable_course_content( $html ) {
|
1041 |
+
$disable_option = (bool) get_tutor_option( 'disable_course_description' );
|
1042 |
+
if ( $disable_option ) {
|
1043 |
return '';
|
1044 |
}
|
1045 |
return $html;
|
1047 |
|
1048 |
/**
|
1049 |
* Enable disable course benefits
|
1050 |
+
*
|
1051 |
* @since v.1.4.8
|
1052 |
*/
|
1053 |
+
public function enable_disable_course_benefits( $html ) {
|
1054 |
+
$disable_option = (bool) get_tutor_option( 'disable_course_benefits' );
|
1055 |
+
if ( $disable_option ) {
|
1056 |
return '';
|
1057 |
}
|
1058 |
return $html;
|
1060 |
|
1061 |
/**
|
1062 |
* Enable disable course requirements
|
1063 |
+
*
|
1064 |
* @since v.1.4.8
|
1065 |
*/
|
1066 |
+
public function enable_disable_course_requirements( $html ) {
|
1067 |
+
$disable_option = (bool) get_tutor_option( 'disable_course_requirements' );
|
1068 |
+
if ( $disable_option ) {
|
1069 |
return '';
|
1070 |
}
|
1071 |
return $html;
|
1073 |
|
1074 |
/**
|
1075 |
* Enable disable course target audience
|
1076 |
+
*
|
1077 |
* @since v.1.4.8
|
1078 |
*/
|
1079 |
+
public function enable_disable_course_target_audience( $html ) {
|
1080 |
+
$disable_option = (bool) get_tutor_option( 'disable_course_target_audience' );
|
1081 |
+
if ( $disable_option ) {
|
1082 |
return '';
|
1083 |
}
|
1084 |
return $html;
|
1085 |
}
|
1086 |
+
|
1087 |
/**
|
1088 |
* Enable disable course nav items
|
1089 |
+
*
|
1090 |
* @since v.1.4.8
|
1091 |
*/
|
1092 |
+
public function enable_disable_course_nav_items( $items ) {
|
1093 |
global $wp_query, $post;
|
1094 |
+
$enable_q_and_a_on_course = (bool) get_tutor_option( 'enable_q_and_a_on_course' );
|
1095 |
+
$disable_course_announcements = (bool) get_tutor_option( 'disable_course_announcements' );
|
1096 |
|
1097 |
+
$disable_qa_for_this_course = ( $wp_query->is_single && ! empty( $post ) ) ? get_post_meta( $post->ID, '_tutor_disable_qa', true ) : '';
|
1098 |
|
1099 |
+
if ( ! $enable_q_and_a_on_course || $disable_qa_for_this_course == 'yes' ) {
|
1100 |
+
if ( tutils()->array_get( 'questions', $items ) ) {
|
1101 |
+
unset( $items['questions'] );
|
1102 |
}
|
1103 |
}
|
1104 |
+
if ( $disable_course_announcements ) {
|
1105 |
+
if ( tutils()->array_get( 'announcements', $items ) ) {
|
1106 |
+
unset( $items['announcements'] );
|
1107 |
}
|
1108 |
}
|
1109 |
return $items;
|
1111 |
|
1112 |
/**
|
1113 |
* Filter product in shop page
|
1114 |
+
*
|
1115 |
* @since v.1.4.9
|
1116 |
*/
|
1117 |
+
public function filter_product_in_shop_page() {
|
1118 |
+
$hide_course_from_shop_page = (bool) get_tutor_option( 'hide_course_from_shop_page' );
|
1119 |
+
if ( ! $hide_course_from_shop_page ) {
|
1120 |
return;
|
1121 |
}
|
1122 |
+
add_action( 'woocommerce_product_query', array( $this, 'filter_woocommerce_product_query' ) );
|
1123 |
+
add_filter( 'edd_downloads_query', array( $this, 'filter_edd_downloads_query' ), 10, 2 );
|
1124 |
+
add_action( 'pre_get_posts', array( $this, 'filter_archive_meta_query' ), 1 );
|
1125 |
}
|
1126 |
|
1127 |
/**
|
1128 |
* Tutor product meta query
|
1129 |
+
*
|
1130 |
* @since v.1.4.9
|
1131 |
*/
|
1132 |
+
public function tutor_product_meta_query() {
|
1133 |
$meta_query = array(
|
1134 |
+
'key' => '_tutor_product',
|
1135 |
+
'compare' => 'NOT EXISTS',
|
1136 |
);
|
1137 |
return $meta_query;
|
1138 |
}
|
1139 |
|
1140 |
/**
|
1141 |
* Filter product in woocommerce shop page
|
1142 |
+
*
|
1143 |
* @since v.1.4.9
|
1144 |
*/
|
1145 |
+
public function filter_woocommerce_product_query( $wp_query ) {
|
1146 |
+
$wp_query->set( 'meta_query', array( $this->tutor_product_meta_query() ) );
|
1147 |
return $wp_query;
|
1148 |
}
|
1149 |
|
1150 |
/**
|
1151 |
* Filter product in edd downloads shortcode page
|
1152 |
+
*
|
1153 |
* @since v.1.4.9
|
1154 |
*/
|
1155 |
+
public function filter_edd_downloads_query( $query ) {
|
1156 |
$query['meta_query'][] = $this->tutor_product_meta_query();
|
1157 |
return $query;
|
1158 |
}
|
1159 |
|
1160 |
/**
|
1161 |
* Filter product in edd downloads archive page
|
1162 |
+
*
|
1163 |
* @since v.1.4.9
|
1164 |
*/
|
1165 |
+
public function filter_archive_meta_query( $wp_query ) {
|
1166 |
+
if ( ! is_admin() && $wp_query->is_archive && $wp_query->get( 'post_type' ) === 'download' ) {
|
1167 |
+
$wp_query->set( 'meta_query', array( $this->tutor_product_meta_query() ) );
|
1168 |
}
|
1169 |
return $wp_query;
|
1170 |
}
|
1171 |
|
1172 |
+
/**
|
1173 |
+
* @param $html
|
1174 |
+
* @return string
|
1175 |
+
*
|
1176 |
+
* Removed course price if already enrolled at single course
|
1177 |
+
*
|
1178 |
+
* @since v.1.5.8
|
1179 |
+
*/
|
1180 |
+
public function remove_price_if_enrolled( $html ) {
|
1181 |
+
$should_removed = apply_filters( 'should_remove_price_if_enrolled', true );
|
1182 |
+
|
1183 |
+
if ( $should_removed ) {
|
1184 |
+
$course_id = get_the_ID();
|
1185 |
+
$enrolled = tutils()->is_enrolled( $course_id );
|
1186 |
+
if ( $enrolled ) {
|
1187 |
+
$html = '';
|
1188 |
+
}
|
1189 |
+
}
|
1190 |
+
return $html;
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
/**
|
1194 |
+
* @param $html
|
1195 |
+
* @return string
|
1196 |
+
*
|
1197 |
+
* Check if all lessons and quizzes done before mark course complete.
|
1198 |
+
*/
|
1199 |
+
function tutor_lms_hide_course_complete_btn( $html ) {
|
1200 |
+
|
1201 |
+
$completion_mode = tutils()->get_option( 'course_completion_process' );
|
1202 |
+
if ( $completion_mode !== 'strict' ) {
|
1203 |
+
return $html;
|
1204 |
+
}
|
1205 |
+
|
1206 |
+
$completed_lesson = tutils()->get_completed_lesson_count_by_course();
|
1207 |
+
$lesson_count = tutils()->get_lesson_count_by_course();
|
1208 |
+
|
1209 |
+
if ( $completed_lesson < $lesson_count ) {
|
1210 |
+
return '<p class="suggestion-before-course-complete">' . __( 'complete all lessons to mark this course as complete', 'tutor' ) . '</p>';
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
$quizzes = array();
|
1214 |
+
|
1215 |
+
$course_contents = tutils()->get_course_contents_by_id();
|
1216 |
+
if ( tutils()->count( $course_contents ) ) {
|
1217 |
+
foreach ( $course_contents as $content ) {
|
1218 |
+
if ( $content->post_type === 'tutor_quiz' ) {
|
1219 |
+
$quizzes[] = $content;
|
1220 |
+
}
|
1221 |
+
}
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
$is_pass = true;
|
1225 |
+
$required_quiz_pass = 0;
|
1226 |
+
|
1227 |
+
if ( tutils()->count( $quizzes ) ) {
|
1228 |
+
foreach ( $quizzes as $quiz ) {
|
1229 |
+
|
1230 |
+
$attempt = tutils()->get_quiz_attempt( $quiz->ID );
|
1231 |
+
if ( $attempt ) {
|
1232 |
+
$passing_grade = tutor_utils()->get_quiz_option( $quiz->ID, 'passing_grade', 0 );
|
1233 |
+
$earned_percentage = $attempt->earned_marks > 0 ? ( number_format( ( $attempt->earned_marks * 100 ) / $attempt->total_marks ) ) : 0;
|
1234 |
+
|
1235 |
+
if ( $earned_percentage < $passing_grade ) {
|
1236 |
+
$required_quiz_pass++;
|
1237 |
+
$is_pass = false;
|
1238 |
+
}
|
1239 |
+
} else {
|
1240 |
+
$required_quiz_pass++;
|
1241 |
+
$is_pass = false;
|
1242 |
+
}
|
1243 |
+
}
|
1244 |
+
}
|
1245 |
+
|
1246 |
+
if ( ! $is_pass ) {
|
1247 |
+
return '<p class="suggestion-before-course-complete">' . sprintf( __( 'You have to pass %s quizzes to complete this course.', 'tutor' ), $required_quiz_pass ) . '</p>';
|
1248 |
+
}
|
1249 |
+
|
1250 |
+
return $html;
|
1251 |
+
}
|
1252 |
+
|
1253 |
+
public function get_generate_greadbook( $html ) {
|
1254 |
+
if ( ! tutils()->is_completed_course() ) {
|
1255 |
+
return '';
|
1256 |
+
}
|
1257 |
+
return $html;
|
1258 |
}
|
1259 |
|
1260 |
/**
|
1261 |
* Add social share content in header
|
1262 |
+
*
|
1263 |
* @since v.1.6.3
|
1264 |
*/
|
1265 |
+
public function social_share_content() {
|
1266 |
global $wp_query, $post;
|
1267 |
+
if ( $wp_query->is_single && ! empty( $wp_query->query_vars['post_type'] ) && $wp_query->query_vars['post_type'] === $this->course_post_type ) { ?>
|
1268 |
<!--Facebook-->
|
1269 |
<meta property="og:type" content="website"/>
|
1270 |
+
<meta property="og:image" content="<?php echo esc_url( get_tutor_course_thumbnail_src() ); ?>" />
|
1271 |
+
<meta property="og:description" content="<?php echo esc_html( $post->post_content ); ?>" />
|
1272 |
<!--Twitter-->
|
1273 |
+
<meta name="twitter:image" content="<?php echo esc_url( get_tutor_course_thumbnail_src() ); ?>">
|
1274 |
+
<meta name="twitter:description" content="<?php echo esc_html( $post->post_content ); ?>">
|
1275 |
<!--Google+-->
|
1276 |
+
<meta itemprop="image" content="<?php echo esc_url( get_tutor_course_thumbnail_src() ); ?>">
|
1277 |
+
<meta itemprop="description" content="<?php echo esc_html( $post->post_content ); ?>">
|
1278 |
+
<?php
|
1279 |
}
|
1280 |
}
|
1281 |
|
1282 |
/**
|
1283 |
* Get posts by type and parent
|
1284 |
+
*
|
1285 |
* @since v.1.6.6
|
1286 |
*/
|
1287 |
+
public function tutor_get_post_ids( $post_type, $post_parent ) {
|
1288 |
$args = array(
|
1289 |
+
'fields' => 'ids',
|
1290 |
'post_type' => $post_type,
|
1291 |
'post_parent' => $post_parent,
|
1292 |
'post_status' => 'any',
|
1293 |
'posts_per_page' => -1,
|
1294 |
);
|
1295 |
+
return get_posts( $args );
|
1296 |
}
|
1297 |
+
|
1298 |
/**
|
1299 |
* Delete course data when permanently deleting a course.
|
1300 |
+
*
|
1301 |
* @since v.1.6.6
|
1302 |
*/
|
1303 |
function delete_tutor_course_data( $post_id ) {
|
1304 |
$course_post_type = tutor()->course_post_type;
|
1305 |
$lesson_post_type = tutor()->lesson_post_type;
|
1306 |
|
1307 |
+
if ( get_post_type( $post_id ) == $course_post_type ) {
|
1308 |
global $wpdb;
|
1309 |
+
$topic_ids = $this->tutor_get_post_ids( 'topics', $post_id );
|
1310 |
+
if ( ! empty( $topic_ids ) ) {
|
1311 |
+
foreach ( $topic_ids as $topic_id ) {
|
1312 |
+
$content_post_type = apply_filters( 'tutor_course_contents_post_types', array( $lesson_post_type, 'tutor_quiz' ) );
|
1313 |
+
$topic_content_ids = $this->tutor_get_post_ids( $content_post_type, $topic_id );
|
1314 |
+
|
1315 |
+
foreach ( $topic_content_ids as $content_id ) {
|
1316 |
+
if ( get_post_type( $content_id ) == 'tutor_quiz' ) {
|
1317 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_attempts', array( 'quiz_id' => $content_id ) );
|
1318 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_attempt_answers', array( 'quiz_id' => $content_id ) );
|
1319 |
+
|
1320 |
+
$questions_ids = $wpdb->get_col( $wpdb->prepare( "SELECT question_id FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = %d ", $content_id ) );
|
1321 |
+
if ( is_array( $questions_ids ) && count( $questions_ids ) ) {
|
1322 |
+
$in_question_ids = "'" . implode( "','", $questions_ids ) . "'";
|
1323 |
+
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id IN({$in_question_ids}) " );
|
1324 |
}
|
1325 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_questions', array( 'quiz_id' => $content_id ) );
|
1326 |
}
|
1327 |
+
wp_delete_post( $content_id, true );
|
1328 |
}
|
1329 |
+
wp_delete_post( $topic_id, true );
|
1330 |
}
|
1331 |
}
|
1332 |
+
$child_post_ids = $this->tutor_get_post_ids( array( 'tutor_announcements', 'tutor_enrolled' ), $post_id );
|
1333 |
+
if ( ! empty( $child_post_ids ) ) {
|
1334 |
+
foreach ( $child_post_ids as $child_post_id ) {
|
1335 |
+
wp_delete_post( $child_post_id, true );
|
1336 |
}
|
1337 |
}
|
1338 |
}
|
1340 |
|
1341 |
/**
|
1342 |
* tutor course setting metabox
|
1343 |
+
*
|
1344 |
* @since v.1.7.0
|
1345 |
*/
|
1346 |
function tutor_course_setting_metabox( $post ) {
|
1347 |
+
|
1348 |
$disable_qa = $this->additional_meta[0];
|
1349 |
+
$is_public = $this->additional_meta[1];
|
1350 |
|
1351 |
+
$disable_qa_checked = get_post_meta( $post->ID, $disable_qa, true ) == 'yes' ? 'checked="checked"' : '';
|
1352 |
+
$is_public_checked = get_post_meta( $post->ID, $is_public, true ) == 'yes' ? 'checked="checked"' : '';
|
1353 |
|
1354 |
+
do_action( 'tutor_before_course_sidebar_settings_metabox', $post );
|
1355 |
?>
|
1356 |
<div class="tutor-course-sidebar-settings-item" id="_tutor_is_course_public_meta_checkbox" style="display:none">
|
1357 |
+
<label for="<?php echo esc_attr( $is_public ); ?>">
|
1358 |
+
<input id="<?php echo esc_attr( $is_public ); ?>" type="checkbox" name="<?php echo esc_attr( $is_public ); ?>" value="yes" <?php echo $is_public_checked; ?> />
|
1359 |
+
<?php _e( 'Make This Course Public', 'tutor' ); ?>
|
1360 |
<small style="display:block;padding-left:24px">
|
1361 |
+
<?php _e( 'No enrollment required.', 'tutor' ); ?>
|
1362 |
</small>
|
1363 |
</label>
|
1364 |
</div>
|
1365 |
<div class="tutor-course-sidebar-settings-item">
|
1366 |
+
<label for="<?php echo esc_attr( $disable_qa ); ?>">
|
1367 |
<input type="hidden" name="_tutor_course_additional_data_edit" value="true" />
|
1368 |
+
<input id="<?php echo esc_attr( $disable_qa ); ?>" type="checkbox" name="<?php echo esc_attr( $disable_qa ); ?>" value="yes" <?php echo $disable_qa_checked; ?> />
|
1369 |
+
<?php _e( 'Disable Q&A', 'tutor' ); ?>
|
1370 |
</label>
|
1371 |
</div>
|
1372 |
<?php
|
1373 |
+
do_action( 'tutor_after_course_sidebar_settings_metabox', $post );
|
1374 |
}
|
1375 |
|
1376 |
+
function tutor_course_setting_metabox_frontend( $post ) {
|
1377 |
+
?>
|
1378 |
<div class="tutor-course-builder-section tutor-course-builder-info">
|
1379 |
<div class="tutor-course-builder-section-title">
|
1380 |
+
<h3><i class="tutor-icon-down"></i><span><?php esc_html_e( 'Tutor Settings', 'tutor' ); ?></span></h3>
|
1381 |
</div>
|
1382 |
<div class="tutor-course-builder-section-content">
|
1383 |
<div class="tutor-frontend-builder-item-scope">
|
1384 |
<div class="tutor-form-group">
|
1385 |
+
<?php $this->tutor_course_setting_metabox( $post ); ?>
|
1386 |
</div>
|
1387 |
</div>
|
1388 |
</div>
|
1392 |
|
1393 |
/**
|
1394 |
* Delete associated enrollment
|
1395 |
+
*
|
1396 |
* @since v.1.8.2
|
1397 |
*/
|
1398 |
+
public function delete_associated_enrollment( $post_id ) {
|
1399 |
+
global $wpdb;
|
1400 |
|
1401 |
+
$enroll_id = $wpdb->get_var(
|
1402 |
+
$wpdb->prepare(
|
1403 |
+
"SELECT
|
1404 |
+
post_id
|
1405 |
+
FROM
|
1406 |
{$wpdb->postmeta}
|
1407 |
+
WHERE
|
1408 |
+
meta_key='_tutor_enrolled_by_order_id'
|
1409 |
AND meta_value = %d
|
1410 |
+
",
|
1411 |
+
$post_id
|
1412 |
+
)
|
1413 |
+
);
|
1414 |
+
|
1415 |
+
if ( is_numeric( $enroll_id ) && $enroll_id > 0 ) {
|
1416 |
|
1417 |
+
$course_id = get_post_field( 'post_parent', $enroll_id );
|
1418 |
+
$user_id = get_post_field( 'post_author', $enroll_id );
|
1419 |
|
1420 |
+
tutils()->cancel_course_enrol( $course_id, $user_id );
|
1421 |
+
}
|
1422 |
+
}
|
1423 |
|
1424 |
public function tutor_reset_course_progress() {
|
1425 |
tutils()->checking_nonce();
|
1426 |
+
$course_id = tutor_utils()->array_get( 'course_id', tutor_sanitize_data($_POST) );
|
1427 |
|
1428 |
+
if ( ! $course_id || ! is_numeric( $course_id ) || ! tutor_utils()->is_enrolled( $course_id ) ) {
|
1429 |
+
wp_send_json_error( array( 'message' => __( 'Invalid Course ID or Access Denied.', 'tutor' ) ) );
|
1430 |
return;
|
1431 |
}
|
1432 |
|
1433 |
+
tutor_utils()->delete_course_progress( $course_id );
|
1434 |
+
wp_send_json_success( array( 'redirect_to' => tutor_utils()->get_course_first_lesson( $course_id ) ) );
|
1435 |
}
|
1436 |
|
1437 |
/**
|
1438 |
* Do enroll if guest attempt to enroll and course is free
|
1439 |
+
*
|
1440 |
* @param $course_id
|
1441 |
+
*
|
1442 |
* @since 1.9.8
|
1443 |
*/
|
1444 |
public function enroll_after_login_if_attempt( $course_id ) {
|
1445 |
$course_id = sanitize_text_field( $course_id );
|
1446 |
if ( $course_id ) {
|
1447 |
+
$is_purchasable = tutor_utils()->is_course_purchasable( $course_id );
|
1448 |
+
if ( ! $is_purchasable ) {
|
1449 |
+
tutor_utils()->do_enroll( $course_id );
|
1450 |
do_action( 'guest_attempt_after_enrollment', $course_id );
|
1451 |
}
|
1452 |
}
|
1453 |
}
|
1454 |
+
}
|
classes/Course_Filter.php
CHANGED
@@ -1,158 +1,167 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
class Course_Filter{
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
|
17 |
-
|
18 |
tutils()->checking_nonce();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
'compare' => 'IN'
|
72 |
-
);
|
73 |
-
}
|
74 |
-
}
|
75 |
-
count($level_price) ? $args['meta_query'] = $level_price : 0;
|
76 |
-
|
77 |
-
$search_key = sanitize_text_field(tutils()->array_get('keyword', $_POST, null));
|
78 |
-
$search_key ? $args['s'] = $search_key : 0;
|
79 |
-
|
80 |
-
if(isset($_POST['tutor_course_filter'])){
|
81 |
-
switch ($_POST['tutor_course_filter']){
|
82 |
-
case 'newest_first':
|
83 |
-
$args['orderby']='ID';
|
84 |
-
$args['order']='desc';
|
85 |
-
break;
|
86 |
-
case 'oldest_first':
|
87 |
-
$args['orderby']='ID';
|
88 |
-
$args['order']='asc';
|
89 |
-
break;
|
90 |
-
case 'course_title_az':
|
91 |
-
$args['orderby']='post_title';
|
92 |
-
$args['order']='asc';
|
93 |
-
break;
|
94 |
-
case 'course_title_za':
|
95 |
-
$args['orderby']='post_title';
|
96 |
-
$args['order']='desc';
|
97 |
-
break;
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
query_posts( apply_filters( 'tutor_course_filter_args', $args ) );
|
102 |
-
$col_per_row = (int)sanitize_text_field(tutils()->array_get('column_per_row', $_POST, 3));
|
103 |
-
$GLOBALS['tutor_shortcode_arg']=array(
|
104 |
-
'column_per_row' => $col_per_row<=0 ? 3 : $col_per_row,
|
105 |
-
'course_per_page' => $courses_per_page
|
106 |
);
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
}
|
111 |
-
|
112 |
-
private function get_current_term_id(){
|
113 |
-
|
114 |
-
if($this->current_term_id===null){
|
115 |
-
$queried = get_queried_object();
|
116 |
-
$this->current_term_id = (is_object($queried) && property_exists($queried, 'term_id')) ? $queried->term_id : false;
|
117 |
-
}
|
118 |
-
|
119 |
-
return $this->current_term_id;
|
120 |
-
}
|
121 |
-
|
122 |
-
private function sort_terms_hierarchically($terms, $parent_id=0)
|
123 |
-
{
|
124 |
-
$term_array = array();
|
125 |
-
|
126 |
-
foreach($terms as $term) {
|
127 |
-
if($term->parent==$parent_id) {
|
128 |
-
$term->children = $this->sort_terms_hierarchically($terms, $term->term_id);
|
129 |
-
$term_array[] = $term;
|
130 |
-
}
|
131 |
-
}
|
132 |
-
|
133 |
-
return $term_array;
|
134 |
-
}
|
135 |
-
|
136 |
-
private function render_terms_hierarchically($terms, $taxonomy) {
|
137 |
-
|
138 |
-
$term_id = $this->get_current_term_id();
|
139 |
-
|
140 |
-
foreach($terms as $term){
|
141 |
-
?>
|
142 |
-
<div class="tutor-course-filter-nested-terms">
|
143 |
-
<label>
|
144 |
-
<input type="checkbox" name="tutor-course-filter-<?php echo $taxonomy; ?>" value="<?php echo $term->term_id; ?>" <?php echo $term->term_id==$term_id ? 'checked="checked"' : ''; ?>/>
|
145 |
-
<?php echo $term->name; ?>
|
146 |
-
</label>
|
147 |
-
|
148 |
-
<?php isset($term->children) ? $this->render_terms_hierarchically($term->children, $taxonomy) : 0; ?>
|
149 |
-
</div>
|
150 |
-
<?php
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
public function render_terms($taxonomy){
|
155 |
-
$terms = get_terms( array('taxonomy' => $this->$taxonomy, 'hide_empty' => true));
|
156 |
-
$this->render_terms_hierarchically( $this->sort_terms_hierarchically( $terms ), $taxonomy );
|
157 |
-
}
|
158 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
class Course_Filter {
|
9 |
+
private $category = 'course-category';
|
10 |
+
private $tag = 'course-tag';
|
11 |
+
private $current_term_id = null;
|
12 |
|
13 |
+
function __construct() {
|
14 |
+
add_action( 'wp_ajax_tutor_course_filter_ajax', array( $this, 'load_listing' ) );
|
15 |
+
add_action( 'wp_ajax_nopriv_tutor_course_filter_ajax', array( $this, 'load_listing' ) );
|
16 |
+
}
|
17 |
|
18 |
+
public function load_listing() {
|
19 |
tutils()->checking_nonce();
|
20 |
+
$_post = tutor_sanitize_data( $_POST );
|
21 |
+
|
22 |
+
$default_per_page = tutils()->get_option( 'courses_per_page', 12 );
|
23 |
+
$courses_per_page = (int) sanitize_text_field( tutils()->array_get( 'course_per_page', $_post, $default_per_page ) );
|
24 |
+
$page = ( isset( $_post['page'] ) && is_numeric( $_post['page'] ) && $_post['page'] > 0 ) ? sanitize_text_field( $_post['page'] ) : 1;
|
25 |
+
|
26 |
+
$args = array(
|
27 |
+
'post_status' => 'publish',
|
28 |
+
'post_type' => 'courses',
|
29 |
+
'posts_per_page' => $courses_per_page,
|
30 |
+
'paged' => $page,
|
31 |
+
'tax_query' => array(
|
32 |
+
'relation' => 'OR',
|
33 |
+
),
|
34 |
+
);
|
35 |
+
|
36 |
+
// Prepare taxonomy
|
37 |
+
foreach ( array( 'category', 'tag' ) as $taxonomy ) {
|
38 |
+
|
39 |
+
$term_array = tutils()->array_get( 'tutor-course-filter-' . $taxonomy, $_post, array() );
|
40 |
+
! is_array( $term_array ) ? $term_array = array( $term_array ) : 0;
|
41 |
+
|
42 |
+
$term_array = array_filter(
|
43 |
+
$term_array,
|
44 |
+
function( $term_id ) {
|
45 |
+
return is_numeric( $term_id );
|
46 |
+
}
|
47 |
+
);
|
48 |
+
|
49 |
+
if ( count( $term_array ) > 0 ) {
|
50 |
+
$tax_query = array(
|
51 |
+
'taxonomy' => $this->$taxonomy,
|
52 |
+
'field' => 'term_id',
|
53 |
+
'terms' => $term_array,
|
54 |
+
'operator' => 'IN',
|
55 |
+
);
|
56 |
+
array_push( $args['tax_query'], $tax_query );
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
// Prepare level and price type
|
61 |
+
$is_membership = get_tutor_option( 'monetize_by' ) == 'pmpro' && tutils()->has_pmpro();
|
62 |
+
$level_price = array();
|
63 |
+
foreach ( array( 'level', 'price' ) as $type ) {
|
64 |
+
|
65 |
+
if ( $is_membership && 'price' === $type ) {
|
66 |
+
continue;
|
67 |
+
}
|
68 |
+
|
69 |
+
$type_array = tutils()->array_get( 'tutor-course-filter-' . $type, $_post, array() );
|
70 |
+
$type_array = array_map( 'sanitize_text_field', ( is_array( $type_array ) ? $type_array : array( $type_array ) ) );
|
71 |
+
|
72 |
+
if ( count( $type_array ) > 0 ) {
|
73 |
+
$level_price[] = array(
|
74 |
+
'key' => 'level' === $type ? '_tutor_course_level' : '_tutor_course_price_type',
|
75 |
+
'value' => $type_array,
|
76 |
+
'compare' => 'IN',
|
77 |
+
);
|
78 |
+
}
|
79 |
+
}
|
80 |
+
count( $level_price ) ? $args['meta_query'] = $level_price : 0;
|
81 |
+
|
82 |
+
$search_key = sanitize_text_field( tutils()->array_get( 'keyword', $_post, null ) );
|
83 |
+
$search_key ? $args['s'] = $search_key : 0;
|
84 |
+
|
85 |
+
if ( isset( $_post['tutor_course_filter'] ) ) {
|
86 |
+
switch ( $_post['tutor_course_filter'] ) {
|
87 |
+
case 'newest_first':
|
88 |
+
$args['orderby'] = 'ID';
|
89 |
+
$args['order'] = 'desc';
|
90 |
+
break;
|
91 |
+
case 'oldest_first':
|
92 |
+
$args['orderby'] = 'ID';
|
93 |
+
$args['order'] = 'asc';
|
94 |
+
break;
|
95 |
+
case 'course_title_az':
|
96 |
+
$args['orderby'] = 'post_title';
|
97 |
+
$args['order'] = 'asc';
|
98 |
+
break;
|
99 |
+
case 'course_title_za':
|
100 |
+
$args['orderby'] = 'post_title';
|
101 |
+
$args['order'] = 'desc';
|
102 |
+
break;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
query_posts( apply_filters( 'tutor_course_filter_args', $args ) );
|
107 |
+
$col_per_row = (int) sanitize_text_field( tutils()->array_get( 'column_per_row', $_post, 3 ) );
|
108 |
+
$GLOBALS['tutor_shortcode_arg'] = array(
|
109 |
+
'column_per_row' => $col_per_row <= 0 ? 3 : $col_per_row,
|
110 |
+
'course_per_page' => $courses_per_page,
|
111 |
+
);
|
112 |
|
113 |
+
tutor_load_template( 'archive-course-init' );
|
114 |
+
exit;
|
115 |
+
}
|
116 |
+
|
117 |
+
private function get_current_term_id() {
|
118 |
+
|
119 |
+
if ( $this->current_term_id === null ) {
|
120 |
+
$queried = get_queried_object();
|
121 |
+
$this->current_term_id = ( is_object( $queried ) && property_exists( $queried, 'term_id' ) ) ? $queried->term_id : false;
|
122 |
+
}
|
123 |
+
|
124 |
+
return $this->current_term_id;
|
125 |
+
}
|
126 |
+
|
127 |
+
private function sort_terms_hierarchically( $terms, $parent_id = 0 ) {
|
128 |
+
$term_array = array();
|
129 |
+
|
130 |
+
foreach ( $terms as $term ) {
|
131 |
+
if ( $term->parent == $parent_id ) {
|
132 |
+
$term->children = $this->sort_terms_hierarchically( $terms, $term->term_id );
|
133 |
+
$term_array[] = $term;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return $term_array;
|
138 |
+
}
|
139 |
+
|
140 |
+
private function render_terms_hierarchically( $terms, $taxonomy ) {
|
141 |
+
|
142 |
+
$term_id = $this->get_current_term_id();
|
143 |
+
|
144 |
+
foreach ( $terms as $term ) {
|
145 |
+
?>
|
146 |
+
<div class="tutor-course-filter-nested-terms">
|
147 |
+
<label>
|
148 |
+
<input type="checkbox" name="tutor-course-filter-<?php echo esc_attr( $taxonomy ); ?>" value="<?php echo $term->term_id; ?>" <?php echo $term->term_id == $term_id ? 'checked' : ''; ?>/>
|
149 |
+
<?php echo $term->name; ?>
|
150 |
+
</label>
|
151 |
+
|
152 |
+
<?php isset( $term->children ) ? $this->render_terms_hierarchically( $term->children, $taxonomy ) : 0; ?>
|
153 |
+
</div>
|
154 |
+
<?php
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
public function render_terms( $taxonomy ) {
|
159 |
+
$terms = get_terms(
|
160 |
+
array(
|
161 |
+
'taxonomy' => $this->$taxonomy,
|
162 |
+
'hide_empty' => true,
|
163 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
);
|
165 |
+
$this->render_terms_hierarchically( $this->sort_terms_hierarchically( $terms ), $taxonomy );
|
166 |
+
}
|
167 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Course_Settings_Tabs.php
CHANGED
@@ -1,119 +1,120 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
class Course_Settings_Tabs {
|
9 |
+
|
10 |
+
public $course_post_type = '';
|
11 |
+
public $is_gutenberg_enable = false;
|
12 |
+
public $args = array();
|
13 |
+
public $settings_meta = null;
|
14 |
+
|
15 |
+
public function __construct() {
|
16 |
+
$this->course_post_type = tutor()->course_post_type;
|
17 |
+
$isGutenberg = apply_filters( 'use_block_editor_for_post_type', true, 'courses' );
|
18 |
+
$this->is_gutenberg_enable = $isGutenberg;
|
19 |
+
|
20 |
+
if ( $isGutenberg ) {
|
21 |
+
// MetaBox
|
22 |
+
add_action( 'add_meta_boxes', array( $this, 'register_meta_box' ) );
|
23 |
+
} else {
|
24 |
+
add_action( 'edit_form_after_editor', array( $this, 'display' ), 10, 0 );
|
25 |
+
}
|
26 |
+
add_action( 'tutor/frontend_course_edit/after/description', array( $this, 'display' ), 10, 0 );
|
27 |
+
|
28 |
+
add_action( 'tutor_save_course', array( $this, 'save_course' ), 10, 2 );
|
29 |
+
}
|
30 |
+
|
31 |
+
public function register_meta_box() {
|
32 |
+
add_meta_box( 'course-settings', __( 'Course Settings', 'tutor' ), array( $this, 'display' ), $this->course_post_type, 'advanced', 'high' );
|
33 |
+
}
|
34 |
+
|
35 |
+
public function get_default_args() {
|
36 |
+
$args = array(
|
37 |
+
'general' => array(
|
38 |
+
'label' => __( 'General', 'tutor' ),
|
39 |
+
'desc' => __( 'General Settings', 'tutor' ),
|
40 |
+
'icon_class' => ' tutor-icon-settings-1',
|
41 |
+
'callback' => '',
|
42 |
+
'fields' => array(
|
43 |
+
'maximum_students' => array(
|
44 |
+
'type' => 'number',
|
45 |
+
'label' => __( 'Maximum Students', 'tutor' ),
|
46 |
+
'label_title' => __( 'Enable', 'tutor' ),
|
47 |
+
'default' => '0',
|
48 |
+
'desc' => __( 'Number of students that can enrol in this course. Set 0 for no limits.', 'tutor' ),
|
49 |
+
),
|
50 |
+
),
|
51 |
+
),
|
52 |
+
);
|
53 |
+
|
54 |
+
return apply_filters( 'tutor_course_settings_tabs', $args );
|
55 |
+
}
|
56 |
+
|
57 |
+
public function display() {
|
58 |
+
global $post;
|
59 |
+
$this->args = $this->get_default_args();
|
60 |
+
|
61 |
+
$settings_meta = get_post_meta( get_the_ID(), '_tutor_course_settings', true );
|
62 |
+
$this->settings_meta = (array) maybe_unserialize( $settings_meta );
|
63 |
+
|
64 |
+
if ( tutils()->count( $this->args ) && $post->post_type === $this->course_post_type ) {
|
65 |
+
include tutor()->path . 'views/metabox/course/settings-tabs.php';
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
public function generate_field( $fields = array() ) {
|
70 |
+
if ( tutils()->count( $fields ) ) {
|
71 |
+
foreach ( $fields as $field_key => $field ) {
|
72 |
+
$type = tutils()->array_get( 'type', $field );
|
73 |
+
?>
|
74 |
+
<div class="tutor-option-field-row tutor-field-row-<?php echo esc_attr( $type ); ?>">
|
75 |
+
<?php
|
76 |
+
if ( isset( $field['label'] ) ) {
|
77 |
+
?>
|
78 |
+
<div class="tutor-option-field-label">
|
79 |
+
<label for=""><?php echo $field['label']; ?></label>
|
80 |
+
</div>
|
81 |
+
<?php
|
82 |
+
}
|
83 |
+
?>
|
84 |
+
<div class="tutor-option-field tutor-field-<?php echo esc_attr( $type ); ?>">
|
85 |
+
<?php
|
86 |
+
$field['field_key'] = $field_key;
|
87 |
+
$this->field_type( $field );
|
88 |
+
if ( isset( $field['desc'] ) ) {
|
89 |
+
printf( "<p class='desc'>%s</p>", $field['desc'] );
|
90 |
+
}
|
91 |
+
?>
|
92 |
+
</div>
|
93 |
+
</div>
|
94 |
+
<?php
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
public function field_type( $field = array() ) {
|
100 |
+
include tutor()->path . "views/metabox/course/field-types/{$field['type']}.php";
|
101 |
+
}
|
102 |
+
|
103 |
+
public function get( $key = null, $default = false ) {
|
104 |
+
return tutils()->array_get( $key, $this->settings_meta, $default );
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @param $post_ID
|
109 |
+
* @param $post
|
110 |
+
*
|
111 |
+
* Fire when course saving...
|
112 |
+
*/
|
113 |
+
public function save_course( $post_ID, $post ) {
|
114 |
+
$_tutor_course_settings = tutils()->array_get( '_tutor_course_settings', tutor_sanitize_data($_POST) );
|
115 |
+
if ( tutils()->count( $_tutor_course_settings ) ) {
|
116 |
+
update_post_meta( $post_ID, '_tutor_course_settings', $_tutor_course_settings );
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
}
|
classes/Course_Widget.php
CHANGED
@@ -11,16 +11,17 @@
|
|
11 |
|
12 |
namespace TUTOR;
|
13 |
|
14 |
-
if ( ! defined( 'ABSPATH' ) )
|
15 |
exit;
|
|
|
16 |
|
17 |
class Course_Widget extends \WP_Widget {
|
18 |
-
|
19 |
function __construct() {
|
20 |
parent::__construct(
|
21 |
'tutor_course_widget', // Base ID
|
22 |
esc_html__( 'Tutor Course', 'tutor' ), // Name
|
23 |
-
array( 'description' => esc_html__( 'Display courses wherever widget support is available.', 'tutor' )
|
24 |
);
|
25 |
}
|
26 |
|
@@ -41,34 +42,34 @@ class Course_Widget extends \WP_Widget {
|
|
41 |
$course_post_type = tutor()->course_post_type;
|
42 |
|
43 |
$form_args = $instance;
|
44 |
-
unset($form_args['title']);
|
45 |
|
46 |
$default_args = array(
|
47 |
-
'post_type'
|
48 |
-
'post_status'
|
49 |
|
50 |
-
'id'
|
51 |
-
'exclude_ids'
|
52 |
-
'category'
|
53 |
|
54 |
-
'orderby'
|
55 |
-
'order'
|
56 |
-
'count'
|
57 |
);
|
58 |
|
59 |
-
$a = array_merge($default_args, $form_args);
|
60 |
|
61 |
-
if ( ! empty($a['id'])){
|
62 |
-
$ids
|
63 |
$a['post__in'] = $ids;
|
64 |
}
|
65 |
|
66 |
-
if ( ! empty($a['exclude_ids'])){
|
67 |
-
$exclude_ids
|
68 |
$a['post__not_in'] = $exclude_ids;
|
69 |
}
|
70 |
-
if ( ! empty($a['category'])){
|
71 |
-
$category = (array) explode(',', $a['category']);
|
72 |
|
73 |
$a['tax_query'] = array(
|
74 |
array(
|
@@ -82,13 +83,12 @@ class Course_Widget extends \WP_Widget {
|
|
82 |
$a['posts_per_page'] = (int) $a['count'];
|
83 |
|
84 |
wp_reset_query();
|
85 |
-
query_posts($a);
|
86 |
ob_start();
|
87 |
-
tutor_load_template('widget.courses');
|
88 |
$output = ob_get_clean();
|
89 |
wp_reset_query();
|
90 |
|
91 |
-
|
92 |
echo $output;
|
93 |
|
94 |
echo $args['after_widget'];
|
@@ -102,70 +102,83 @@ class Course_Widget extends \WP_Widget {
|
|
102 |
* @param array $instance Previously saved values from database.
|
103 |
*/
|
104 |
public function form( $instance ) {
|
105 |
-
$title
|
106 |
-
$id
|
107 |
$exclude_ids = ! empty( $instance['exclude_ids'] ) ? $instance['exclude_ids'] : '';
|
108 |
-
$category
|
109 |
-
$orderby
|
110 |
-
$order
|
111 |
-
$count
|
112 |
?>
|
113 |
<p>
|
114 |
-
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
|
|
|
|
|
115 |
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
|
116 |
</p>
|
117 |
|
118 |
<p>
|
119 |
-
<label for="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>"
|
|
|
|
|
120 |
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'id' ) ); ?>" type="text" value="<?php echo esc_attr( $id ); ?>"> <br />
|
121 |
-
<span style="color: #AAAAAA"
|
|
|
|
|
122 |
</p>
|
123 |
|
124 |
<p>
|
125 |
<label for="<?php echo esc_attr( $this->get_field_id( 'exclude_ids' ) ); ?>"><?php esc_attr_e( 'Exclude IDS:', 'tutor' ); ?></label>
|
126 |
-
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'exclude_ids' ) ); ?>" name="<?php echo esc_attr(
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
</p>
|
131 |
|
132 |
<p>
|
133 |
-
<label for="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>"
|
134 |
-
|
135 |
-
|
136 |
-
<
|
137 |
-
|
|
|
|
|
138 |
</p>
|
139 |
|
140 |
<p>
|
141 |
-
<label for="<?php echo esc_attr( $this->get_field_id( 'orderby' ) ); ?>"
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
<option value="
|
147 |
-
<option value="
|
148 |
-
<option value="
|
149 |
-
<option value="
|
|
|
|
|
150 |
</select> <br />
|
151 |
</p>
|
152 |
|
153 |
<p>
|
154 |
-
<label for="<?php echo esc_attr( $this->get_field_id( 'order' ) ); ?>"
|
|
|
|
|
155 |
|
156 |
-
<select class="widefat" name="<?php echo esc_attr($this->get_field_name( 'order' ) ); ?>" >
|
157 |
-
<option value="DESC" <?php selected('DESC', $order) ?> >DESC</option>
|
158 |
-
<option value="ASC" <?php selected('ASC', $order) ?> >ASC</option>
|
159 |
</select> <br />
|
160 |
</p>
|
161 |
|
162 |
<p>
|
163 |
<label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_attr_e( 'Count:', 'tutor' ); ?></label>
|
164 |
-
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr(
|
165 |
-
|
166 |
-
|
|
|
167 |
</p>
|
168 |
-
|
169 |
<?php
|
170 |
}
|
171 |
|
@@ -180,18 +193,15 @@ class Course_Widget extends \WP_Widget {
|
|
180 |
* @return array Updated safe values to be saved.
|
181 |
*/
|
182 |
public function update( $new_instance, $old_instance ) {
|
183 |
-
$instance
|
184 |
-
$instance['title']
|
185 |
-
$instance['id']
|
186 |
-
$instance['exclude_ids']
|
187 |
-
$instance['category']
|
188 |
-
$instance['orderby']
|
189 |
-
$instance['order']
|
190 |
-
$instance['count']
|
191 |
|
192 |
return $instance;
|
193 |
}
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
}
|
11 |
|
12 |
namespace TUTOR;
|
13 |
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
exit;
|
16 |
+
}
|
17 |
|
18 |
class Course_Widget extends \WP_Widget {
|
19 |
+
|
20 |
function __construct() {
|
21 |
parent::__construct(
|
22 |
'tutor_course_widget', // Base ID
|
23 |
esc_html__( 'Tutor Course', 'tutor' ), // Name
|
24 |
+
array( 'description' => esc_html__( 'Display courses wherever widget support is available.', 'tutor' ) ) // Args
|
25 |
);
|
26 |
}
|
27 |
|
42 |
$course_post_type = tutor()->course_post_type;
|
43 |
|
44 |
$form_args = $instance;
|
45 |
+
unset( $form_args['title'] );
|
46 |
|
47 |
$default_args = array(
|
48 |
+
'post_type' => $course_post_type,
|
49 |
+
'post_status' => 'publish',
|
50 |
|
51 |
+
'id' => '',
|
52 |
+
'exclude_ids' => '',
|
53 |
+
'category' => '',
|
54 |
|
55 |
+
'orderby' => 'ID',
|
56 |
+
'order' => 'DESC',
|
57 |
+
'count' => '6',
|
58 |
);
|
59 |
|
60 |
+
$a = array_merge( $default_args, $form_args );
|
61 |
|
62 |
+
if ( ! empty( $a['id'] ) ) {
|
63 |
+
$ids = (array) explode( ',', $a['id'] );
|
64 |
$a['post__in'] = $ids;
|
65 |
}
|
66 |
|
67 |
+
if ( ! empty( $a['exclude_ids'] ) ) {
|
68 |
+
$exclude_ids = (array) explode( ',', $a['exclude_ids'] );
|
69 |
$a['post__not_in'] = $exclude_ids;
|
70 |
}
|
71 |
+
if ( ! empty( $a['category'] ) ) {
|
72 |
+
$category = (array) explode( ',', $a['category'] );
|
73 |
|
74 |
$a['tax_query'] = array(
|
75 |
array(
|
83 |
$a['posts_per_page'] = (int) $a['count'];
|
84 |
|
85 |
wp_reset_query();
|
86 |
+
query_posts( $a );
|
87 |
ob_start();
|
88 |
+
tutor_load_template( 'widget.courses' );
|
89 |
$output = ob_get_clean();
|
90 |
wp_reset_query();
|
91 |
|
|
|
92 |
echo $output;
|
93 |
|
94 |
echo $args['after_widget'];
|
102 |
* @param array $instance Previously saved values from database.
|
103 |
*/
|
104 |
public function form( $instance ) {
|
105 |
+
$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'tutor' );
|
106 |
+
$id = ! empty( $instance['id'] ) ? $instance['id'] : '';
|
107 |
$exclude_ids = ! empty( $instance['exclude_ids'] ) ? $instance['exclude_ids'] : '';
|
108 |
+
$category = ! empty( $instance['category'] ) ? $instance['category'] : '';
|
109 |
+
$orderby = ! empty( $instance['orderby'] ) ? $instance['orderby'] : '';
|
110 |
+
$order = ! empty( $instance['order'] ) ? $instance['order'] : '';
|
111 |
+
$count = ! empty( $instance['count'] ) ? $instance['count'] : '6';
|
112 |
?>
|
113 |
<p>
|
114 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
|
115 |
+
<?php _e( 'Title', 'tutor' ); ?>:
|
116 |
+
</label>
|
117 |
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
|
118 |
</p>
|
119 |
|
120 |
<p>
|
121 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>">
|
122 |
+
<?php _e( 'ID', 'tutor' ); ?>:
|
123 |
+
</label>
|
124 |
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'id' ) ); ?>" type="text" value="<?php echo esc_attr( $id ); ?>"> <br />
|
125 |
+
<span style="color: #AAAAAA">
|
126 |
+
<?php _e( 'Place single course id or comma (,) separated course ids', 'tutor' ); ?>
|
127 |
+
</span>
|
128 |
</p>
|
129 |
|
130 |
<p>
|
131 |
<label for="<?php echo esc_attr( $this->get_field_id( 'exclude_ids' ) ); ?>"><?php esc_attr_e( 'Exclude IDS:', 'tutor' ); ?></label>
|
132 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'exclude_ids' ) ); ?>" name="<?php echo esc_attr($this->get_field_name( 'exclude_ids' )); ?>" type="text" value="<?php echo esc_attr( $exclude_ids ); ?>"> <br />
|
133 |
+
<span style="color: #AAAAAA">
|
134 |
+
<?php _e( 'Place comma (,) separated courses ids which you like to exclude from the query', 'tutor' ); ?>
|
135 |
+
</span>
|
136 |
</p>
|
137 |
|
138 |
<p>
|
139 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>">
|
140 |
+
<?php _e( 'Category', 'tutor' ); ?>:
|
141 |
+
</label>
|
142 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>" name="<?php echo esc_attr($this->get_field_name( 'category' )); ?>" type="text" value="<?php echo esc_attr( $category ); ?>"> <br />
|
143 |
+
<span style="color: #AAAAAA">
|
144 |
+
<?php _e( 'Place comma (,) separated category ids', 'tutor' ); ?>
|
145 |
+
</span>
|
146 |
</p>
|
147 |
|
148 |
<p>
|
149 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'orderby' ) ); ?>">
|
150 |
+
<?php _e( 'OrderBy', 'tutor' ); ?>
|
151 |
+
</label>
|
152 |
+
|
153 |
+
<select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'orderby' ) ); ?>" >
|
154 |
+
<option value="ID" <?php selected( 'ID', $orderby ); ?> >ID</option>
|
155 |
+
<option value="title" <?php selected( 'title', $orderby ); ?> >title</option>
|
156 |
+
<option value="rand" <?php selected( 'rand', $orderby ); ?> >rand</option>
|
157 |
+
<option value="date" <?php selected( 'date', $orderby ); ?> >date</option>
|
158 |
+
<option value="menu_order" <?php selected( 'menu_order', $orderby ); ?> >menu_order</option>
|
159 |
+
<option value="post__in" <?php selected( 'post__in', $orderby ); ?> >post__in</option>
|
160 |
</select> <br />
|
161 |
</p>
|
162 |
|
163 |
<p>
|
164 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'order' ) ); ?>">
|
165 |
+
<?php _e( 'Order', 'tutor' ); ?>
|
166 |
+
</label>
|
167 |
|
168 |
+
<select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'order' ) ); ?>" >
|
169 |
+
<option value="DESC" <?php selected( 'DESC', $order ); ?> >DESC</option>
|
170 |
+
<option value="ASC" <?php selected( 'ASC', $order ); ?> >ASC</option>
|
171 |
</select> <br />
|
172 |
</p>
|
173 |
|
174 |
<p>
|
175 |
<label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_attr_e( 'Count:', 'tutor' ); ?></label>
|
176 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>" type="number" value="<?php echo esc_attr( $count ); ?>"> <br />
|
177 |
+
<span style="color: #AAAAAA">
|
178 |
+
<?php _e( 'Total results you like to show', 'tutor' ); ?>
|
179 |
+
</span>
|
180 |
</p>
|
181 |
+
|
182 |
<?php
|
183 |
}
|
184 |
|
193 |
* @return array Updated safe values to be saved.
|
194 |
*/
|
195 |
public function update( $new_instance, $old_instance ) {
|
196 |
+
$instance = array();
|
197 |
+
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
|
198 |
+
$instance['id'] = ( ! empty( $new_instance['id'] ) ) ? sanitize_text_field( $new_instance['id'] ) : '';
|
199 |
+
$instance['exclude_ids'] = ( ! empty( $new_instance['exclude_ids'] ) ) ? sanitize_text_field( $new_instance['exclude_ids'] ) : '';
|
200 |
+
$instance['category'] = ( ! empty( $new_instance['category'] ) ) ? sanitize_text_field( $new_instance['category'] ) : '';
|
201 |
+
$instance['orderby'] = ( ! empty( $new_instance['orderby'] ) ) ? sanitize_text_field( $new_instance['orderby'] ) : '';
|
202 |
+
$instance['order'] = ( ! empty( $new_instance['order'] ) ) ? sanitize_text_field( $new_instance['order'] ) : '';
|
203 |
+
$instance['count'] = ( ! empty( $new_instance['count'] ) ) ? sanitize_text_field( $new_instance['count'] ) : '';
|
204 |
|
205 |
return $instance;
|
206 |
}
|
207 |
+
}
|
|
|
|
|
|
classes/Dashboard.php
CHANGED
@@ -10,42 +10,48 @@
|
|
10 |
|
11 |
namespace TUTOR;
|
12 |
|
13 |
-
if ( ! defined( 'ABSPATH' ) )
|
14 |
exit;
|
|
|
15 |
|
16 |
class Dashboard {
|
17 |
|
18 |
public function __construct() {
|
19 |
-
add_action('tutor_load_template_before', array($this, 'tutor_load_template_before'), 10, 2);
|
20 |
-
add_action('tutor_load_template_after', array($this, 'tutor_load_template_after'), 10, 2);
|
21 |
-
add_filter('should_tutor_load_template', array($this, 'should_tutor_load_template'), 10, 2);
|
22 |
|
23 |
-
add_action('tutor_dashboard/notification_area', array($this, 'profile_completion_notification'), 10, 2);
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
* @param $template
|
28 |
* @param $variables
|
29 |
*/
|
30 |
-
public function tutor_load_template_before($template, $variables){
|
31 |
global $wp_query;
|
32 |
|
33 |
-
$tutor_dashboard_page = tutor_utils()->array_get('query_vars.tutor_dashboard_page', $wp_query);
|
34 |
-
if ($tutor_dashboard_page === 'create-course') {
|
35 |
global $post;
|
36 |
wp_reset_query();
|
37 |
|
38 |
-
|
39 |
/**
|
40 |
* Get course which currently in edit, or insert new course
|
41 |
*/
|
42 |
-
$course_ID = (int) sanitize_text_field(tutor_utils()->array_get('course_ID', $_GET));
|
43 |
|
44 |
-
if ($course_ID){
|
45 |
$post_id = $course_ID;
|
46 |
-
}else{
|
47 |
$post_type = tutor()->course_post_type;
|
48 |
-
$post_id
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
$post = get_post( $post_id );
|
@@ -53,17 +59,17 @@ class Dashboard {
|
|
53 |
}
|
54 |
}
|
55 |
|
56 |
-
public function tutor_load_template_after(){
|
57 |
global $wp_query;
|
58 |
|
59 |
-
$tutor_dashboard_page = tutor_utils()->array_get('query_vars.tutor_dashboard_page', $wp_query);
|
60 |
-
if ($tutor_dashboard_page === 'create-course'){
|
61 |
wp_reset_query();
|
62 |
}
|
63 |
}
|
64 |
|
65 |
-
public function should_tutor_load_template($bool, $template){
|
66 |
-
if ($template === 'dashboard.create-course' && ! tutor()->has_pro){
|
67 |
return false;
|
68 |
}
|
69 |
return $bool;
|
@@ -72,20 +78,20 @@ class Dashboard {
|
|
72 |
|
73 |
/**
|
74 |
* Display completion notification
|
75 |
-
*
|
76 |
* @return string
|
77 |
*
|
78 |
* @since v.1.6.6
|
79 |
*/
|
80 |
public function profile_completion_notification() {
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
}
|
10 |
|
11 |
namespace TUTOR;
|
12 |
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
exit;
|
15 |
+
}
|
16 |
|
17 |
class Dashboard {
|
18 |
|
19 |
public function __construct() {
|
20 |
+
add_action( 'tutor_load_template_before', array( $this, 'tutor_load_template_before' ), 10, 2 );
|
21 |
+
add_action( 'tutor_load_template_after', array( $this, 'tutor_load_template_after' ), 10, 2 );
|
22 |
+
add_filter( 'should_tutor_load_template', array( $this, 'should_tutor_load_template' ), 10, 2 );
|
23 |
|
24 |
+
add_action( 'tutor_dashboard/notification_area', array( $this, 'profile_completion_notification' ), 10, 2 );
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
* @param $template
|
29 |
* @param $variables
|
30 |
*/
|
31 |
+
public function tutor_load_template_before( $template, $variables ) {
|
32 |
global $wp_query;
|
33 |
|
34 |
+
$tutor_dashboard_page = tutor_utils()->array_get( 'query_vars.tutor_dashboard_page', $wp_query );
|
35 |
+
if ( $tutor_dashboard_page === 'create-course' ) {
|
36 |
global $post;
|
37 |
wp_reset_query();
|
38 |
|
|
|
39 |
/**
|
40 |
* Get course which currently in edit, or insert new course
|
41 |
*/
|
42 |
+
$course_ID = (int) sanitize_text_field( tutor_utils()->array_get( 'course_ID', $_GET ) );
|
43 |
|
44 |
+
if ( $course_ID ) {
|
45 |
$post_id = $course_ID;
|
46 |
+
} else {
|
47 |
$post_type = tutor()->course_post_type;
|
48 |
+
$post_id = wp_insert_post(
|
49 |
+
array(
|
50 |
+
'post_title' => __( 'Auto Draft', 'tutor' ),
|
51 |
+
'post_type' => $post_type,
|
52 |
+
'post_status' => 'draft',
|
53 |
+
)
|
54 |
+
);
|
55 |
}
|
56 |
|
57 |
$post = get_post( $post_id );
|
59 |
}
|
60 |
}
|
61 |
|
62 |
+
public function tutor_load_template_after() {
|
63 |
global $wp_query;
|
64 |
|
65 |
+
$tutor_dashboard_page = tutor_utils()->array_get( 'query_vars.tutor_dashboard_page', $wp_query );
|
66 |
+
if ( $tutor_dashboard_page === 'create-course' ) {
|
67 |
wp_reset_query();
|
68 |
}
|
69 |
}
|
70 |
|
71 |
+
public function should_tutor_load_template( $bool, $template ) {
|
72 |
+
if ( $template === 'dashboard.create-course' && ! tutor()->has_pro ) {
|
73 |
return false;
|
74 |
}
|
75 |
return $bool;
|
78 |
|
79 |
/**
|
80 |
* Display completion notification
|
81 |
+
*
|
82 |
* @return string
|
83 |
*
|
84 |
* @since v.1.6.6
|
85 |
*/
|
86 |
public function profile_completion_notification() {
|
87 |
+
$output = '';
|
88 |
+
$enable_profile_completion = tutils()->get_option( 'enable_profile_completion' );
|
89 |
+
if ( $enable_profile_completion ) {
|
90 |
+
ob_start();
|
91 |
+
tutor_load_template( 'dashboard.notifications.profile-completion' );
|
92 |
+
$output = apply_filters( 'tutor_profile_completion_notification_html', ob_get_clean() );
|
93 |
+
}
|
94 |
+
|
95 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
96 |
+
}
|
97 |
+
}
|
classes/FormHandler.php
CHANGED
@@ -10,28 +10,28 @@
|
|
10 |
|
11 |
namespace TUTOR;
|
12 |
|
13 |
-
|
14 |
-
if ( ! defined( 'ABSPATH' ) )
|
15 |
exit;
|
|
|
16 |
|
17 |
|
18 |
class FormHandler {
|
19 |
|
20 |
public function __construct() {
|
21 |
-
add_action('tutor_action_tutor_retrieve_password', array($this, 'tutor_retrieve_password'));
|
22 |
-
add_action('tutor_action_tutor_process_reset_password', array($this, 'tutor_process_reset_password'));
|
23 |
|
24 |
add_action( 'tutor_reset_password_notification', array( $this, 'reset_password_notification' ), 10, 2 );
|
25 |
add_filter( 'tutor_lostpassword_url', array( $this, 'lostpassword_url' ) );
|
26 |
}
|
27 |
|
28 |
-
public function tutor_retrieve_password(){
|
29 |
tutils()->checking_nonce();
|
30 |
|
31 |
-
$login = sanitize_user( tutils()->array_get('user_login', $_POST));
|
32 |
|
33 |
if ( empty( $login ) ) {
|
34 |
-
tutor_flash_set('danger', __( 'Enter a username or email address.', 'tutor' ));
|
35 |
return false;
|
36 |
} else {
|
37 |
// Check on username first, as customers can use emails as usernames.
|
@@ -48,17 +48,17 @@ class FormHandler {
|
|
48 |
do_action( 'lostpassword_post', $errors );
|
49 |
|
50 |
if ( $errors->get_error_code() ) {
|
51 |
-
tutor_flash_set('danger', $errors->get_error_message() );
|
52 |
return false;
|
53 |
}
|
54 |
|
55 |
if ( ! $user_data ) {
|
56 |
-
tutor_flash_set('danger', __( 'Invalid username or email.', 'tutor' ) );
|
57 |
return false;
|
58 |
}
|
59 |
|
60 |
if ( is_multisite() && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) {
|
61 |
-
tutor_flash_set('danger', __( 'Invalid username or email.', 'tutor' ) );
|
62 |
return false;
|
63 |
}
|
64 |
|
@@ -70,68 +70,71 @@ class FormHandler {
|
|
70 |
$allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
|
71 |
|
72 |
if ( ! $allow ) {
|
73 |
-
tutor_flash_set('danger', __( 'Password reset is not allowed for this user', 'tutor' ) );
|
74 |
return false;
|
75 |
} elseif ( is_wp_error( $allow ) ) {
|
76 |
-
tutor_flash_set('danger', $allow->get_error_message() );
|
77 |
return false;
|
78 |
}
|
79 |
|
80 |
// Get password reset key (function introduced in WordPress 4.4).
|
81 |
-
$key = get_password_reset_key($user_data);
|
82 |
|
83 |
// Send email notification.
|
84 |
do_action( 'tutor_reset_password_notification', $user_login, $key );
|
85 |
}
|
86 |
|
87 |
-
public function reset_password_notification( $user_login = '', $reset_key = ''){
|
88 |
-
$this->sendNotification($user_login, $reset_key);
|
89 |
|
90 |
-
$html
|
91 |
-
$html .=
|
92 |
-
$html .=
|
93 |
-
tutor_flash_set('success', $html);
|
94 |
}
|
95 |
|
96 |
-
public function lostpassword_url($url){
|
97 |
-
return tutils()->tutor_dashboard_url('retrieve-password');
|
98 |
}
|
99 |
|
100 |
-
public function tutor_process_reset_password(){
|
101 |
tutils()->checking_nonce();
|
102 |
|
103 |
-
$reset_key
|
104 |
-
$user_id
|
105 |
-
$password
|
106 |
-
$confirm_password = sanitize_text_field(tutils()->array_get('confirm_password', $_POST));
|
107 |
|
108 |
-
$user = get_user_by('ID', $user_id);
|
109 |
$user = check_password_reset_key( $reset_key, $user->user_login );
|
110 |
|
111 |
if ( is_wp_error( $user ) ) {
|
112 |
-
tutor_flash_set('danger', __( 'This key is invalid or has already been used. Please reset your password again if needed.', 'tutor') );
|
113 |
return false;
|
114 |
}
|
115 |
|
116 |
-
|
117 |
if ( $user instanceof \WP_User ) {
|
118 |
-
if (
|
119 |
-
tutor_flash_set('danger', __( 'Please enter your password.', 'tutor') );
|
120 |
return false;
|
121 |
}
|
122 |
|
123 |
-
if ( $password !== $confirm_password) {
|
124 |
-
tutor_flash_set('danger', __( 'Passwords do not match.', 'tutor') );
|
125 |
return false;
|
126 |
}
|
127 |
|
128 |
-
tutils()->reset_password($user, $password);
|
129 |
|
130 |
do_action( 'tutor_user_reset_password', $user );
|
131 |
|
132 |
// Perform the login.
|
133 |
-
$creds = array(
|
134 |
-
|
|
|
|
|
|
|
|
|
135 |
|
136 |
do_action( 'tutor_user_reset_password_login', $user );
|
137 |
|
@@ -147,38 +150,38 @@ class FormHandler {
|
|
147 |
* Send E-Mail notification
|
148 |
* We are sending directly right now, later we will introduce centralised E-Mail notification System...
|
149 |
*/
|
150 |
-
public function sendNotification($user_login, $reset_key){
|
151 |
-
//Send the E-Mail to user
|
152 |
|
153 |
$user_data = get_user_by( 'login', $user_login );
|
154 |
|
155 |
$variable = array(
|
156 |
'user_login' => $user_login,
|
157 |
-
'reset_key'
|
158 |
-
'user_id'
|
159 |
);
|
160 |
|
161 |
-
$html
|
162 |
-
$subject = sprintf(__( 'Password Reset Request for %s', 'tutor' ), get_option( 'blogname' ));
|
163 |
|
164 |
$header = 'Content-Type: text/html' . "\r\n";
|
165 |
|
166 |
add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
|
167 |
add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
|
168 |
|
169 |
-
wp_mail($user_data->user_email, $subject, $html, $header);
|
170 |
|
171 |
remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
|
172 |
remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
|
173 |
}
|
174 |
|
175 |
-
public function get_from_address(){
|
176 |
-
return apply_filters('tutor_email_from_address', get_tutor_option('email_from_address'));
|
177 |
}
|
178 |
|
179 |
-
public function get_from_name(){
|
180 |
-
return apply_filters('tutor_email_from_name', get_tutor_option('email_from_name'));
|
181 |
}
|
182 |
|
183 |
|
184 |
-
}
|
10 |
|
11 |
namespace TUTOR;
|
12 |
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
|
14 |
exit;
|
15 |
+
}
|
16 |
|
17 |
|
18 |
class FormHandler {
|
19 |
|
20 |
public function __construct() {
|
21 |
+
add_action( 'tutor_action_tutor_retrieve_password', array( $this, 'tutor_retrieve_password' ) );
|
22 |
+
add_action( 'tutor_action_tutor_process_reset_password', array( $this, 'tutor_process_reset_password' ) );
|
23 |
|
24 |
add_action( 'tutor_reset_password_notification', array( $this, 'reset_password_notification' ), 10, 2 );
|
25 |
add_filter( 'tutor_lostpassword_url', array( $this, 'lostpassword_url' ) );
|
26 |
}
|
27 |
|
28 |
+
public function tutor_retrieve_password() {
|
29 |
tutils()->checking_nonce();
|
30 |
|
31 |
+
$login = sanitize_user( tutils()->array_get( 'user_login', $_POST ) );
|
32 |
|
33 |
if ( empty( $login ) ) {
|
34 |
+
tutor_flash_set( 'danger', __( 'Enter a username or email address.', 'tutor' ) );
|
35 |
return false;
|
36 |
} else {
|
37 |
// Check on username first, as customers can use emails as usernames.
|
48 |
do_action( 'lostpassword_post', $errors );
|
49 |
|
50 |
if ( $errors->get_error_code() ) {
|
51 |
+
tutor_flash_set( 'danger', $errors->get_error_message() );
|
52 |
return false;
|
53 |
}
|
54 |
|
55 |
if ( ! $user_data ) {
|
56 |
+
tutor_flash_set( 'danger', __( 'Invalid username or email.', 'tutor' ) );
|
57 |
return false;
|
58 |
}
|
59 |
|
60 |
if ( is_multisite() && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) {
|
61 |
+
tutor_flash_set( 'danger', __( 'Invalid username or email.', 'tutor' ) );
|
62 |
return false;
|
63 |
}
|
64 |
|
70 |
$allow = apply_filters( 'allow_password_reset', true, $user_data->ID );
|
71 |
|
72 |
if ( ! $allow ) {
|
73 |
+
tutor_flash_set( 'danger', __( 'Password reset is not allowed for this user', 'tutor' ) );
|
74 |
return false;
|
75 |
} elseif ( is_wp_error( $allow ) ) {
|
76 |
+
tutor_flash_set( 'danger', $allow->get_error_message() );
|
77 |
return false;
|
78 |
}
|
79 |
|
80 |
// Get password reset key (function introduced in WordPress 4.4).
|
81 |
+
$key = get_password_reset_key( $user_data );
|
82 |
|
83 |
// Send email notification.
|
84 |
do_action( 'tutor_reset_password_notification', $user_login, $key );
|
85 |
}
|
86 |
|
87 |
+
public function reset_password_notification( $user_login = '', $reset_key = '' ) {
|
88 |
+
$this->sendNotification( $user_login, $reset_key );
|
89 |
|
90 |
+
$html = '<h3>' . __( 'Check your E-Mail', 'tutor' ) . '</h3>';
|
91 |
+
$html .= '<p>' . __( "We've sent an email to this account's email address. Click the link in the email to reset your password", 'tutor' ) . '</p>';
|
92 |
+
$html .= '<p>' . __( "If you don't see the email, check other places it might be, like your junk, spam, social, promotion or others folders.", 'tutor' ) . '</p>';
|
93 |
+
tutor_flash_set( 'success', $html );
|
94 |
}
|
95 |
|
96 |
+
public function lostpassword_url( $url ) {
|
97 |
+
return tutils()->tutor_dashboard_url( 'retrieve-password' );
|
98 |
}
|
99 |
|
100 |
+
public function tutor_process_reset_password() {
|
101 |
tutils()->checking_nonce();
|
102 |
|
103 |
+
$reset_key = sanitize_text_field( tutils()->array_get( 'reset_key', $_POST ) );
|
104 |
+
$user_id = (int) sanitize_text_field( tutils()->array_get( 'user_id', $_POST ) );
|
105 |
+
$password = sanitize_text_field( tutils()->array_get( 'password', $_POST ) );
|
106 |
+
$confirm_password = sanitize_text_field( tutils()->array_get( 'confirm_password', $_POST ) );
|
107 |
|
108 |
+
$user = get_user_by( 'ID', $user_id );
|
109 |
$user = check_password_reset_key( $reset_key, $user->user_login );
|
110 |
|
111 |
if ( is_wp_error( $user ) ) {
|
112 |
+
tutor_flash_set( 'danger', __( 'This key is invalid or has already been used. Please reset your password again if needed.', 'tutor' ) );
|
113 |
return false;
|
114 |
}
|
115 |
|
|
|
116 |
if ( $user instanceof \WP_User ) {
|
117 |
+
if ( ! $password ) {
|
118 |
+
tutor_flash_set( 'danger', __( 'Please enter your password.', 'tutor' ) );
|
119 |
return false;
|
120 |
}
|
121 |
|
122 |
+
if ( $password !== $confirm_password ) {
|
123 |
+
tutor_flash_set( 'danger', __( 'Passwords do not match.', 'tutor' ) );
|
124 |
return false;
|
125 |
}
|
126 |
|
127 |
+
tutils()->reset_password( $user, $password );
|
128 |
|
129 |
do_action( 'tutor_user_reset_password', $user );
|
130 |
|
131 |
// Perform the login.
|
132 |
+
$creds = array(
|
133 |
+
'user_login' => $user->user_login,
|
134 |
+
'user_password' => $password,
|
135 |
+
'remember' => true,
|
136 |
+
);
|
137 |
+
$user = wp_signon( apply_filters( 'tutor_login_credentials', $creds ), is_ssl() );
|
138 |
|
139 |
do_action( 'tutor_user_reset_password_login', $user );
|
140 |
|
150 |
* Send E-Mail notification
|
151 |
* We are sending directly right now, later we will introduce centralised E-Mail notification System...
|
152 |
*/
|
153 |
+
public function sendNotification( $user_login, $reset_key ) {
|
154 |
+
// Send the E-Mail to user
|
155 |
|
156 |
$user_data = get_user_by( 'login', $user_login );
|
157 |
|
158 |
$variable = array(
|
159 |
'user_login' => $user_login,
|
160 |
+
'reset_key' => $reset_key,
|
161 |
+
'user_id' => $user_data->ID,
|
162 |
);
|
163 |
|
164 |
+
$html = tutor_get_template_html( 'email.send-reset-password', $variable );
|
165 |
+
$subject = sprintf( __( 'Password Reset Request for %s', 'tutor' ), get_option( 'blogname' ) );
|
166 |
|
167 |
$header = 'Content-Type: text/html' . "\r\n";
|
168 |
|
169 |
add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
|
170 |
add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
|
171 |
|
172 |
+
wp_mail( $user_data->user_email, $subject, $html, $header );
|
173 |
|
174 |
remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
|
175 |
remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
|
176 |
}
|
177 |
|
178 |
+
public function get_from_address() {
|
179 |
+
return apply_filters( 'tutor_email_from_address', get_tutor_option( 'email_from_address' ) );
|
180 |
}
|
181 |
|
182 |
+
public function get_from_name() {
|
183 |
+
return apply_filters( 'tutor_email_from_name', get_tutor_option( 'email_from_name' ) );
|
184 |
}
|
185 |
|
186 |
|
187 |
+
}
|
classes/Instructors_List.php
CHANGED
@@ -1,47 +1,55 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
if (! class_exists('Tutor_List_Table')){
|
8 |
-
include_once tutor()->path.'classes/Tutor_List_Table.php';
|
9 |
}
|
10 |
|
11 |
class Instructors_List extends \Tutor_List_Table {
|
12 |
|
13 |
const INSTRUCTOR_LIST_PAGE = 'tutor-instructors';
|
14 |
|
15 |
-
function __construct(){
|
16 |
global $status, $page;
|
17 |
|
18 |
-
//Set parent defaults
|
19 |
-
parent::__construct(
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
24 |
|
25 |
-
|
26 |
}
|
27 |
|
28 |
-
function column_default($item, $column_name){
|
29 |
-
switch($column_name){
|
30 |
case 'user_email':
|
31 |
case 'display_name':
|
32 |
return $item->$column_name;
|
33 |
case 'registration_date':
|
34 |
-
return esc_html( date( get_option( 'date_format'), strtotime($item->user_registered ) ) );
|
35 |
default:
|
36 |
-
return print_r($item,true); //Show the whole array for troubleshooting purposes
|
37 |
}
|
38 |
}
|
39 |
|
40 |
-
function column_total_course($item){
|
41 |
global $wpdb;
|
42 |
$course_post_type = tutor()->course_post_type;
|
43 |
|
44 |
-
$total_course = (int) $wpdb->get_var($wpdb->prepare(
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
echo $total_course;
|
47 |
}
|
@@ -51,132 +59,133 @@ class Instructors_List extends \Tutor_List_Table {
|
|
51 |
*
|
52 |
* Completed Course by User
|
53 |
*/
|
54 |
-
function column_status($item){
|
55 |
-
$status
|
56 |
-
$status_name = tutor_utils()->instructor_status($item->ID);
|
57 |
-
echo
|
58 |
}
|
59 |
|
60 |
-
function column_display_name($item) {
|
61 |
-
//Build row actions
|
62 |
$actions = array();
|
63 |
|
64 |
-
$status = tutor_utils()->instructor_status($item->ID, false);
|
65 |
|
66 |
-
switch ($status){
|
67 |
case 'pending':
|
68 |
-
$actions['approved'] = sprintf('<a class="instructor-action" data-action="approve" data-instructor-id="'
|
69 |
break;
|
70 |
case 'approved':
|
71 |
-
$actions['blocked'] = sprintf('<a data-prompt-message="'.__('Sure to Block?', 'tutor').'" class="instructor-action" data-action="blocked" data-instructor-id="'
|
72 |
break;
|
73 |
case 'blocked':
|
74 |
-
$actions['approved'] = sprintf('<a data-prompt-message="'.__('Sure to Un Block?', 'tutor').'" class="instructor-action" data-action="approve" data-instructor-id="'
|
75 |
break;
|
76 |
}
|
77 |
|
78 |
// Add user edit link
|
79 |
-
$edit_link
|
80 |
-
$edit_link
|
81 |
-
$actions['tutor-instructor-edit-link']
|
82 |
|
83 |
// Add remove instructor action
|
84 |
-
$removal_title
|
85 |
-
$removal_warning
|
86 |
-
$actions['tutor-remove-instructor'] = sprintf('<a data-prompt-message="' . $removal_warning . '" class="instructor-action" data-action="remove-instructor" data-instructor-id="'
|
87 |
|
88 |
-
//Return the title contents
|
89 |
-
return sprintf(
|
|
|
90 |
$item->display_name,
|
91 |
$item->ID,
|
92 |
-
$this->row_actions($actions)
|
93 |
);
|
94 |
}
|
95 |
|
96 |
-
function column_cb($item){
|
97 |
return sprintf(
|
98 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
99 |
-
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label ("instructor")
|
100 |
-
/*$2%s*/ $item->ID //The value of the checkbox should be the record's id
|
101 |
);
|
102 |
}
|
103 |
|
104 |
-
function column_instructor_commission($item){
|
105 |
-
$commision = apply_filters('tutor_pro_instructor_commission_string', $item->ID);
|
106 |
|
107 |
// If the return value is numeric, it means the filter was not executed.
|
108 |
// may be pro is not installed. So show N\A. The return value will something like '23 percent'
|
109 |
|
110 |
-
return !is_numeric($commision) ? $commision : 'N\\A';
|
111 |
}
|
112 |
|
113 |
-
function get_columns(){
|
114 |
$columns = array(
|
115 |
-
'cb'
|
116 |
-
'display_name'
|
117 |
-
'user_email'
|
118 |
-
'total_course'
|
119 |
-
'instructor_commission'
|
120 |
-
'registration_date'
|
121 |
-
'status'
|
122 |
);
|
123 |
return $columns;
|
124 |
}
|
125 |
|
126 |
function get_sortable_columns() {
|
127 |
$sortable_columns = array(
|
128 |
-
//'display_name' => array('title',false), //true means it's already sorted
|
129 |
);
|
130 |
return $sortable_columns;
|
131 |
}
|
132 |
|
133 |
function get_bulk_actions() {
|
134 |
$actions = array(
|
135 |
-
'delete'
|
136 |
);
|
137 |
return $actions;
|
138 |
}
|
139 |
|
140 |
function process_bulk_action() {
|
141 |
-
if( 'approve' === $this->current_action() ) {
|
142 |
-
$instructor_id = (int) sanitize_text_field($_GET['instructor']);
|
143 |
|
144 |
-
do_action('tutor_before_approved_instructor', $instructor_id);
|
145 |
|
146 |
-
update_user_meta($instructor_id, '_tutor_instructor_status', 'approved');
|
147 |
-
update_user_meta($instructor_id, '_tutor_instructor_approved', tutor_time());
|
148 |
|
149 |
-
$instructor = new \WP_User($instructor_id);
|
150 |
-
$instructor->add_role(tutor()->instructor_role);
|
151 |
|
152 |
-
//TODO: send E-Mail to this user about instructor approval, should via hook
|
153 |
-
do_action('tutor_after_approved_instructor', $instructor_id);
|
154 |
}
|
155 |
|
156 |
-
if( 'blocked' === $this->current_action() ) {
|
157 |
-
$instructor_id = (int) sanitize_text_field($_GET['instructor']);
|
158 |
|
159 |
-
do_action('tutor_before_blocked_instructor', $instructor_id);
|
160 |
-
update_user_meta($instructor_id, '_tutor_instructor_status', 'blocked');
|
161 |
|
162 |
-
$instructor = new \WP_User($instructor_id);
|
163 |
-
$instructor->remove_role(tutor()->instructor_role);
|
164 |
-
do_action('tutor_after_blocked_instructor', $instructor_id);
|
165 |
|
166 |
-
//TODO: send E-Mail to this user about instructor blocked, should via hook
|
167 |
}
|
168 |
|
169 |
-
//Detect when a bulk action is being triggered...
|
170 |
-
if( 'delete'=== $this->current_action() ) {
|
171 |
-
|
172 |
-
$delete_instructors = $_GET['instructor'];
|
173 |
-
if ( count($delete_instructors) ) {
|
174 |
-
foreach( $delete_instructors as $instructor ) {
|
175 |
-
do_action( 'tutor_insctructor_before_delete', $instructor);
|
176 |
|
177 |
-
wp_delete_user($instructor);
|
178 |
|
179 |
-
do_action( 'tutor_insctructor_after_delete', $instructor);
|
180 |
|
181 |
}
|
182 |
}
|
@@ -185,34 +194,36 @@ class Instructors_List extends \Tutor_List_Table {
|
|
185 |
|
186 |
/**
|
187 |
* Filter support added
|
188 |
-
*
|
189 |
* @param optional
|
190 |
-
*
|
191 |
* @since 1.9.7
|
192 |
*/
|
193 |
-
function prepare_items($search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '') {
|
194 |
$per_page = 20;
|
195 |
|
196 |
// $search_term = '';
|
197 |
// if (isset($_REQUEST['s'])){
|
198 |
-
//
|
199 |
// }
|
200 |
|
201 |
-
$columns
|
202 |
-
$hidden
|
203 |
$sortable = $this->get_sortable_columns();
|
204 |
|
205 |
-
$this->_column_headers = array($columns, $hidden, $sortable);
|
206 |
$this->process_bulk_action();
|
207 |
$current_page = $this->get_pagenum();
|
208 |
|
209 |
-
$total_items = tutor_utils()->get_total_instructors($search_filter);
|
210 |
-
$this->items = tutor_utils()->get_instructors(($current_page-1)
|
211 |
|
212 |
-
$this->set_pagination_args(
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
|
|
|
|
217 |
}
|
218 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
if ( ! class_exists( 'Tutor_List_Table' ) ) {
|
9 |
+
include_once tutor()->path . 'classes/Tutor_List_Table.php';
|
10 |
}
|
11 |
|
12 |
class Instructors_List extends \Tutor_List_Table {
|
13 |
|
14 |
const INSTRUCTOR_LIST_PAGE = 'tutor-instructors';
|
15 |
|
16 |
+
function __construct() {
|
17 |
global $status, $page;
|
18 |
|
19 |
+
// Set parent defaults
|
20 |
+
parent::__construct(
|
21 |
+
array(
|
22 |
+
'singular' => 'instructor', // singular name of the listed records
|
23 |
+
'plural' => 'instructors', // plural name of the listed records
|
24 |
+
'ajax' => false, // does this table support ajax?
|
25 |
+
)
|
26 |
+
);
|
27 |
|
28 |
+
// $this->process_bulk_action();
|
29 |
}
|
30 |
|
31 |
+
function column_default( $item, $column_name ) {
|
32 |
+
switch ( $column_name ) {
|
33 |
case 'user_email':
|
34 |
case 'display_name':
|
35 |
return $item->$column_name;
|
36 |
case 'registration_date':
|
37 |
+
return esc_html( date( get_option( 'date_format' ), strtotime( $item->user_registered ) ) );
|
38 |
default:
|
39 |
+
return print_r( $item, true ); // Show the whole array for troubleshooting purposes
|
40 |
}
|
41 |
}
|
42 |
|
43 |
+
function column_total_course( $item ) {
|
44 |
global $wpdb;
|
45 |
$course_post_type = tutor()->course_post_type;
|
46 |
|
47 |
+
$total_course = (int) $wpdb->get_var( $wpdb->prepare(
|
48 |
+
"SELECT count(ID) from {$wpdb->posts}
|
49 |
+
WHERE post_author=%d AND post_type=%s ",
|
50 |
+
$item->ID,
|
51 |
+
$course_post_type
|
52 |
+
) );
|
53 |
|
54 |
echo $total_course;
|
55 |
}
|
59 |
*
|
60 |
* Completed Course by User
|
61 |
*/
|
62 |
+
function column_status( $item ) {
|
63 |
+
$status = tutor_utils()->instructor_status( $item->ID, false );
|
64 |
+
$status_name = tutor_utils()->instructor_status( $item->ID );
|
65 |
+
echo '<span class="tutor-status-context tutor-status-' . $status . '-context">' . $status_name . '</span>';
|
66 |
}
|
67 |
|
68 |
+
function column_display_name( $item ) {
|
69 |
+
// Build row actions
|
70 |
$actions = array();
|
71 |
|
72 |
+
$status = tutor_utils()->instructor_status( $item->ID, false );
|
73 |
|
74 |
+
switch ( $status ) {
|
75 |
case 'pending':
|
76 |
+
$actions['approved'] = sprintf( '<a class="instructor-action" data-action="approve" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Approve', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'approve', $item->ID );
|
77 |
break;
|
78 |
case 'approved':
|
79 |
+
$actions['blocked'] = sprintf( '<a data-prompt-message="' . __( 'Sure to Block?', 'tutor' ) . '" class="instructor-action" data-action="blocked" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Block', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'blocked', $item->ID );
|
80 |
break;
|
81 |
case 'blocked':
|
82 |
+
$actions['approved'] = sprintf( '<a data-prompt-message="' . __( 'Sure to Un Block?', 'tutor' ) . '" class="instructor-action" data-action="approve" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . __( 'Unblock', 'tutor' ) . '</a>', self::INSTRUCTOR_LIST_PAGE, 'approve', $item->ID );
|
83 |
break;
|
84 |
}
|
85 |
|
86 |
// Add user edit link
|
87 |
+
$edit_link = get_edit_user_link( $item->ID );
|
88 |
+
$edit_link = '<a href="' . esc_url( $edit_link ) . '">' . esc_html__( 'Edit' ) . '</a>';
|
89 |
+
$actions['tutor-instructor-edit-link'] = $edit_link;
|
90 |
|
91 |
// Add remove instructor action
|
92 |
+
$removal_title = $status == 'pending' ? __( 'Reject', 'tutor' ) : __( 'Remove as Instructor', 'tutor' );
|
93 |
+
$removal_warning = $status == 'pending' ? __( 'Sure to Reject?', 'tutor' ) : __( 'Sure to Remove as Instructor?', 'tutor' );
|
94 |
+
$actions['tutor-remove-instructor'] = sprintf( '<a data-prompt-message="' . $removal_warning . '" class="instructor-action" data-action="remove-instructor" data-instructor-id="' . $item->ID . '" href="?page=%s&action=%s&instructor=%s">' . $removal_title . '</a>', self::INSTRUCTOR_LIST_PAGE, 'remove-instructor', $item->ID );
|
95 |
|
96 |
+
// Return the title contents
|
97 |
+
return sprintf(
|
98 |
+
'%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
|
99 |
$item->display_name,
|
100 |
$item->ID,
|
101 |
+
$this->row_actions( $actions )
|
102 |
);
|
103 |
}
|
104 |
|
105 |
+
function column_cb( $item ) {
|
106 |
return sprintf(
|
107 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
108 |
+
/*$1%s*/ $this->_args['singular'], // Let's simply repurpose the table's singular label ("instructor")
|
109 |
+
/*$2%s*/ $item->ID // The value of the checkbox should be the record's id
|
110 |
);
|
111 |
}
|
112 |
|
113 |
+
function column_instructor_commission( $item ) {
|
114 |
+
$commision = apply_filters( 'tutor_pro_instructor_commission_string', $item->ID );
|
115 |
|
116 |
// If the return value is numeric, it means the filter was not executed.
|
117 |
// may be pro is not installed. So show N\A. The return value will something like '23 percent'
|
118 |
|
119 |
+
return ! is_numeric( $commision ) ? $commision : 'N\\A';
|
120 |
}
|
121 |
|
122 |
+
function get_columns() {
|
123 |
$columns = array(
|
124 |
+
'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
|
125 |
+
'display_name' => __( 'Name', 'tutor' ),
|
126 |
+
'user_email' => __( 'E-Mail', 'tutor' ),
|
127 |
+
'total_course' => __( 'Total Course', 'tutor' ),
|
128 |
+
'instructor_commission' => __( 'Instructor Commission', 'tutor' ),
|
129 |
+
'registration_date' => __( 'Date', 'tutor' ),
|
130 |
+
'status' => __( 'Status', 'tutor' ),
|
131 |
);
|
132 |
return $columns;
|
133 |
}
|
134 |
|
135 |
function get_sortable_columns() {
|
136 |
$sortable_columns = array(
|
137 |
+
// 'display_name' => array('title',false), //true means it's already sorted
|
138 |
);
|
139 |
return $sortable_columns;
|
140 |
}
|
141 |
|
142 |
function get_bulk_actions() {
|
143 |
$actions = array(
|
144 |
+
'delete' => 'Delete',
|
145 |
);
|
146 |
return $actions;
|
147 |
}
|
148 |
|
149 |
function process_bulk_action() {
|
150 |
+
if ( 'approve' === $this->current_action() ) {
|
151 |
+
$instructor_id = (int) sanitize_text_field( $_GET['instructor'] );
|
152 |
|
153 |
+
do_action( 'tutor_before_approved_instructor', $instructor_id );
|
154 |
|
155 |
+
update_user_meta( $instructor_id, '_tutor_instructor_status', 'approved' );
|
156 |
+
update_user_meta( $instructor_id, '_tutor_instructor_approved', tutor_time() );
|
157 |
|
158 |
+
$instructor = new \WP_User( $instructor_id );
|
159 |
+
$instructor->add_role( tutor()->instructor_role );
|
160 |
|
161 |
+
// TODO: send E-Mail to this user about instructor approval, should via hook
|
162 |
+
do_action( 'tutor_after_approved_instructor', $instructor_id );
|
163 |
}
|
164 |
|
165 |
+
if ( 'blocked' === $this->current_action() ) {
|
166 |
+
$instructor_id = (int) sanitize_text_field( $_GET['instructor'] );
|
167 |
|
168 |
+
do_action( 'tutor_before_blocked_instructor', $instructor_id );
|
169 |
+
update_user_meta( $instructor_id, '_tutor_instructor_status', 'blocked' );
|
170 |
|
171 |
+
$instructor = new \WP_User( $instructor_id );
|
172 |
+
$instructor->remove_role( tutor()->instructor_role );
|
173 |
+
do_action( 'tutor_after_blocked_instructor', $instructor_id );
|
174 |
|
175 |
+
// TODO: send E-Mail to this user about instructor blocked, should via hook
|
176 |
}
|
177 |
|
178 |
+
// Detect when a bulk action is being triggered...
|
179 |
+
if ( 'delete' === $this->current_action() ) {
|
180 |
+
|
181 |
+
$delete_instructors = tutor_sanitize_data($_GET['instructor']);
|
182 |
+
if ( count( $delete_instructors ) ) {
|
183 |
+
foreach ( $delete_instructors as $instructor ) {
|
184 |
+
do_action( 'tutor_insctructor_before_delete', $instructor );
|
185 |
|
186 |
+
wp_delete_user( $instructor );
|
187 |
|
188 |
+
do_action( 'tutor_insctructor_after_delete', $instructor );
|
189 |
|
190 |
}
|
191 |
}
|
194 |
|
195 |
/**
|
196 |
* Filter support added
|
197 |
+
*
|
198 |
* @param optional
|
199 |
+
*
|
200 |
* @since 1.9.7
|
201 |
*/
|
202 |
+
function prepare_items( $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '' ) {
|
203 |
$per_page = 20;
|
204 |
|
205 |
// $search_term = '';
|
206 |
// if (isset($_REQUEST['s'])){
|
207 |
+
// $search_term = sanitize_text_field($_REQUEST['s']);
|
208 |
// }
|
209 |
|
210 |
+
$columns = $this->get_columns();
|
211 |
+
$hidden = array();
|
212 |
$sortable = $this->get_sortable_columns();
|
213 |
|
214 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
215 |
$this->process_bulk_action();
|
216 |
$current_page = $this->get_pagenum();
|
217 |
|
218 |
+
$total_items = tutor_utils()->get_total_instructors( $search_filter );
|
219 |
+
$this->items = tutor_utils()->get_instructors( ( $current_page - 1 ) * $per_page, $per_page, $search_filter, $course_filter, $date_filter, $order_filter, $status = null, $cat_ids = array() );
|
220 |
|
221 |
+
$this->set_pagination_args(
|
222 |
+
array(
|
223 |
+
'total_items' => $total_items,
|
224 |
+
'per_page' => $per_page,
|
225 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
226 |
+
)
|
227 |
+
);
|
228 |
}
|
229 |
+
}
|
classes/Lesson.php
CHANGED
@@ -1,225 +1,227 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
class Lesson extends Tutor_Base {
|
8 |
public function __construct() {
|
9 |
parent::__construct();
|
10 |
|
11 |
-
add_action( 'add_meta_boxes', array($this, 'register_meta_box') );
|
12 |
-
add_action('save_post_'
|
13 |
|
14 |
-
add_action('wp_ajax_tutor_load_edit_lesson_modal', array($this,
|
15 |
-
add_action('wp_ajax_tutor_modal_create_or_update_lesson', array($this,
|
16 |
-
add_action('wp_ajax_tutor_delete_lesson_by_id', array($this,
|
17 |
|
18 |
-
add_filter('get_sample_permalink', array($this, 'change_lesson_permalink'), 10, 2);
|
19 |
-
add_action('admin_init', array($this, 'flush_rewrite_rules'));
|
20 |
|
21 |
/**
|
22 |
* Add Column
|
23 |
*/
|
24 |
|
25 |
-
add_filter( "manage_{$this->lesson_post_type}_posts_columns", array($this, 'add_column'), 10,1 );
|
26 |
-
add_action( "manage_{$this->lesson_post_type}_posts_custom_column"
|
27 |
|
28 |
-
//Frontend Action
|
29 |
-
add_action('template_redirect', array($this, 'mark_lesson_complete'));
|
30 |
|
31 |
-
add_action('wp_ajax_tutor_render_lesson_content', array($this,
|
32 |
-
add_action('wp_ajax_nopriv_tutor_render_lesson_content', array($this,
|
33 |
|
34 |
/**
|
35 |
* Autoplay next video
|
|
|
36 |
* @since v.1.4.9
|
37 |
*/
|
38 |
-
add_action('wp_ajax_autoload_next_course_content', array($this, 'autoload_next_course_content'));
|
39 |
|
40 |
/**
|
41 |
* Load next course item after click complete button
|
|
|
42 |
* @since v.1.5.3
|
43 |
*/
|
44 |
-
add_action('tutor_lesson_completed_after', array($this, 'tutor_lesson_completed_after'), 999);
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
* Registering metabox
|
49 |
*/
|
50 |
-
public function register_meta_box(){
|
51 |
$lesson_post_type = $this->lesson_post_type;
|
52 |
|
53 |
-
add_meta_box( 'tutor-course-select', __( 'Select Course', 'tutor' ), array($this, 'lesson_metabox'), $lesson_post_type );
|
54 |
-
add_meta_box( 'tutor-lesson-videos', __( 'Lesson Video', 'tutor' ), array($this, 'lesson_video_metabox'), $lesson_post_type );
|
55 |
-
add_meta_box( 'tutor-lesson-attachments', __( 'Attachments', 'tutor' ), array($this, 'lesson_attachments_metabox'), $lesson_post_type );
|
56 |
}
|
57 |
|
58 |
-
public function lesson_metabox(){
|
59 |
-
include
|
60 |
}
|
61 |
|
62 |
-
public function lesson_video_metabox(){
|
63 |
-
include
|
64 |
}
|
65 |
|
66 |
-
public function lesson_attachments_metabox(){
|
67 |
-
include
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
* @param $post_ID
|
72 |
*
|
73 |
* Saving lesson meta and assets
|
74 |
-
*
|
75 |
*/
|
76 |
-
public function save_lesson_meta($post_ID){
|
77 |
-
//Course
|
78 |
-
if (isset($_POST['selected_course'])) {
|
79 |
$course_id = (int) sanitize_text_field( $_POST['selected_course'] );
|
80 |
if ( $course_id ) {
|
81 |
update_post_meta( $post_ID, '_tutor_course_id_for_lesson', $course_id );
|
82 |
}
|
83 |
}
|
84 |
|
85 |
-
//Video
|
86 |
-
$video_source = sanitize_text_field( tutils()->array_get('video.source', $_POST) );
|
87 |
-
if ( $video_source === '-1'){
|
88 |
-
delete_post_meta($post_ID, '_video');
|
89 |
-
}elseif($video_source) {
|
90 |
-
$video = (array)tutor_utils()->array_get('video', $_POST, array());
|
91 |
-
update_post_meta($post_ID, '_video', $video);
|
92 |
}
|
93 |
|
94 |
-
//Attachments
|
95 |
$attachments = array();
|
96 |
-
if ( ! empty($_POST['tutor_attachments'])){
|
97 |
-
$attachments = tutor_utils()->sanitize_array($_POST['tutor_attachments']);
|
98 |
-
$attachments = array_unique($attachments);
|
99 |
-
}
|
100 |
|
101 |
/**
|
102 |
* it !empty attachment then update meta else
|
103 |
* delete meta key to prevetn empty data in db
|
|
|
104 |
* @since 1.8.9
|
105 |
*/
|
106 |
-
if( ! empty($attachments) ) {
|
107 |
-
update_post_meta($post_ID, '_tutor_attachments', $attachments);
|
108 |
} else {
|
109 |
-
delete_post_meta($post_ID, '_tutor_attachments');
|
110 |
}
|
111 |
-
|
112 |
}
|
113 |
|
114 |
-
public function tutor_load_edit_lesson_modal(){
|
115 |
tutils()->checking_nonce();
|
116 |
|
117 |
-
$lesson_id = (int) tutor_utils()->avalue_dot('lesson_id', $_POST);
|
118 |
-
$topic_id
|
119 |
|
120 |
-
if(!tutils()->can_user_manage('topic', $topic_id)) {
|
121 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
* If Lesson Not Exists, provide dummy
|
126 |
*/
|
127 |
$post_arr = array(
|
128 |
-
'ID'
|
129 |
'post_content' => '',
|
130 |
'post_type' => $this->lesson_post_type,
|
131 |
-
'post_title' => __('Draft Lesson', 'tutor'),
|
132 |
'post_status' => 'publish',
|
133 |
'post_author' => get_current_user_id(),
|
134 |
'post_parent' => $topic_id,
|
135 |
);
|
136 |
|
137 |
-
$post = $lesson_id ? get_post($lesson_id) : (object)$post_arr;
|
138 |
-
|
139 |
ob_start();
|
140 |
-
include tutor()->path.'views/modal/edit-lesson.php';
|
141 |
$output = ob_get_clean();
|
142 |
|
143 |
-
wp_send_json_success(array('output' => $output));
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
* @since v.1.0.0
|
148 |
* @updated v.1.5.1
|
149 |
*/
|
150 |
-
public function tutor_modal_create_or_update_lesson(){
|
151 |
tutils()->checking_nonce();
|
152 |
|
153 |
global $wpdb;
|
154 |
-
|
155 |
-
$lesson_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('lesson_id', $_POST));
|
156 |
-
$topic_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('current_topic_id', $_POST));
|
157 |
-
$course_id = tutor_utils()->get_course_id_by('topic', $topic_id);
|
158 |
-
$_lesson_thumbnail_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('_lesson_thumbnail_id', $_POST));
|
159 |
-
|
160 |
-
if(!tutils()->can_user_manage('topic', $topic_id)) {
|
161 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
162 |
-
}
|
163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
|
165 |
-
$title
|
166 |
-
$lesson_content = wp_kses_post($_POST['lesson_content']);
|
167 |
|
168 |
$lesson_data = array(
|
169 |
'post_type' => $this->lesson_post_type,
|
170 |
'post_title' => $title,
|
171 |
-
'post_name' => sanitize_title($title),
|
172 |
'post_content' => $lesson_content,
|
173 |
'post_status' => 'publish',
|
174 |
'post_author' => get_current_user_id(),
|
175 |
-
'post_parent' => $topic_id
|
176 |
);
|
177 |
|
178 |
-
if($lesson_id==0) {
|
179 |
|
180 |
$lesson_data['menu_order'] = tutor_utils()->get_next_course_content_order_id( $topic_id );
|
181 |
-
$lesson_id
|
182 |
|
183 |
-
if ($lesson_id ) {
|
184 |
-
do_action('tutor/lesson/created', $lesson_id);
|
185 |
update_post_meta( $lesson_id, '_tutor_course_id_for_lesson', $course_id );
|
186 |
} else {
|
187 |
-
wp_send_json_error( array('message' => __('Couldn\'t create lesson.', 'tutor')) );
|
188 |
}
|
189 |
} else {
|
190 |
-
$lesson_data['ID']
|
191 |
|
192 |
-
do_action('tutor/lesson_update/before', $lesson_id);
|
193 |
-
wp_update_post($lesson_data);
|
194 |
-
if ($_lesson_thumbnail_id){
|
195 |
-
update_post_meta($lesson_id, '_thumbnail_id', $_lesson_thumbnail_id);
|
196 |
} else {
|
197 |
-
delete_post_meta($lesson_id, '_thumbnail_id');
|
198 |
}
|
199 |
-
do_action('tutor/lesson_update/after', $lesson_id);
|
200 |
}
|
201 |
-
|
202 |
ob_start();
|
203 |
-
include
|
204 |
$course_contents = ob_get_clean();
|
205 |
|
206 |
-
wp_send_json_success(array('course_contents' => $course_contents));
|
207 |
}
|
208 |
|
209 |
/**
|
210 |
* Delete Lesson from course builder
|
211 |
*/
|
212 |
-
public function tutor_delete_lesson_by_id(){
|
213 |
tutils()->checking_nonce();
|
214 |
|
215 |
-
$lesson_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('lesson_id', $_POST));
|
216 |
|
217 |
-
if(!tutils()->can_user_manage('lesson', $lesson_id)) {
|
218 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
219 |
}
|
220 |
|
221 |
-
wp_delete_post($lesson_id, true);
|
222 |
-
delete_post_meta($lesson_id, '_tutor_course_id_for_lesson');
|
223 |
wp_send_json_success();
|
224 |
}
|
225 |
|
@@ -233,43 +235,43 @@ class Lesson extends Tutor_Base {
|
|
233 |
* Changed the URI based
|
234 |
*/
|
235 |
|
236 |
-
public function change_lesson_permalink($uri, $lesson_id){
|
237 |
-
$post = get_post($lesson_id);
|
238 |
|
239 |
-
if ($post && $post->post_type === $this->lesson_post_type){
|
240 |
-
$uri_base = trailingslashit(site_url());
|
241 |
|
242 |
-
$sample_course =
|
243 |
-
$is_course
|
244 |
-
if ($is_course){
|
245 |
-
$course = get_post($is_course);
|
246 |
-
if ($course){
|
247 |
$sample_course = $course->post_name;
|
248 |
}
|
249 |
}
|
250 |
|
251 |
-
$new_course_base = $uri_base."course/{$sample_course}/lesson/%pagename%/";
|
252 |
-
$uri[0]
|
253 |
}
|
254 |
|
255 |
return $uri;
|
256 |
}
|
257 |
|
258 |
|
259 |
-
public function flush_rewrite_rules(){
|
260 |
-
$is_required_flush = get_option('required_rewrite_flush');
|
261 |
-
if ($is_required_flush){
|
262 |
flush_rewrite_rules();
|
263 |
delete_option( 'required_rewrite_flush' );
|
264 |
}
|
265 |
}
|
266 |
|
267 |
|
268 |
-
public function add_column($columns){
|
269 |
$date_col = $columns['date'];
|
270 |
-
unset($columns['date']);
|
271 |
-
$columns['course'] = __('Course', 'tutor');
|
272 |
-
$columns['date']
|
273 |
|
274 |
return $columns;
|
275 |
}
|
@@ -277,16 +279,14 @@ class Lesson extends Tutor_Base {
|
|
277 |
/**
|
278 |
* @param $column
|
279 |
* @param $post_id
|
280 |
-
*
|
281 |
*/
|
282 |
-
public function custom_lesson_column($column, $post_id ){
|
283 |
-
if ($column === 'course'){
|
284 |
|
285 |
-
$course_id = tutor_utils()->get_course_id_by('lesson', $post_id);
|
286 |
-
if ($course_id){
|
287 |
-
echo '<a href="'.admin_url('post.php?post='
|
288 |
}
|
289 |
-
|
290 |
}
|
291 |
}
|
292 |
|
@@ -296,50 +296,50 @@ class Lesson extends Tutor_Base {
|
|
296 |
*
|
297 |
* @since v.1.0.0
|
298 |
*/
|
299 |
-
public function mark_lesson_complete(){
|
300 |
-
if ( ! isset($_POST['tutor_action'])
|
301 |
return;
|
302 |
}
|
303 |
-
//Checking nonce
|
304 |
tutor_utils()->checking_nonce();
|
305 |
|
306 |
$user_id = get_current_user_id();
|
307 |
|
308 |
-
//TODO: need to show view if not signed_in
|
309 |
-
if ( ! $user_id){
|
310 |
-
die(__('Please Sign-In', 'tutor'));
|
311 |
}
|
312 |
|
313 |
-
$lesson_id = (int) sanitize_text_field($_POST['lesson_id']);
|
314 |
|
315 |
-
do_action('tutor_lesson_completed_before', $lesson_id);
|
316 |
/**
|
317 |
* Marking lesson at user meta, meta format, _tutor_completed_lesson_id_{id} and value = tutor_time();
|
318 |
*/
|
319 |
-
tutor_utils()->mark_lesson_complete($lesson_id);
|
320 |
|
321 |
-
do_action('tutor_lesson_completed_after', $lesson_id, $user_id);
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
* Render the lesson content
|
326 |
*/
|
327 |
-
public function tutor_render_lesson_content(){
|
328 |
tutils()->checking_nonce();
|
329 |
|
330 |
-
$lesson_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('lesson_id', $_POST));
|
331 |
|
332 |
-
$ancestors = get_post_ancestors($lesson_id);
|
333 |
-
$course_id = !empty($ancestors) ? array_pop($ancestors): $lesson_id;
|
334 |
|
335 |
// Course must be public or current user must be enrolled to access this lesson
|
336 |
-
if(get_post_meta($course_id, '_tutor_is_public_course', true)!=='yes' && !tutils()->is_enrolled($course_id)){
|
337 |
-
|
338 |
-
$is_admin = tutor_utils()->has_user_role('administrator');
|
339 |
-
$allowed
|
340 |
|
341 |
-
if(
|
342 |
-
http_response_code(400);
|
343 |
exit;
|
344 |
}
|
345 |
}
|
@@ -347,13 +347,13 @@ class Lesson extends Tutor_Base {
|
|
347 |
ob_start();
|
348 |
global $post;
|
349 |
|
350 |
-
$post = get_post($lesson_id);
|
351 |
-
setup_postdata($post);
|
352 |
tutor_lesson_content();
|
353 |
wp_reset_postdata();
|
354 |
|
355 |
$html = ob_get_clean();
|
356 |
-
wp_send_json_success(array('html' => $html));
|
357 |
}
|
358 |
|
359 |
/**
|
@@ -361,19 +361,19 @@ class Lesson extends Tutor_Base {
|
|
361 |
*
|
362 |
* @since v.1.4.9
|
363 |
*/
|
364 |
-
public function autoload_next_course_content(){
|
365 |
tutor_utils()->checking_nonce();
|
366 |
|
367 |
-
$post_id
|
368 |
-
$content_id = tutils()->get_post_id($post_id);
|
369 |
-
$contents
|
370 |
|
371 |
-
$autoload_course_content = (bool) get_tutor_option('autoload_next_course_content');
|
372 |
-
$next_url
|
373 |
-
if($autoload_course_content) {
|
374 |
-
$next_url = get_the_permalink($contents->next_id);
|
375 |
}
|
376 |
-
wp_send_json_success(array('next_url' => $next_url));
|
377 |
}
|
378 |
|
379 |
/**
|
@@ -381,13 +381,13 @@ class Lesson extends Tutor_Base {
|
|
381 |
*
|
382 |
* @since v.1.5.3
|
383 |
*/
|
384 |
-
public function tutor_lesson_completed_after($content_id){
|
385 |
-
$contents
|
386 |
-
$autoload_course_content = (bool) get_tutor_option('autoload_next_course_content');
|
387 |
-
if($autoload_course_content) {
|
388 |
-
wp_redirect(get_the_permalink($contents->next_id));
|
389 |
} else {
|
390 |
-
wp_redirect(get_the_permalink($content_id));
|
391 |
}
|
392 |
die();
|
393 |
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
class Lesson extends Tutor_Base {
|
9 |
public function __construct() {
|
10 |
parent::__construct();
|
11 |
|
12 |
+
add_action( 'add_meta_boxes', array( $this, 'register_meta_box' ) );
|
13 |
+
add_action( 'save_post_' . $this->lesson_post_type, array( $this, 'save_lesson_meta' ) );
|
14 |
|
15 |
+
add_action( 'wp_ajax_tutor_load_edit_lesson_modal', array( $this, 'tutor_load_edit_lesson_modal' ) );
|
16 |
+
add_action( 'wp_ajax_tutor_modal_create_or_update_lesson', array( $this, 'tutor_modal_create_or_update_lesson' ) );
|
17 |
+
add_action( 'wp_ajax_tutor_delete_lesson_by_id', array( $this, 'tutor_delete_lesson_by_id' ) );
|
18 |
|
19 |
+
add_filter( 'get_sample_permalink', array( $this, 'change_lesson_permalink' ), 10, 2 );
|
20 |
+
add_action( 'admin_init', array( $this, 'flush_rewrite_rules' ) );
|
21 |
|
22 |
/**
|
23 |
* Add Column
|
24 |
*/
|
25 |
|
26 |
+
add_filter( "manage_{$this->lesson_post_type}_posts_columns", array( $this, 'add_column' ), 10, 1 );
|
27 |
+
add_action( "manage_{$this->lesson_post_type}_posts_custom_column", array( $this, 'custom_lesson_column' ), 10, 2 );
|
28 |
|
29 |
+
// Frontend Action
|
30 |
+
add_action( 'template_redirect', array( $this, 'mark_lesson_complete' ) );
|
31 |
|
32 |
+
add_action( 'wp_ajax_tutor_render_lesson_content', array( $this, 'tutor_render_lesson_content' ) );
|
33 |
+
add_action( 'wp_ajax_nopriv_tutor_render_lesson_content', array( $this, 'tutor_render_lesson_content' ) ); // For public course access
|
34 |
|
35 |
/**
|
36 |
* Autoplay next video
|
37 |
+
*
|
38 |
* @since v.1.4.9
|
39 |
*/
|
40 |
+
add_action( 'wp_ajax_autoload_next_course_content', array( $this, 'autoload_next_course_content' ) );
|
41 |
|
42 |
/**
|
43 |
* Load next course item after click complete button
|
44 |
+
*
|
45 |
* @since v.1.5.3
|
46 |
*/
|
47 |
+
add_action( 'tutor_lesson_completed_after', array( $this, 'tutor_lesson_completed_after' ), 999 );
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
* Registering metabox
|
52 |
*/
|
53 |
+
public function register_meta_box() {
|
54 |
$lesson_post_type = $this->lesson_post_type;
|
55 |
|
56 |
+
add_meta_box( 'tutor-course-select', __( 'Select Course', 'tutor' ), array( $this, 'lesson_metabox' ), $lesson_post_type );
|
57 |
+
add_meta_box( 'tutor-lesson-videos', __( 'Lesson Video', 'tutor' ), array( $this, 'lesson_video_metabox' ), $lesson_post_type );
|
58 |
+
add_meta_box( 'tutor-lesson-attachments', __( 'Attachments', 'tutor' ), array( $this, 'lesson_attachments_metabox' ), $lesson_post_type );
|
59 |
}
|
60 |
|
61 |
+
public function lesson_metabox() {
|
62 |
+
include tutor()->path . 'views/metabox/lesson-metabox.php';
|
63 |
}
|
64 |
|
65 |
+
public function lesson_video_metabox() {
|
66 |
+
include tutor()->path . 'views/metabox/video-metabox.php';
|
67 |
}
|
68 |
|
69 |
+
public function lesson_attachments_metabox() {
|
70 |
+
include tutor()->path . 'views/metabox/lesson-attachments-metabox.php';
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
* @param $post_ID
|
75 |
*
|
76 |
* Saving lesson meta and assets
|
|
|
77 |
*/
|
78 |
+
public function save_lesson_meta( $post_ID ) {
|
79 |
+
// Course
|
80 |
+
if ( isset( $_POST['selected_course'] ) ) {
|
81 |
$course_id = (int) sanitize_text_field( $_POST['selected_course'] );
|
82 |
if ( $course_id ) {
|
83 |
update_post_meta( $post_ID, '_tutor_course_id_for_lesson', $course_id );
|
84 |
}
|
85 |
}
|
86 |
|
87 |
+
// Video
|
88 |
+
$video_source = sanitize_text_field( tutils()->array_get( 'video.source', $_POST ) );
|
89 |
+
if ( $video_source === '-1' ) {
|
90 |
+
delete_post_meta( $post_ID, '_video' );
|
91 |
+
} elseif ( $video_source ) {
|
92 |
+
$video = (array) tutor_utils()->array_get( 'video', tutor_sanitize_data($_POST), array() );
|
93 |
+
update_post_meta( $post_ID, '_video', $video );
|
94 |
}
|
95 |
|
96 |
+
// Attachments
|
97 |
$attachments = array();
|
98 |
+
if ( ! empty( $_POST['tutor_attachments'] ) ) {
|
99 |
+
$attachments = tutor_utils()->sanitize_array( $_POST['tutor_attachments'] );
|
100 |
+
$attachments = array_unique( $attachments );
|
101 |
+
}
|
102 |
|
103 |
/**
|
104 |
* it !empty attachment then update meta else
|
105 |
* delete meta key to prevetn empty data in db
|
106 |
+
*
|
107 |
* @since 1.8.9
|
108 |
*/
|
109 |
+
if ( ! empty( $attachments ) ) {
|
110 |
+
update_post_meta( $post_ID, '_tutor_attachments', $attachments );
|
111 |
} else {
|
112 |
+
delete_post_meta( $post_ID, '_tutor_attachments' );
|
113 |
}
|
114 |
+
|
115 |
}
|
116 |
|
117 |
+
public function tutor_load_edit_lesson_modal() {
|
118 |
tutils()->checking_nonce();
|
119 |
|
120 |
+
$lesson_id = (int) tutor_utils()->avalue_dot( 'lesson_id', tutor_sanitize_data($_POST) );
|
121 |
+
$topic_id = (int) sanitize_text_field( $_POST['topic_id'] );
|
122 |
|
123 |
+
if ( ! tutils()->can_user_manage( 'topic', $topic_id ) ) {
|
124 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
* If Lesson Not Exists, provide dummy
|
129 |
*/
|
130 |
$post_arr = array(
|
131 |
+
'ID' => 0,
|
132 |
'post_content' => '',
|
133 |
'post_type' => $this->lesson_post_type,
|
134 |
+
'post_title' => __( 'Draft Lesson', 'tutor' ),
|
135 |
'post_status' => 'publish',
|
136 |
'post_author' => get_current_user_id(),
|
137 |
'post_parent' => $topic_id,
|
138 |
);
|
139 |
|
140 |
+
$post = $lesson_id ? get_post( $lesson_id ) : (object) $post_arr;
|
141 |
+
|
142 |
ob_start();
|
143 |
+
include tutor()->path . 'views/modal/edit-lesson.php';
|
144 |
$output = ob_get_clean();
|
145 |
|
146 |
+
wp_send_json_success( array( 'output' => $output ) );
|
147 |
}
|
148 |
|
149 |
/**
|
150 |
* @since v.1.0.0
|
151 |
* @updated v.1.5.1
|
152 |
*/
|
153 |
+
public function tutor_modal_create_or_update_lesson() {
|
154 |
tutils()->checking_nonce();
|
155 |
|
156 |
global $wpdb;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
|
158 |
+
$lesson_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( 'lesson_id', $_POST ) );
|
159 |
+
$topic_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( 'current_topic_id', $_POST ) );
|
160 |
+
$course_id = tutor_utils()->get_course_id_by( 'topic', $topic_id );
|
161 |
+
$_lesson_thumbnail_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( '_lesson_thumbnail_id', $_POST ) );
|
162 |
+
|
163 |
+
if ( ! tutils()->can_user_manage( 'topic', $topic_id ) ) {
|
164 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
165 |
+
}
|
166 |
|
167 |
+
$title = sanitize_text_field( $_POST['lesson_title'] );
|
168 |
+
$lesson_content = wp_kses_post( $_POST['lesson_content'] );
|
169 |
|
170 |
$lesson_data = array(
|
171 |
'post_type' => $this->lesson_post_type,
|
172 |
'post_title' => $title,
|
173 |
+
'post_name' => sanitize_title( $title ),
|
174 |
'post_content' => $lesson_content,
|
175 |
'post_status' => 'publish',
|
176 |
'post_author' => get_current_user_id(),
|
177 |
+
'post_parent' => $topic_id,
|
178 |
);
|
179 |
|
180 |
+
if ( $lesson_id == 0 ) {
|
181 |
|
182 |
$lesson_data['menu_order'] = tutor_utils()->get_next_course_content_order_id( $topic_id );
|
183 |
+
$lesson_id = wp_insert_post( $lesson_data );
|
184 |
|
185 |
+
if ( $lesson_id ) {
|
186 |
+
do_action( 'tutor/lesson/created', $lesson_id );
|
187 |
update_post_meta( $lesson_id, '_tutor_course_id_for_lesson', $course_id );
|
188 |
} else {
|
189 |
+
wp_send_json_error( array( 'message' => __( 'Couldn\'t create lesson.', 'tutor' ) ) );
|
190 |
}
|
191 |
} else {
|
192 |
+
$lesson_data['ID'] = $lesson_id;
|
193 |
|
194 |
+
do_action( 'tutor/lesson_update/before', $lesson_id );
|
195 |
+
wp_update_post( $lesson_data );
|
196 |
+
if ( $_lesson_thumbnail_id ) {
|
197 |
+
update_post_meta( $lesson_id, '_thumbnail_id', $_lesson_thumbnail_id );
|
198 |
} else {
|
199 |
+
delete_post_meta( $lesson_id, '_thumbnail_id' );
|
200 |
}
|
201 |
+
do_action( 'tutor/lesson_update/after', $lesson_id );
|
202 |
}
|
203 |
+
|
204 |
ob_start();
|
205 |
+
include tutor()->path . 'views/metabox/course-contents.php';
|
206 |
$course_contents = ob_get_clean();
|
207 |
|
208 |
+
wp_send_json_success( array( 'course_contents' => $course_contents ) );
|
209 |
}
|
210 |
|
211 |
/**
|
212 |
* Delete Lesson from course builder
|
213 |
*/
|
214 |
+
public function tutor_delete_lesson_by_id() {
|
215 |
tutils()->checking_nonce();
|
216 |
|
217 |
+
$lesson_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( 'lesson_id', $_POST ) );
|
218 |
|
219 |
+
if ( ! tutils()->can_user_manage( 'lesson', $lesson_id ) ) {
|
220 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
221 |
}
|
222 |
|
223 |
+
wp_delete_post( $lesson_id, true );
|
224 |
+
delete_post_meta( $lesson_id, '_tutor_course_id_for_lesson' );
|
225 |
wp_send_json_success();
|
226 |
}
|
227 |
|
235 |
* Changed the URI based
|
236 |
*/
|
237 |
|
238 |
+
public function change_lesson_permalink( $uri, $lesson_id ) {
|
239 |
+
$post = get_post( $lesson_id );
|
240 |
|
241 |
+
if ( $post && $post->post_type === $this->lesson_post_type ) {
|
242 |
+
$uri_base = trailingslashit( site_url() );
|
243 |
|
244 |
+
$sample_course = 'sample-course';
|
245 |
+
$is_course = tutor_utils()->get_course_id_by( 'lesson', get_the_ID() );
|
246 |
+
if ( $is_course ) {
|
247 |
+
$course = get_post( $is_course );
|
248 |
+
if ( $course ) {
|
249 |
$sample_course = $course->post_name;
|
250 |
}
|
251 |
}
|
252 |
|
253 |
+
$new_course_base = $uri_base . "course/{$sample_course}/lesson/%pagename%/";
|
254 |
+
$uri[0] = $new_course_base;
|
255 |
}
|
256 |
|
257 |
return $uri;
|
258 |
}
|
259 |
|
260 |
|
261 |
+
public function flush_rewrite_rules() {
|
262 |
+
$is_required_flush = get_option( 'required_rewrite_flush' );
|
263 |
+
if ( $is_required_flush ) {
|
264 |
flush_rewrite_rules();
|
265 |
delete_option( 'required_rewrite_flush' );
|
266 |
}
|
267 |
}
|
268 |
|
269 |
|
270 |
+
public function add_column( $columns ) {
|
271 |
$date_col = $columns['date'];
|
272 |
+
unset( $columns['date'] );
|
273 |
+
$columns['course'] = __( 'Course', 'tutor' );
|
274 |
+
$columns['date'] = $date_col;
|
275 |
|
276 |
return $columns;
|
277 |
}
|
279 |
/**
|
280 |
* @param $column
|
281 |
* @param $post_id
|
|
|
282 |
*/
|
283 |
+
public function custom_lesson_column( $column, $post_id ) {
|
284 |
+
if ( $column === 'course' ) {
|
285 |
|
286 |
+
$course_id = tutor_utils()->get_course_id_by( 'lesson', $post_id );
|
287 |
+
if ( $course_id ) {
|
288 |
+
echo '<a href="' . admin_url( 'post.php?post=' . $course_id . '&action=edit' ) . '">' . get_the_title( $course_id ) . '</a>';
|
289 |
}
|
|
|
290 |
}
|
291 |
}
|
292 |
|
296 |
*
|
297 |
* @since v.1.0.0
|
298 |
*/
|
299 |
+
public function mark_lesson_complete() {
|
300 |
+
if ( ! isset( $_POST['tutor_action'] ) || $_POST['tutor_action'] !== 'tutor_complete_lesson' ) {
|
301 |
return;
|
302 |
}
|
303 |
+
// Checking nonce
|
304 |
tutor_utils()->checking_nonce();
|
305 |
|
306 |
$user_id = get_current_user_id();
|
307 |
|
308 |
+
// TODO: need to show view if not signed_in
|
309 |
+
if ( ! $user_id ) {
|
310 |
+
die( __( 'Please Sign-In', 'tutor' ) );
|
311 |
}
|
312 |
|
313 |
+
$lesson_id = (int) sanitize_text_field( $_POST['lesson_id'] );
|
314 |
|
315 |
+
do_action( 'tutor_lesson_completed_before', $lesson_id );
|
316 |
/**
|
317 |
* Marking lesson at user meta, meta format, _tutor_completed_lesson_id_{id} and value = tutor_time();
|
318 |
*/
|
319 |
+
tutor_utils()->mark_lesson_complete( $lesson_id );
|
320 |
|
321 |
+
do_action( 'tutor_lesson_completed_after', $lesson_id, $user_id );
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
* Render the lesson content
|
326 |
*/
|
327 |
+
public function tutor_render_lesson_content() {
|
328 |
tutils()->checking_nonce();
|
329 |
|
330 |
+
$lesson_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( 'lesson_id', $_POST ) );
|
331 |
|
332 |
+
$ancestors = get_post_ancestors( $lesson_id );
|
333 |
+
$course_id = ! empty( $ancestors ) ? array_pop( $ancestors ) : $lesson_id;
|
334 |
|
335 |
// Course must be public or current user must be enrolled to access this lesson
|
336 |
+
if ( get_post_meta( $course_id, '_tutor_is_public_course', true ) !== 'yes' && ! tutils()->is_enrolled( $course_id ) ) {
|
337 |
+
|
338 |
+
$is_admin = tutor_utils()->has_user_role( 'administrator' );
|
339 |
+
$allowed = $is_admin ? true : tutor_utils()->is_instructor_of_this_course( get_current_user_id(), $course_id );
|
340 |
|
341 |
+
if ( ! $allowed ) {
|
342 |
+
http_response_code( 400 );
|
343 |
exit;
|
344 |
}
|
345 |
}
|
347 |
ob_start();
|
348 |
global $post;
|
349 |
|
350 |
+
$post = get_post( $lesson_id );
|
351 |
+
setup_postdata( $post );
|
352 |
tutor_lesson_content();
|
353 |
wp_reset_postdata();
|
354 |
|
355 |
$html = ob_get_clean();
|
356 |
+
wp_send_json_success( array( 'html' => $html ) );
|
357 |
}
|
358 |
|
359 |
/**
|
361 |
*
|
362 |
* @since v.1.4.9
|
363 |
*/
|
364 |
+
public function autoload_next_course_content() {
|
365 |
tutor_utils()->checking_nonce();
|
366 |
|
367 |
+
$post_id = sanitize_text_field( $_POST['post_id'] );
|
368 |
+
$content_id = tutils()->get_post_id( $post_id );
|
369 |
+
$contents = tutor_utils()->get_course_prev_next_contents_by_id( $content_id );
|
370 |
|
371 |
+
$autoload_course_content = (bool) get_tutor_option( 'autoload_next_course_content' );
|
372 |
+
$next_url = false;
|
373 |
+
if ( $autoload_course_content ) {
|
374 |
+
$next_url = get_the_permalink( $contents->next_id );
|
375 |
}
|
376 |
+
wp_send_json_success( array( 'next_url' => $next_url ) );
|
377 |
}
|
378 |
|
379 |
/**
|
381 |
*
|
382 |
* @since v.1.5.3
|
383 |
*/
|
384 |
+
public function tutor_lesson_completed_after( $content_id ) {
|
385 |
+
$contents = tutor_utils()->get_course_prev_next_contents_by_id( $content_id );
|
386 |
+
$autoload_course_content = (bool) get_tutor_option( 'autoload_next_course_content' );
|
387 |
+
if ( $autoload_course_content ) {
|
388 |
+
wp_redirect( get_the_permalink( $contents->next_id ) );
|
389 |
} else {
|
390 |
+
wp_redirect( get_the_permalink( $content_id ) );
|
391 |
}
|
392 |
die();
|
393 |
}
|
classes/Options.php
CHANGED
@@ -59,8 +59,9 @@ class Options {
|
|
59 |
|
60 |
do_action('tutor_option_save_before');
|
61 |
|
62 |
-
$option = (array)tutils()->array_get('tutor_option', $_POST, array());
|
63 |
-
|
|
|
64 |
foreach ( $option as $key => $value ) {
|
65 |
if ( 'login_error_message' === $key ) {
|
66 |
$option['login_error_message'] = $this->tutor_sanitize_settings_options( 'login_error_message' );
|
@@ -74,9 +75,9 @@ class Options {
|
|
74 |
$option['email_from_address'] = $this->tutor_sanitize_settings_options( 'email_from_address' );
|
75 |
}
|
76 |
}
|
77 |
-
|
78 |
$option = apply_filters('tutor_option_input', $option);
|
79 |
-
|
80 |
update_option('tutor_option', $option);
|
81 |
|
82 |
do_action('tutor_option_save_after');
|
@@ -93,7 +94,7 @@ class Options {
|
|
93 |
$lesson_sample_url_text = __( "/course/sample-course/<code>lessons</code>/sample-lesson/", 'tutor' );
|
94 |
$lesson_url = site_url().$lesson_sample_url_text;
|
95 |
|
96 |
-
$student_url = site_url().'/'._x( 'profile', 'tutor student profile', 'tutor' ).'/'.$current_user->display_name ;
|
97 |
|
98 |
$attempts_allowed = array();
|
99 |
$attempts_allowed['unlimited'] = __('Unlimited' , 'tutor');
|
@@ -740,13 +741,13 @@ class Options {
|
|
740 |
'default' => '',
|
741 |
),
|
742 |
//tutor button style options
|
743 |
-
|
744 |
'tutor_button_primary' => array(
|
745 |
'type' => 'color',
|
746 |
'label' => __('Button Primary Color','tutor'),
|
747 |
'default' => ''
|
748 |
-
),
|
749 |
-
|
750 |
'tutor_button_danger' => array(
|
751 |
'type' => 'color',
|
752 |
'label' => __('Button Danger Color','tutor'),
|
@@ -821,13 +822,13 @@ class Options {
|
|
821 |
public function generate_field($field = array()){
|
822 |
ob_start();
|
823 |
include tutor()->path.'views/options/option_field.php';
|
824 |
-
|
825 |
}
|
826 |
|
827 |
public function field_type($field = array()){
|
828 |
ob_start();
|
829 |
-
include tutor()->path.
|
830 |
-
|
831 |
}
|
832 |
|
833 |
public function generate(){
|
59 |
|
60 |
do_action('tutor_option_save_before');
|
61 |
|
62 |
+
$option = (array) tutils()->array_get('tutor_option', $_POST, array());
|
63 |
+
$option = tutor_sanitize_data($option);
|
64 |
+
|
65 |
foreach ( $option as $key => $value ) {
|
66 |
if ( 'login_error_message' === $key ) {
|
67 |
$option['login_error_message'] = $this->tutor_sanitize_settings_options( 'login_error_message' );
|
75 |
$option['email_from_address'] = $this->tutor_sanitize_settings_options( 'email_from_address' );
|
76 |
}
|
77 |
}
|
78 |
+
|
79 |
$option = apply_filters('tutor_option_input', $option);
|
80 |
+
|
81 |
update_option('tutor_option', $option);
|
82 |
|
83 |
do_action('tutor_option_save_after');
|
94 |
$lesson_sample_url_text = __( "/course/sample-course/<code>lessons</code>/sample-lesson/", 'tutor' );
|
95 |
$lesson_url = site_url().$lesson_sample_url_text;
|
96 |
|
97 |
+
$student_url = site_url().'/'._x( 'profile', 'tutor student profile', 'tutor' ).'/'.$current_user->display_name ;
|
98 |
|
99 |
$attempts_allowed = array();
|
100 |
$attempts_allowed['unlimited'] = __('Unlimited' , 'tutor');
|
741 |
'default' => '',
|
742 |
),
|
743 |
//tutor button style options
|
744 |
+
|
745 |
'tutor_button_primary' => array(
|
746 |
'type' => 'color',
|
747 |
'label' => __('Button Primary Color','tutor'),
|
748 |
'default' => ''
|
749 |
+
),
|
750 |
+
|
751 |
'tutor_button_danger' => array(
|
752 |
'type' => 'color',
|
753 |
'label' => __('Button Danger Color','tutor'),
|
822 |
public function generate_field($field = array()){
|
823 |
ob_start();
|
824 |
include tutor()->path.'views/options/option_field.php';
|
825 |
+
echo ob_get_clean();
|
826 |
}
|
827 |
|
828 |
public function field_type($field = array()){
|
829 |
ob_start();
|
830 |
+
include tutor()->path.'views/options/field-types/'.$field['type'].'.php';
|
831 |
+
echo ob_get_clean();
|
832 |
}
|
833 |
|
834 |
public function generate(){
|
classes/Post_types.php
CHANGED
@@ -4,14 +4,14 @@ if ( ! defined( 'ABSPATH' ) )
|
|
4 |
exit;
|
5 |
|
6 |
class Post_types{
|
7 |
-
|
8 |
public $course_post_type;
|
9 |
public $lesson_post_type;
|
10 |
|
11 |
public function __construct() {
|
12 |
$this->course_post_type = tutor()->course_post_type;
|
13 |
$this->lesson_post_type = tutor()->lesson_post_type;
|
14 |
-
|
15 |
add_action( 'init', array($this, 'register_course_post_types') );
|
16 |
add_action( 'init', array($this, 'register_lesson_post_types') );
|
17 |
add_action( 'init', array($this, 'register_quiz_post_types') );
|
@@ -31,7 +31,7 @@ class Post_types{
|
|
31 |
*/
|
32 |
add_action( 'init', array($this, 'register_tutor_enrolled_post_types') );
|
33 |
}
|
34 |
-
|
35 |
public function register_course_post_types() {
|
36 |
$course_post_type = $this->course_post_type;
|
37 |
$courses_base_slug = apply_filters('tutor_courses_base_slug', $course_post_type);
|
@@ -207,7 +207,7 @@ class Post_types{
|
|
207 |
|
208 |
register_post_type($lesson_post_type, $args );
|
209 |
}
|
210 |
-
|
211 |
public function register_quiz_post_types() {
|
212 |
$labels = array(
|
213 |
'name' => _x( 'Quizzes', 'post type general name', 'tutor' ),
|
@@ -327,7 +327,7 @@ class Post_types{
|
|
327 |
$post = get_post();
|
328 |
$post_type = get_post_type( $post );
|
329 |
$post_type_object = get_post_type_object( $post_type );
|
330 |
-
|
331 |
$course_post_type = tutor()->course_post_type;
|
332 |
|
333 |
$messages[$course_post_type] = array(
|
@@ -337,7 +337,7 @@ class Post_types{
|
|
337 |
3 => __( 'Custom field deleted.', 'tutor' ),
|
338 |
4 => __( 'Course updated.', 'tutor' ),
|
339 |
/* translators: %s: date and time of the revision */
|
340 |
-
5 => isset( $_GET['revision'] ) ? sprintf( __( 'Course restored to revision from %s', 'tutor' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
|
341 |
6 => __( 'Course published.', 'tutor' ),
|
342 |
7 => __( 'Course saved.', 'tutor' ),
|
343 |
8 => __( 'Course submitted.', 'tutor' ),
|
4 |
exit;
|
5 |
|
6 |
class Post_types{
|
7 |
+
|
8 |
public $course_post_type;
|
9 |
public $lesson_post_type;
|
10 |
|
11 |
public function __construct() {
|
12 |
$this->course_post_type = tutor()->course_post_type;
|
13 |
$this->lesson_post_type = tutor()->lesson_post_type;
|
14 |
+
|
15 |
add_action( 'init', array($this, 'register_course_post_types') );
|
16 |
add_action( 'init', array($this, 'register_lesson_post_types') );
|
17 |
add_action( 'init', array($this, 'register_quiz_post_types') );
|
31 |
*/
|
32 |
add_action( 'init', array($this, 'register_tutor_enrolled_post_types') );
|
33 |
}
|
34 |
+
|
35 |
public function register_course_post_types() {
|
36 |
$course_post_type = $this->course_post_type;
|
37 |
$courses_base_slug = apply_filters('tutor_courses_base_slug', $course_post_type);
|
207 |
|
208 |
register_post_type($lesson_post_type, $args );
|
209 |
}
|
210 |
+
|
211 |
public function register_quiz_post_types() {
|
212 |
$labels = array(
|
213 |
'name' => _x( 'Quizzes', 'post type general name', 'tutor' ),
|
327 |
$post = get_post();
|
328 |
$post_type = get_post_type( $post );
|
329 |
$post_type_object = get_post_type_object( $post_type );
|
330 |
+
|
331 |
$course_post_type = tutor()->course_post_type;
|
332 |
|
333 |
$messages[$course_post_type] = array(
|
337 |
3 => __( 'Custom field deleted.', 'tutor' ),
|
338 |
4 => __( 'Course updated.', 'tutor' ),
|
339 |
/* translators: %s: date and time of the revision */
|
340 |
+
5 => isset( $_GET['revision'] ) ? sprintf( __( 'Course restored to revision from %s', 'tutor' ), wp_post_revision_title( (int) tutor_sanitize_data($_GET['revision']), false ) ) : false,
|
341 |
6 => __( 'Course published.', 'tutor' ),
|
342 |
7 => __( 'Course saved.', 'tutor' ),
|
343 |
8 => __( 'Course submitted.', 'tutor' ),
|
classes/Question_Answers_List.php
CHANGED
@@ -1,93 +1,96 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
if (! class_exists('Tutor_List_Table')){
|
8 |
-
include_once tutor()->path.'classes/Tutor_List_Table.php';
|
9 |
}
|
10 |
|
11 |
class Question_Answers_List extends \Tutor_List_Table {
|
12 |
|
13 |
const Question_Answer_PAGE = 'question_answer';
|
14 |
|
15 |
-
function __construct(){
|
16 |
global $status, $page;
|
17 |
|
18 |
-
//Set parent defaults
|
19 |
-
parent::__construct(
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
24 |
}
|
25 |
|
26 |
-
function column_default($item, $column_name){
|
27 |
-
switch($column_name){
|
28 |
case 'user_email':
|
29 |
case 'display_name':
|
30 |
case 'post_title':
|
31 |
case 'answer_count':
|
32 |
return $item->$column_name;
|
33 |
default:
|
34 |
-
return print_r($item,true); //Show the whole array for troubleshooting purposes
|
35 |
}
|
36 |
}
|
37 |
|
38 |
-
function column_question($item){
|
39 |
-
//Build row actions
|
40 |
$actions = array(
|
41 |
-
//'edit' => sprintf('<a href="?page=%s&action=%s&instructor=%s">Edit</a>',$_REQUEST['page'],'edit',$item->comment_ID),
|
42 |
-
//'delete' => sprintf('<a href="?page=%s&action=%s&instructor=%s">Delete</a>',$_REQUEST['page'],'delete',$item->comment_ID),
|
43 |
);
|
44 |
$answer_action_text = __( 'Answer', 'tutor' );
|
45 |
|
46 |
-
$actions['answer'] = sprintf('<a href="?page=%s&sub_page=%s&question_id=%s">'
|
47 |
-
|
48 |
|
49 |
-
//Return the title contents
|
50 |
-
return sprintf(
|
51 |
-
|
|
|
52 |
$item->comment_ID,
|
53 |
-
$this->row_actions($actions)
|
54 |
);
|
55 |
}
|
56 |
|
57 |
-
function column_cb($item){
|
58 |
return sprintf(
|
59 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
60 |
-
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label ("instructor")
|
61 |
-
/*$2%s*/ $item->comment_ID //The value of the checkbox should be the record's id
|
62 |
);
|
63 |
}
|
64 |
|
65 |
-
function column_course($item) {
|
66 |
|
67 |
return $item->comment_ID;
|
68 |
}
|
69 |
|
70 |
-
function get_columns(){
|
71 |
$columns = array(
|
72 |
-
'cb'
|
73 |
-
'question'
|
74 |
-
'display_name'
|
75 |
-
'post_title'
|
76 |
-
'answer_count'
|
77 |
);
|
78 |
return $columns;
|
79 |
}
|
80 |
|
81 |
function get_sortable_columns() {
|
82 |
$sortable_columns = array(
|
83 |
-
//'display_name' => array('title',false), //true means it's already sorted
|
84 |
);
|
85 |
return $sortable_columns;
|
86 |
}
|
87 |
|
88 |
function get_bulk_actions() {
|
89 |
$actions = array(
|
90 |
-
'delete'
|
91 |
);
|
92 |
return $actions;
|
93 |
}
|
@@ -95,16 +98,16 @@ class Question_Answers_List extends \Tutor_List_Table {
|
|
95 |
function process_bulk_action() {
|
96 |
global $wpdb;
|
97 |
|
98 |
-
//Detect when a bulk action is being triggered...
|
99 |
-
if( 'delete' === $this->current_action() ) {
|
100 |
-
if ( empty($_GET['question']) || ! is_array($_GET['question'])){
|
101 |
return;
|
102 |
}
|
103 |
|
104 |
-
$question_ids = array_map('sanitize_text_field', $_GET['question']);
|
105 |
$question_ids = implode( ',', array_map( 'absint', $question_ids ) );
|
106 |
|
107 |
-
//Deleting question (comment), child question and question meta (comment meta)
|
108 |
$wpdb->query( "DELETE FROM {$wpdb->comments} WHERE {$wpdb->comments}.comment_ID IN($question_ids)" );
|
109 |
$wpdb->query( "DELETE FROM {$wpdb->comments} WHERE {$wpdb->comments}.comment_parent IN($question_ids)" );
|
110 |
$wpdb->query( "DELETE FROM {$wpdb->commentmeta} WHERE {$wpdb->commentmeta}.comment_id IN($question_ids)" );
|
@@ -115,26 +118,28 @@ class Question_Answers_List extends \Tutor_List_Table {
|
|
115 |
$per_page = 20;
|
116 |
|
117 |
$search_term = '';
|
118 |
-
if (isset($_REQUEST['s'])){
|
119 |
-
$search_term = sanitize_text_field($_REQUEST['s']);
|
120 |
}
|
121 |
|
122 |
-
$columns
|
123 |
-
$hidden
|
124 |
$sortable = $this->get_sortable_columns();
|
125 |
|
126 |
-
$this->_column_headers = array($columns, $hidden, $sortable);
|
127 |
$this->process_bulk_action();
|
128 |
|
129 |
$current_page = $this->get_pagenum();
|
130 |
|
131 |
-
$total_items = tutor_utils()->get_total_qa_question($search_term);
|
132 |
-
$this->items = tutor_utils()->get_qa_questions(($current_page-1)
|
133 |
|
134 |
-
$this->set_pagination_args(
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
|
|
|
|
139 |
}
|
140 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
if ( ! class_exists( 'Tutor_List_Table' ) ) {
|
9 |
+
include_once tutor()->path . 'classes/Tutor_List_Table.php';
|
10 |
}
|
11 |
|
12 |
class Question_Answers_List extends \Tutor_List_Table {
|
13 |
|
14 |
const Question_Answer_PAGE = 'question_answer';
|
15 |
|
16 |
+
function __construct() {
|
17 |
global $status, $page;
|
18 |
|
19 |
+
// Set parent defaults
|
20 |
+
parent::__construct(
|
21 |
+
array(
|
22 |
+
'singular' => 'question', // singular name of the listed records
|
23 |
+
'plural' => 'questions', // plural name of the listed records
|
24 |
+
'ajax' => false, // does this table support ajax?
|
25 |
+
)
|
26 |
+
);
|
27 |
}
|
28 |
|
29 |
+
function column_default( $item, $column_name ) {
|
30 |
+
switch ( $column_name ) {
|
31 |
case 'user_email':
|
32 |
case 'display_name':
|
33 |
case 'post_title':
|
34 |
case 'answer_count':
|
35 |
return $item->$column_name;
|
36 |
default:
|
37 |
+
return print_r( $item, true ); // Show the whole array for troubleshooting purposes
|
38 |
}
|
39 |
}
|
40 |
|
41 |
+
function column_question( $item ) {
|
42 |
+
// Build row actions
|
43 |
$actions = array(
|
44 |
+
// 'edit' => sprintf('<a href="?page=%s&action=%s&instructor=%s">Edit</a>',$_REQUEST['page'],'edit',$item->comment_ID),
|
45 |
+
// 'delete' => sprintf('<a href="?page=%s&action=%s&instructor=%s">Delete</a>',$_REQUEST['page'],'delete',$item->comment_ID),
|
46 |
);
|
47 |
$answer_action_text = __( 'Answer', 'tutor' );
|
48 |
|
49 |
+
$actions['answer'] = sprintf( '<a href="?page=%s&sub_page=%s&question_id=%s">' . $answer_action_text . '</a>', $_REQUEST['page'], 'answer', $item->comment_ID );
|
|
|
50 |
|
51 |
+
// Return the title contents
|
52 |
+
return sprintf(
|
53 |
+
'%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
|
54 |
+
wp_kses_post( stripslashes( $item->comment_content ) ),
|
55 |
$item->comment_ID,
|
56 |
+
$this->row_actions( $actions )
|
57 |
);
|
58 |
}
|
59 |
|
60 |
+
function column_cb( $item ) {
|
61 |
return sprintf(
|
62 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
63 |
+
/*$1%s*/ $this->_args['singular'], // Let's simply repurpose the table's singular label ("instructor")
|
64 |
+
/*$2%s*/ $item->comment_ID // The value of the checkbox should be the record's id
|
65 |
);
|
66 |
}
|
67 |
|
68 |
+
function column_course( $item ) {
|
69 |
|
70 |
return $item->comment_ID;
|
71 |
}
|
72 |
|
73 |
+
function get_columns() {
|
74 |
$columns = array(
|
75 |
+
'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
|
76 |
+
'question' => __( 'Question', 'tutor' ),
|
77 |
+
'display_name' => __( 'Student', 'tutor' ),
|
78 |
+
'post_title' => __( 'Course', 'tutor' ),
|
79 |
+
'answer_count' => __( 'Answer', 'tutor' ),
|
80 |
);
|
81 |
return $columns;
|
82 |
}
|
83 |
|
84 |
function get_sortable_columns() {
|
85 |
$sortable_columns = array(
|
86 |
+
// 'display_name' => array('title',false), //true means it's already sorted
|
87 |
);
|
88 |
return $sortable_columns;
|
89 |
}
|
90 |
|
91 |
function get_bulk_actions() {
|
92 |
$actions = array(
|
93 |
+
'delete' => 'Delete',
|
94 |
);
|
95 |
return $actions;
|
96 |
}
|
98 |
function process_bulk_action() {
|
99 |
global $wpdb;
|
100 |
|
101 |
+
// Detect when a bulk action is being triggered...
|
102 |
+
if ( 'delete' === $this->current_action() ) {
|
103 |
+
if ( empty( $_GET['question'] ) || ! is_array( $_GET['question'] ) ) {
|
104 |
return;
|
105 |
}
|
106 |
|
107 |
+
$question_ids = array_map( 'sanitize_text_field', $_GET['question'] );
|
108 |
$question_ids = implode( ',', array_map( 'absint', $question_ids ) );
|
109 |
|
110 |
+
// Deleting question (comment), child question and question meta (comment meta)
|
111 |
$wpdb->query( "DELETE FROM {$wpdb->comments} WHERE {$wpdb->comments}.comment_ID IN($question_ids)" );
|
112 |
$wpdb->query( "DELETE FROM {$wpdb->comments} WHERE {$wpdb->comments}.comment_parent IN($question_ids)" );
|
113 |
$wpdb->query( "DELETE FROM {$wpdb->commentmeta} WHERE {$wpdb->commentmeta}.comment_id IN($question_ids)" );
|
118 |
$per_page = 20;
|
119 |
|
120 |
$search_term = '';
|
121 |
+
if ( isset( $_REQUEST['s'] ) ) {
|
122 |
+
$search_term = sanitize_text_field( $_REQUEST['s'] );
|
123 |
}
|
124 |
|
125 |
+
$columns = $this->get_columns();
|
126 |
+
$hidden = array();
|
127 |
$sortable = $this->get_sortable_columns();
|
128 |
|
129 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
130 |
$this->process_bulk_action();
|
131 |
|
132 |
$current_page = $this->get_pagenum();
|
133 |
|
134 |
+
$total_items = tutor_utils()->get_total_qa_question( $search_term );
|
135 |
+
$this->items = tutor_utils()->get_qa_questions( ( $current_page - 1 ) * $per_page, $per_page, $search_term );
|
136 |
|
137 |
+
$this->set_pagination_args(
|
138 |
+
array(
|
139 |
+
'total_items' => $total_items,
|
140 |
+
'per_page' => $per_page,
|
141 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
142 |
+
)
|
143 |
+
);
|
144 |
}
|
145 |
+
}
|
classes/Quiz.php
CHANGED
@@ -11,192 +11,193 @@
|
|
11 |
|
12 |
namespace TUTOR;
|
13 |
|
14 |
-
if ( ! defined( 'ABSPATH' ) )
|
15 |
exit;
|
|
|
16 |
|
17 |
class Quiz {
|
18 |
|
19 |
-
private $allowed_attributes = array(
|
20 |
-
'src'
|
21 |
-
'style' => array(),
|
22 |
-
'class' => array(),
|
23 |
-
'id'
|
24 |
-
'href'
|
25 |
-
'alt'
|
26 |
'title' => array(),
|
27 |
'type' => array(),
|
28 |
'controls' => array(),
|
29 |
'muted' => array(),
|
30 |
-
'loop'
|
31 |
'poster' => array(),
|
32 |
'preload' => array(),
|
33 |
'autoplay' => array(),
|
34 |
'width' => array(),
|
35 |
-
'height' => array()
|
36 |
);
|
37 |
-
|
38 |
private $allowed_html = array( 'img', 'b', 'i', 'br', 'a', 'audio', 'video', 'source' );
|
39 |
|
40 |
public function __construct() {
|
41 |
-
|
42 |
-
add_action('save_post_tutor_quiz', array($this, 'save_quiz_meta'));
|
43 |
|
44 |
-
add_action('
|
45 |
-
|
|
|
|
|
46 |
|
47 |
-
add_action('wp_ajax_tutor_quiz_timeout', array($this, 'tutor_quiz_timeout'));
|
48 |
|
49 |
-
//User take the quiz
|
50 |
-
add_action('template_redirect', array($this, 'start_the_quiz'));
|
51 |
-
add_action('template_redirect', array($this, 'answering_quiz'));
|
52 |
-
add_action('template_redirect', array($this, 'finishing_quiz_attempt'));
|
53 |
|
54 |
-
add_action('admin_action_review_quiz_answer', array($this, 'review_quiz_answer'));
|
55 |
-
add_action('wp_ajax_review_quiz_answer', array($this, 'review_quiz_answer'));
|
56 |
-
add_action('wp_ajax_tutor_instructor_feedback', array($this, 'tutor_instructor_feedback')); // Instructor Feedback Action
|
57 |
|
58 |
/**
|
59 |
* New Design Quiz
|
60 |
*/
|
61 |
|
62 |
-
add_action('wp_ajax_tutor_create_quiz_and_load_modal', array($this, 'tutor_create_quiz_and_load_modal'));
|
63 |
-
add_action('wp_ajax_tutor_delete_quiz_by_id', array($this, 'tutor_delete_quiz_by_id'));
|
64 |
-
add_action('wp_ajax_tutor_quiz_builder_quiz_update', array($this, 'tutor_quiz_builder_quiz_update'));
|
65 |
-
add_action('wp_ajax_tutor_load_edit_quiz_modal', array($this, 'tutor_load_edit_quiz_modal'));
|
66 |
-
add_action('wp_ajax_tutor_quiz_builder_get_question_form', array($this, 'tutor_quiz_builder_get_question_form'));
|
67 |
-
add_action('wp_ajax_tutor_quiz_modal_update_question', array($this, 'tutor_quiz_modal_update_question'));
|
68 |
-
add_action('wp_ajax_tutor_quiz_builder_question_delete', array($this, 'tutor_quiz_builder_question_delete'));
|
69 |
-
add_action('wp_ajax_tutor_quiz_add_question_answers', array($this, 'tutor_quiz_add_question_answers'));
|
70 |
-
add_action('wp_ajax_tutor_quiz_edit_question_answer', array($this, 'tutor_quiz_edit_question_answer'));
|
71 |
-
add_action('wp_ajax_tutor_save_quiz_answer_options', array($this, 'tutor_save_quiz_answer_options'));
|
72 |
-
add_action('wp_ajax_tutor_update_quiz_answer_options', array($this, 'tutor_update_quiz_answer_options'));
|
73 |
-
add_action('wp_ajax_tutor_quiz_builder_get_answers_by_question', array($this, 'tutor_quiz_builder_get_answers_by_question'));
|
74 |
-
add_action('wp_ajax_tutor_quiz_builder_delete_answer', array($this, 'tutor_quiz_builder_delete_answer'));
|
75 |
-
add_action('wp_ajax_tutor_quiz_question_sorting', array($this, 'tutor_quiz_question_sorting'));
|
76 |
-
add_action('wp_ajax_tutor_quiz_answer_sorting', array($this, 'tutor_quiz_answer_sorting'));
|
77 |
-
add_action('wp_ajax_tutor_mark_answer_as_correct', array($this, 'tutor_mark_answer_as_correct'));
|
78 |
-
add_action('wp_ajax_tutor_quiz_modal_update_settings', array($this, 'tutor_quiz_modal_update_settings'));
|
79 |
|
80 |
/**
|
81 |
-
|
82 |
-
|
83 |
-
add_action('wp_ajax_tutor_render_quiz_content', array($this, 'tutor_render_quiz_content'));
|
84 |
|
85 |
/**
|
86 |
* Quiz abandon action
|
87 |
-
*
|
88 |
* @since 1.9.6
|
89 |
*/
|
90 |
-
add_action('wp_ajax_tutor_quiz_abandon', array($this, 'tutor_quiz_abandon'));
|
91 |
|
92 |
$this->prepare_allowed_html();
|
93 |
}
|
94 |
|
95 |
private function prepare_allowed_html() {
|
96 |
-
|
97 |
$allowed = array();
|
98 |
|
99 |
-
foreach($this->allowed_html as $tag) {
|
100 |
-
$allowed[$tag] = $this->allowed_attributes;
|
101 |
}
|
102 |
|
103 |
$this->allowed_html = $allowed;
|
104 |
}
|
105 |
|
106 |
-
public function tutor_instructor_feedback(){
|
107 |
tutils()->checking_nonce();
|
108 |
|
109 |
-
$feedback
|
110 |
-
$attempt_id = (int) tutor_utils()->avalue_dot('attempts_id', $_POST);
|
111 |
|
112 |
-
if ($attempt_id && tutils()->can_user_manage('attempt', $attempt_id)) {
|
113 |
-
update_post_meta($attempt_id, 'instructor_feedback', $feedback);
|
114 |
-
do_action('tutor_quiz/attempt/submitted/feedback', $attempt_id);
|
115 |
|
116 |
-
wp_send_json_success(
|
117 |
}
|
118 |
}
|
119 |
|
120 |
-
public function save_quiz_meta($post_ID){
|
121 |
-
if (isset($_POST['quiz_option'])){
|
122 |
-
$quiz_option = tutor_utils()->sanitize_array($_POST['quiz_option']);
|
123 |
-
update_post_meta($post_ID, 'tutor_quiz_option', $quiz_option);
|
124 |
}
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
* Tutor Quiz Builder Modal
|
129 |
*/
|
130 |
-
public function tutor_load_quiz_builder_modal(){
|
131 |
tutils()->checking_nonce();
|
132 |
|
133 |
ob_start();
|
134 |
-
include
|
135 |
$output = ob_get_clean();
|
136 |
|
137 |
-
wp_send_json_success(array('output' => $output));
|
138 |
}
|
139 |
|
140 |
-
public function remove_quiz_from_post(){
|
141 |
tutils()->checking_nonce();
|
142 |
|
143 |
global $wpdb;
|
144 |
-
$quiz_id = (int) tutor_utils()->avalue_dot('quiz_id', $_POST);
|
145 |
|
146 |
-
if(!tutils()->can_user_manage('quiz', $quiz_id)) {
|
147 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
148 |
}
|
149 |
|
150 |
-
$wpdb->update($wpdb->posts, array('post_parent' => 0), array('ID' => $quiz_id) );
|
151 |
wp_send_json_success();
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
*
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
*/
|
160 |
|
161 |
-
public function start_the_quiz(){
|
162 |
-
if ( ! isset($_POST['tutor_action'])
|
163 |
return;
|
164 |
}
|
165 |
-
//Checking nonce
|
166 |
tutor_utils()->checking_nonce();
|
167 |
|
168 |
-
if ( ! is_user_logged_in()){
|
169 |
-
//TODO: need to set a view in the next version
|
170 |
-
die('Please sign in to do this operation');
|
171 |
}
|
172 |
|
173 |
global $wpdb;
|
174 |
|
175 |
$user_id = get_current_user_id();
|
176 |
-
$user
|
177 |
|
178 |
-
$quiz_id = (int) sanitize_text_field($_POST['quiz_id']);
|
179 |
|
180 |
-
$quiz
|
181 |
-
$course = tutor_utils()->get_course_by_quiz($quiz_id);
|
182 |
-
if ( empty($course->ID)){
|
183 |
-
|
184 |
-
|
185 |
|
186 |
-
|
187 |
|
188 |
-
$date = date(
|
189 |
|
190 |
-
$tutor_quiz_option = (array) maybe_unserialize(get_post_meta($quiz_id, 'tutor_quiz_option', true));
|
191 |
-
$attempts_allowed
|
192 |
|
193 |
-
$time_limit
|
194 |
$time_limit_seconds = 0;
|
195 |
-
$time_type
|
196 |
-
if ($time_limit){
|
197 |
-
$time_type = tutor_utils()->get_quiz_option($quiz_id, 'time_limit.time_type');
|
198 |
|
199 |
-
switch ($time_type){
|
200 |
case 'seconds':
|
201 |
$time_limit_seconds = $time_limit;
|
202 |
break;
|
@@ -215,54 +216,54 @@ class Quiz {
|
|
215 |
}
|
216 |
}
|
217 |
|
218 |
-
$max_question_allowed
|
219 |
$tutor_quiz_option['time_limit']['time_limit_seconds'] = $time_limit_seconds;
|
220 |
|
221 |
$attempt_data = array(
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
$wpdb->insert($wpdb->prefix.'tutor_quiz_attempts', $attempt_data);
|
234 |
$attempt_id = (int) $wpdb->insert_id;
|
235 |
|
236 |
-
do_action('tutor_quiz/start/after', $quiz_id, $user_id, $attempt_id);
|
237 |
|
238 |
-
wp_redirect(get_permalink($quiz_id));
|
239 |
die();
|
240 |
}
|
241 |
|
242 |
-
public function answering_quiz(){
|
243 |
|
244 |
-
if ( tutils()->array_get('tutor_action', $_POST) !== 'tutor_answering_quiz_question' ){
|
245 |
return;
|
246 |
}
|
247 |
-
//submit quiz attempts
|
248 |
self::tutor_quiz_attemp_submit();
|
249 |
|
250 |
-
wp_redirect(get_the_permalink());
|
251 |
die();
|
252 |
}
|
253 |
|
254 |
/**
|
255 |
* Quiz abandon submission handler
|
256 |
-
*
|
257 |
* @return JSON response
|
258 |
-
*
|
259 |
* @since 1.9.6
|
260 |
*/
|
261 |
-
public function tutor_quiz_abandon(){
|
262 |
-
if ( tutils()->array_get('tutor_action', $_POST) !== 'tutor_answering_quiz_question' ){
|
263 |
return;
|
264 |
}
|
265 |
-
//submit quiz attempts
|
266 |
if ( self::tutor_quiz_attemp_submit() ) {
|
267 |
wp_send_json_success();
|
268 |
} else {
|
@@ -272,263 +273,273 @@ class Quiz {
|
|
272 |
|
273 |
/**
|
274 |
* This is a unified method for handling normal quiz submit or abandon submit
|
275 |
-
*
|
276 |
* It will handle ajax or normal form submit and can be used with different hooks
|
277 |
-
*
|
278 |
* @return true | false
|
279 |
-
*
|
280 |
-
* @since 1.9.6
|
281 |
*/
|
282 |
public static function tutor_quiz_attemp_submit() {
|
283 |
tutor_utils()->checking_nonce();
|
284 |
|
285 |
-
$attempt_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('attempt_id', $_POST));
|
286 |
-
$attempt
|
287 |
-
$course_id
|
288 |
|
289 |
-
$attempt_answers = isset($_POST['attempt']) ? $_POST['attempt'] : false;
|
290 |
-
if ( ! is_user_logged_in()){
|
291 |
-
die('Please sign in to do this operation');
|
292 |
}
|
293 |
|
294 |
global $wpdb;
|
295 |
$user_id = get_current_user_id();
|
296 |
|
297 |
-
do_action('tutor_quiz/attempt_analysing/before', $attempt_id);
|
298 |
|
299 |
-
if ($attempt_answers && is_array($attempt_answers) && count($attempt_answers)){
|
300 |
-
|
301 |
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
|
316 |
-
|
317 |
|
318 |
-
|
319 |
-
|
320 |
|
321 |
-
|
322 |
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
|
327 |
-
|
328 |
-
|
329 |
|
330 |
-
|
331 |
|
332 |
-
if(!is_numeric($answers) ||
|
333 |
wp_send_json_error();
|
334 |
exit;
|
335 |
}
|
336 |
|
337 |
-
|
338 |
-
|
339 |
|
340 |
-
|
341 |
|
342 |
$given_answer = (array) ( $answers );
|
343 |
-
|
344 |
-
$given_answer = array_filter(
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
|
|
|
|
|
|
|
|
356 |
AND is_correct = 1 ;
|
357 |
-
",
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
if (count(array_diff($get_original_answers, $given_answer)) === 0 && count($get_original_answers) === count($given_answer)) {
|
364 |
-
|
365 |
}
|
366 |
$given_answer = maybe_serialize( $answers );
|
367 |
|
368 |
-
|
|
|
|
|
|
|
369 |
|
370 |
-
|
371 |
-
|
372 |
|
373 |
-
|
374 |
-
|
|
|
|
|
|
|
|
|
|
|
375 |
|
376 |
-
|
377 |
-
if ( strtolower($given_answer) == strtolower(maybe_serialize( $gap_answer )) ) {
|
378 |
-
$is_answer_was_correct = true;
|
379 |
-
}
|
380 |
-
} elseif ( $question_type === 'open_ended' || $question_type === 'short_answer' ) {
|
381 |
-
$review_required = true;
|
382 |
-
$given_answer = wp_kses_post( $answers );
|
383 |
|
384 |
-
|
|
|
385 |
|
386 |
-
|
387 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
|
389 |
-
$get_original_answers = (array) $wpdb->get_col($wpdb->prepare(
|
390 |
-
"SELECT answer_id
|
391 |
-
FROM {$wpdb->prefix}tutor_quiz_question_answers
|
392 |
-
WHERE belongs_question_id = %d AND belongs_question_type = %s ORDER BY answer_order ASC ;", $question->question_id, $question_type));
|
393 |
-
|
394 |
$get_original_answers = array_map( 'sanitize_text_field', $get_original_answers );
|
395 |
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
FROM {$wpdb->prefix}tutor_quiz_question_answers
|
409 |
-
WHERE belongs_question_id = %d AND belongs_question_type = 'image_answering' ORDER BY answer_order asc ;",
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
|
|
|
|
437 |
}
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
return true;
|
459 |
-
|
460 |
return false;
|
461 |
}
|
462 |
|
463 |
|
464 |
/**
|
465 |
* Quiz attempt will be finish here
|
466 |
-
*
|
467 |
*/
|
468 |
|
469 |
-
public function finishing_quiz_attempt(){
|
470 |
|
471 |
-
if ( ! isset($_POST['tutor_action'])
|
472 |
return;
|
473 |
}
|
474 |
-
//Checking nonce
|
475 |
tutor_utils()->checking_nonce();
|
476 |
|
477 |
-
if ( ! is_user_logged_in()){
|
478 |
-
die('Please sign in to do this operation');
|
479 |
}
|
480 |
|
481 |
global $wpdb;
|
482 |
|
483 |
-
$quiz_id
|
484 |
-
$attempt
|
485 |
$attempt_id = $attempt->attempt_id;
|
486 |
|
487 |
$attempt_info = array(
|
488 |
-
'total_answered_questions'
|
489 |
-
'earned_marks'
|
490 |
-
'attempt_status'
|
491 |
-
'attempt_ended_at'
|
492 |
);
|
493 |
|
494 |
-
do_action('tutor_quiz_before_finish', $attempt_id, $quiz_id, $attempt->user_id);
|
495 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_info, array('attempt_id' => $attempt_id));
|
496 |
-
do_action('tutor_quiz_finished', $attempt_id, $quiz_id, $attempt->user_id);
|
497 |
|
498 |
-
wp_redirect(tutor_utils()->input_old('_wp_http_referer'));
|
499 |
}
|
500 |
|
501 |
/**
|
502 |
* Quiz timeout by ajax
|
503 |
*/
|
504 |
-
public function tutor_quiz_timeout(){
|
505 |
tutils()->checking_nonce();
|
506 |
|
507 |
global $wpdb;
|
508 |
|
509 |
-
$quiz_id = (int) sanitize_text_field($_POST['quiz_id']);
|
510 |
|
511 |
// if(!tutils()->can_user_manage('quiz', $quiz_id)) {
|
512 |
-
//
|
513 |
// }
|
514 |
|
515 |
-
$attempt = tutor_utils()->is_started_quiz($quiz_id);
|
516 |
|
517 |
-
if ($attempt) {
|
518 |
$attempt_id = $attempt->attempt_id;
|
519 |
|
520 |
$data = array(
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
|
526 |
-
do_action('tutor_quiz_timeout', $attempt_id, $quiz_id, $attempt->user_id);
|
527 |
|
528 |
wp_send_json_success();
|
529 |
}
|
530 |
|
531 |
-
wp_send_json_error(__('Quiz has been timeout already', 'tutor'));
|
532 |
}
|
533 |
|
534 |
/**
|
@@ -536,94 +547,88 @@ class Quiz {
|
|
536 |
*/
|
537 |
|
538 |
public function review_quiz_answer() {
|
539 |
-
|
540 |
-
tutils()->checking_nonce(strtolower($_SERVER['REQUEST_METHOD']));
|
541 |
|
542 |
global $wpdb;
|
543 |
|
544 |
-
$attempt_id
|
545 |
-
$attempt_answer_id = (int) sanitize_text_field($_GET['attempt_answer_id']);
|
546 |
-
$mark_as
|
547 |
|
548 |
-
if(!tutils()->can_user_manage('attempt', $attempt_id) || !tutils()->can_user_manage('attempt_answer', $attempt_answer_id)) {
|
549 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
550 |
}
|
551 |
|
552 |
-
$attempt_answer = $wpdb->get_row(
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
|
|
|
|
557 |
|
558 |
-
$attempt
|
559 |
-
$question
|
560 |
-
$course_id
|
561 |
-
$student_id
|
562 |
-
$previous_ans =
|
563 |
|
564 |
-
do_action('tutor_quiz_review_answer_before', $attempt_answer_id, $attempt_id, $mark_as);
|
565 |
|
566 |
-
if ($mark_as === 'correct'){
|
567 |
|
568 |
$answer_update_data = array(
|
569 |
'achieved_mark' => $attempt_answer->question_mark,
|
570 |
-
'is_correct'
|
571 |
);
|
572 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_attempt_answers', $answer_update_data, array('attempt_answer_id' => $attempt_answer_id ));
|
573 |
-
if($previous_ans ==0
|
574 |
-
|
575 |
-
|
576 |
-
//if previous answer was wrong or in review then add point as correct
|
577 |
$attempt_update_data = array(
|
578 |
-
'earned_marks'
|
579 |
-
|
580 |
-
'manually_reviewed_at' => date(
|
581 |
);
|
582 |
|
583 |
-
|
584 |
}
|
585 |
-
|
586 |
-
if ($question->question_type === 'open_ended' || $question->question_type === 'short_answer' ){
|
587 |
-
|
588 |
-
|
589 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_update_data, array('attempt_id' => $attempt_id ));
|
590 |
-
}
|
591 |
-
elseif($mark_as === 'incorrect')
|
592 |
-
{
|
593 |
|
594 |
$answer_update_data = array(
|
595 |
'achieved_mark' => '0.00',
|
596 |
-
'is_correct'
|
597 |
);
|
598 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_attempt_answers', $answer_update_data, array('attempt_answer_id' => $attempt_answer_id ));
|
599 |
|
|
|
600 |
|
601 |
-
|
602 |
-
{
|
603 |
-
|
604 |
-
//if previous ans was right then mynus
|
605 |
$attempt_update_data = array(
|
606 |
-
'earned_marks'
|
607 |
-
'is_manually_reviewed'
|
608 |
-
'manually_reviewed_at'
|
609 |
);
|
610 |
|
611 |
}
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_update_data, array('attempt_id' => $attempt_id ));
|
617 |
}
|
618 |
-
do_action('tutor_quiz_review_answer_after', $attempt_answer_id, $attempt_id, $mark_as);
|
619 |
-
do_action('tutor_quiz/answer/review/after', $attempt_answer_id, $course_id, $student_id);
|
620 |
-
|
621 |
-
if (wp_doing_ajax())
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
else{
|
626 |
-
wp_redirect(admin_url("admin.php?page=tutor_quiz_attempts&sub_page=view_attempt&attempt_id=".$attempt_id));
|
627 |
}
|
628 |
|
629 |
die();
|
@@ -633,131 +638,143 @@ class Quiz {
|
|
633 |
/**
|
634 |
* New Design Quiz
|
635 |
*/
|
636 |
-
public function tutor_create_quiz_and_load_modal(){
|
637 |
tutils()->checking_nonce();
|
638 |
|
639 |
-
$topic_id
|
640 |
-
$quiz_title
|
641 |
-
$quiz_description
|
642 |
-
$next_order_id
|
643 |
-
|
644 |
-
if(!tutils()->can_user_manage('topic', $topic_id)) {
|
645 |
-
wp_send_json_error(
|
|
|
|
|
|
|
|
|
|
|
646 |
}
|
647 |
|
648 |
$post_arr = array(
|
649 |
-
'post_type'
|
650 |
-
'post_title'
|
651 |
-
'post_content'
|
652 |
-
'post_status'
|
653 |
-
'post_author'
|
654 |
-
'post_parent'
|
655 |
-
'menu_order'
|
656 |
);
|
657 |
-
$quiz_id
|
658 |
-
do_action('tutor_initial_quiz_created', $quiz_id);
|
659 |
|
660 |
ob_start();
|
661 |
-
include
|
662 |
$output = ob_get_clean();
|
663 |
|
664 |
ob_start();
|
665 |
?>
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
|
|
|
|
675 |
<?php
|
676 |
$output_quiz_row = ob_get_clean();
|
677 |
|
678 |
-
wp_send_json_success(
|
|
|
|
|
|
|
|
|
|
|
679 |
}
|
680 |
|
681 |
-
public function tutor_delete_quiz_by_id(){
|
682 |
tutils()->checking_nonce();
|
683 |
|
684 |
-
|
685 |
|
686 |
-
|
687 |
-
|
688 |
|
689 |
-
|
690 |
-
|
691 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
692 |
}
|
693 |
|
694 |
-
|
695 |
-
|
696 |
|
697 |
-
|
698 |
-
|
699 |
|
700 |
-
|
701 |
-
|
702 |
-
if (is_array($questions_ids) && count($questions_ids)){
|
703 |
-
|
704 |
-
|
705 |
}
|
706 |
-
|
707 |
-
$wpdb->delete($wpdb->prefix.'tutor_quiz_questions', array('quiz_id' => $quiz_id));
|
708 |
|
709 |
-
|
710 |
-
delete_post_meta($quiz_id, '_tutor_course_id_for_lesson');
|
711 |
|
712 |
-
|
|
|
713 |
|
|
|
714 |
|
715 |
-
|
716 |
-
|
717 |
|
718 |
-
|
719 |
-
|
720 |
|
721 |
/**
|
722 |
* Update Quiz from quiz builder modal
|
723 |
*
|
724 |
* @since v.1.0.0
|
725 |
*/
|
726 |
-
public function tutor_quiz_builder_quiz_update(){
|
727 |
tutils()->checking_nonce();
|
728 |
|
729 |
-
$quiz_id
|
730 |
-
$topic_id
|
731 |
-
$quiz_title
|
732 |
-
$quiz_description
|
733 |
|
734 |
-
if(!tutils()->can_user_manage('quiz', $quiz_id)) {
|
735 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
736 |
}
|
737 |
|
738 |
$post_arr = array(
|
739 |
-
'ID'
|
740 |
-
'post_title'
|
741 |
-
'post_content'
|
742 |
|
743 |
);
|
744 |
$quiz_id = wp_update_post( $post_arr );
|
745 |
|
746 |
-
do_action('tutor_quiz_updated', $quiz_id);
|
747 |
|
748 |
ob_start();
|
749 |
?>
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
|
|
|
|
757 |
<?php
|
758 |
$output_quiz_row = ob_get_clean();
|
759 |
|
760 |
-
wp_send_json_success(array('output_quiz_row' => $output_quiz_row));
|
761 |
}
|
762 |
|
763 |
/**
|
@@ -765,21 +782,21 @@ class Quiz {
|
|
765 |
*
|
766 |
* @since v.1.0.0
|
767 |
*/
|
768 |
-
public function tutor_load_edit_quiz_modal(){
|
769 |
tutils()->checking_nonce();
|
770 |
|
771 |
-
$quiz_id
|
772 |
-
$topic_id
|
773 |
-
|
774 |
-
if(!tutils()->can_user_manage('quiz', $quiz_id)) {
|
775 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
776 |
}
|
777 |
-
|
778 |
ob_start();
|
779 |
-
include
|
780 |
$output = ob_get_clean();
|
781 |
|
782 |
-
wp_send_json_success(array('output' => $output));
|
783 |
}
|
784 |
|
785 |
/**
|
@@ -787,115 +804,114 @@ class Quiz {
|
|
787 |
*
|
788 |
* @since v.1.0.0
|
789 |
*/
|
790 |
-
public function tutor_quiz_builder_get_question_form(){
|
791 |
tutils()->checking_nonce();
|
792 |
|
793 |
global $wpdb;
|
794 |
-
$quiz_id
|
795 |
-
$question_id = sanitize_text_field(tutor_utils()->avalue_dot('question_id', $_POST));
|
796 |
|
797 |
-
if(!tutils()->can_user_manage('quiz', $quiz_id)) {
|
798 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
799 |
}
|
800 |
-
|
801 |
-
if ( ! $question_id){
|
802 |
-
$next_question_id
|
803 |
-
$next_question_order = tutor_utils()->quiz_next_question_order_id($quiz_id);
|
804 |
|
805 |
$new_question_data = array(
|
806 |
-
'quiz_id'
|
807 |
-
'question_title'
|
808 |
-
'question_description'
|
809 |
-
'question_type'
|
810 |
-
'question_mark'
|
811 |
-
'question_settings'
|
812 |
-
'question_order'
|
813 |
);
|
814 |
|
815 |
-
$wpdb->insert($wpdb->prefix.'tutor_quiz_questions', $new_question_data);
|
816 |
$question_id = $wpdb->insert_id;
|
817 |
}
|
818 |
|
819 |
-
$question = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions where question_id = %d ", $question_id));
|
820 |
|
821 |
ob_start();
|
822 |
-
include
|
823 |
$output = ob_get_clean();
|
824 |
|
825 |
-
wp_send_json_success(array('output' => $output));
|
826 |
}
|
827 |
|
828 |
-
public function tutor_quiz_modal_update_question(){
|
829 |
tutils()->checking_nonce();
|
830 |
|
831 |
global $wpdb;
|
832 |
|
833 |
-
$question_data = $_POST['tutor_quiz_question'];
|
834 |
|
835 |
-
foreach ($question_data as $question_id => $question) {
|
836 |
|
837 |
-
if(!tutils()->can_user_manage('question', $question_id)) {
|
838 |
continue;
|
839 |
}
|
840 |
|
841 |
-
$question_title
|
842 |
-
$question_description
|
843 |
-
$question_type
|
844 |
-
$question_mark
|
845 |
|
846 |
-
unset($question['question_title']);
|
847 |
-
unset($question['question_description']);
|
848 |
|
849 |
$data = array(
|
850 |
-
'question_title'
|
851 |
-
'question_description'
|
852 |
-
'question_type'
|
853 |
-
'question_mark'
|
854 |
-
'question_settings'
|
855 |
);
|
856 |
|
857 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_questions', $data, array('question_id' => $question_id) );
|
858 |
-
|
859 |
|
860 |
/**
|
861 |
* Validation
|
862 |
*/
|
863 |
-
if ($question_type === 'true_false' || $question_type === 'single_choice'){
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
}
|
882 |
|
883 |
wp_send_json_success();
|
884 |
}
|
885 |
|
886 |
-
public function tutor_quiz_builder_question_delete(){
|
887 |
tutils()->checking_nonce();
|
888 |
|
889 |
global $wpdb;
|
890 |
|
891 |
-
$question_id = sanitize_text_field(tutor_utils()->avalue_dot('question_id', $_POST));
|
892 |
-
|
893 |
-
if(!tutils()->can_user_manage('question', $question_id)) {
|
894 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
895 |
}
|
896 |
|
897 |
-
if ($question_id){
|
898 |
-
$wpdb->delete($wpdb->prefix.'tutor_quiz_questions', array('question_id' => esc_sql( $question_id ) ));
|
899 |
}
|
900 |
|
901 |
wp_send_json_success();
|
@@ -906,126 +922,143 @@ class Quiz {
|
|
906 |
*
|
907 |
* @since v.1.0.0
|
908 |
*/
|
909 |
-
public function tutor_quiz_add_question_answers(){
|
910 |
tutils()->checking_nonce();
|
911 |
|
912 |
-
$question_id
|
913 |
-
$question
|
914 |
$question_type = $question['question_type'];
|
915 |
|
916 |
-
if(!tutils()->can_user_manage('question', $question_id)) {
|
917 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
918 |
}
|
919 |
|
920 |
ob_start();
|
921 |
-
include
|
922 |
$output = ob_get_clean();
|
923 |
|
924 |
-
wp_send_json_success(array('output' => $output));
|
925 |
}
|
926 |
|
927 |
/**
|
928 |
* Edit Answer Form
|
929 |
-
|
930 |
-
|
931 |
*/
|
932 |
-
public function tutor_quiz_edit_question_answer(){
|
933 |
tutils()->checking_nonce();
|
934 |
|
935 |
-
$answer_id = (int) sanitize_text_field($_POST['answer_id']);
|
|
|
|
|
|
|
|
|
936 |
|
937 |
-
|
938 |
-
|
939 |
}
|
940 |
-
|
941 |
-
$old_answer = tutor_utils()->get_answer_by_id($answer_id);
|
942 |
-
foreach ($old_answer as $old_answer);
|
943 |
-
$question_id = $old_answer->belongs_question_id;
|
944 |
$question_type = $old_answer->belongs_question_type;
|
945 |
|
946 |
ob_start();
|
947 |
-
include
|
948 |
$output = ob_get_clean();
|
949 |
|
950 |
-
wp_send_json_success(array('output' => $output));
|
951 |
-
|
952 |
|
953 |
-
public function tutor_save_quiz_answer_options(){
|
954 |
tutils()->checking_nonce();
|
955 |
|
956 |
global $wpdb;
|
957 |
|
958 |
-
$questions = $_POST['tutor_quiz_question'];
|
959 |
-
$answers
|
960 |
|
961 |
-
foreach ($answers as $question_id => $answer){
|
962 |
|
963 |
-
if(!tutils()->can_user_manage('question', $question_id)) {
|
964 |
continue;
|
965 |
}
|
966 |
|
967 |
-
$question
|
968 |
$question_type = $question['question_type'];
|
969 |
|
970 |
-
//Getting next sorting order
|
971 |
-
$next_order_id = (int) $wpdb->get_var(
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
|
|
|
|
|
|
|
|
|
|
976 |
|
977 |
$next_order_id = $next_order_id + 1;
|
978 |
|
979 |
-
if ($question){
|
980 |
-
if ($question_type === 'true_false'){
|
981 |
-
$wpdb->delete(
|
|
|
|
|
|
|
|
|
|
|
|
|
982 |
$data_true_false = array(
|
983 |
array(
|
984 |
-
'belongs_question_id' => esc_sql( $question_id )
|
985 |
'belongs_question_type' => $question_type,
|
986 |
-
'answer_title' => __('True', 'tutor'),
|
987 |
'is_correct' => $answer['true_false'] == 'true' ? 1 : 0,
|
988 |
'answer_two_gap_match' => 'true',
|
989 |
),
|
990 |
array(
|
991 |
-
'belongs_question_id' => esc_sql( $question_id )
|
992 |
'belongs_question_type' => $question_type,
|
993 |
-
'answer_title' => __('False', 'tutor'),
|
994 |
'is_correct' => $answer['true_false'] == 'false' ? 1 : 0,
|
995 |
'answer_two_gap_match' => 'false',
|
996 |
),
|
997 |
);
|
998 |
|
999 |
-
foreach ($data_true_false as $true_false_data){
|
1000 |
-
$wpdb->insert($wpdb->prefix.'tutor_quiz_question_answers', $true_false_data);
|
1001 |
}
|
1002 |
-
|
1003 |
-
|
1004 |
-
$question_type === 'matching' || $question_type === 'image_matching' || $question_type === 'image_answering' ){
|
1005 |
|
1006 |
$answer_data = array(
|
1007 |
'belongs_question_id' => sanitize_text_field( $question_id ),
|
1008 |
'belongs_question_type' => $question_type,
|
1009 |
'answer_title' => sanitize_text_field( $answer['answer_title'] ),
|
1010 |
-
'image_id' => isset($answer['image_id']) ? $answer['image_id'] : 0,
|
1011 |
-
'answer_view_format' => isset($answer['answer_view_format']) ? $answer['answer_view_format'] : 0,
|
1012 |
'answer_order' => $next_order_id,
|
1013 |
);
|
1014 |
-
if (isset($answer['matched_answer_title'])){
|
1015 |
$answer_data['answer_two_gap_match'] = sanitize_text_field( $answer['matched_answer_title'] );
|
1016 |
-
|
1017 |
|
1018 |
-
$wpdb->insert($wpdb->prefix.'tutor_quiz_question_answers', $answer_data);
|
1019 |
|
1020 |
-
}elseif($question_type === 'fill_in_the_blank'){
|
1021 |
-
$wpdb->delete(
|
|
|
|
|
|
|
|
|
|
|
|
|
1022 |
$answer_data = array(
|
1023 |
-
'belongs_question_id' => sanitize_text_field( $question_id )
|
1024 |
'belongs_question_type' => $question_type,
|
1025 |
'answer_title' => sanitize_text_field( $answer['answer_title'] ),
|
1026 |
-
'answer_two_gap_match' => isset($answer['answer_two_gap_match']) ? sanitize_text_field( trim($answer['answer_two_gap_match']) ) : null,
|
1027 |
);
|
1028 |
-
$wpdb->insert($wpdb->prefix.'tutor_quiz_question_answers', $answer_data);
|
1029 |
}
|
1030 |
}
|
1031 |
}
|
@@ -1035,275 +1068,275 @@ class Quiz {
|
|
1035 |
|
1036 |
/**
|
1037 |
* Tutor Update Answer
|
1038 |
-
|
1039 |
-
|
1040 |
*/
|
1041 |
-
public function tutor_update_quiz_answer_options(){
|
1042 |
tutils()->checking_nonce();
|
1043 |
|
1044 |
global $wpdb;
|
1045 |
|
1046 |
-
$answer_id = (int) sanitize_text_field($_POST['tutor_quiz_answer_id']);
|
1047 |
|
1048 |
-
if(!tutils()->can_user_manage('quiz_answer', $answer_id)) {
|
1049 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
1050 |
}
|
1051 |
|
1052 |
-
$questions = $_POST['tutor_quiz_question'];
|
1053 |
-
$answers
|
1054 |
|
1055 |
-
foreach ($answers as $question_id => $answer){
|
1056 |
-
$question
|
1057 |
$question_type = $question['question_type'];
|
1058 |
|
1059 |
-
if ($question){
|
1060 |
-
if($question_type === 'multiple_choice' || $question_type === 'single_choice' || $question_type === 'ordering' || $question_type === 'matching' || $question_type === 'image_matching' || $question_type === 'fill_in_the_blank' || $question_type === 'image_answering'
|
1061 |
|
1062 |
$answer_data = array(
|
1063 |
'belongs_question_id' => $question_id,
|
1064 |
'belongs_question_type' => $question_type,
|
1065 |
-
'answer_title' => sanitize_text_field( $answer['answer_title'] )
|
1066 |
-
'image_id' => isset($answer['image_id']) ? $answer['image_id'] : 0,
|
1067 |
-
'answer_view_format' => isset($answer['answer_view_format']) ? sanitize_text_field( $answer['answer_view_format'] )
|
1068 |
);
|
1069 |
-
if (isset($answer['matched_answer_title'])){
|
1070 |
-
$answer_data['answer_two_gap_match'] = sanitize_text_field( $answer['matched_answer_title'] )
|
1071 |
}
|
1072 |
|
1073 |
-
if ($question_type === 'fill_in_the_blank'){
|
1074 |
-
$answer_data['answer_two_gap_match'] = isset($answer['answer_two_gap_match']) ? sanitize_text_field(trim($answer['answer_two_gap_match'])) : null;
|
1075 |
}
|
1076 |
|
1077 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_question_answers', $answer_data, array('answer_id' => $answer_id));
|
1078 |
}
|
1079 |
}
|
1080 |
}
|
1081 |
|
1082 |
-
//die(print_r($_POST));
|
1083 |
wp_send_json_success();
|
1084 |
-
|
1085 |
|
1086 |
-
public function tutor_quiz_builder_get_answers_by_question(){
|
1087 |
tutils()->checking_nonce();
|
1088 |
|
1089 |
global $wpdb;
|
1090 |
-
$question_id
|
1091 |
-
$question_type = sanitize_text_field($_POST['question_type']);
|
1092 |
|
1093 |
-
if(!tutils()->can_user_manage('question', $question_id)) {
|
1094 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
1095 |
}
|
1096 |
|
1097 |
-
$question = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE question_id = %d ", $question_id));
|
1098 |
-
$answers
|
1099 |
|
1100 |
ob_start();
|
1101 |
|
1102 |
-
switch ($question_type){
|
1103 |
case 'true_false':
|
1104 |
-
echo '<label>'.__('Answer options & mark correct', 'tutor').'</label>';
|
1105 |
break;
|
1106 |
case 'ordering':
|
1107 |
-
echo '<label>'.__('Make sure you’re saving the answers in the right order. Students will have to match this order exactly.', 'tutor').'</label>';
|
1108 |
break;
|
1109 |
}
|
1110 |
|
1111 |
-
if (is_array($answers) && count($answers)){
|
1112 |
-
foreach ($answers as $answer){
|
1113 |
?>
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
|
1129 |
<?php
|
1130 |
-
if ($answer->image_id){
|
1131 |
-
echo '<span class="tutor-question-answer-image"><img src="'.wp_get_attachment_image_url($answer->image_id).'" /> </span>';
|
1132 |
}
|
1133 |
-
if ($question_type === 'true_false' || $question_type === 'single_choice'){
|
1134 |
?>
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
<?php
|
1139 |
-
}elseif ($question_type === 'multiple_choice'){
|
1140 |
?>
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
<?php
|
1145 |
}
|
1146 |
?>
|
1147 |
-
<?php if(
|
1148 |
<span class="tutor-quiz-answer-edit">
|
1149 |
<a href="javascript:;"><i class="tutor-icon-pencil"></i> </a>
|
1150 |
</span>
|
1151 |
-
<?php endif
|
1152 |
-
|
1153 |
-
|
1154 |
-
<?php if(
|
1155 |
<div class="tutor-quiz-answer-trash-wrap">
|
1156 |
-
<a href="javascript:;" class="answer-trash-btn" data-answer-id="<?php echo $answer->answer_id; ?>"><i class="tutor-icon-garbage"></i> </a>
|
1157 |
</div>
|
1158 |
-
<?php endif
|
1159 |
-
|
1160 |
<?php
|
1161 |
}
|
1162 |
}
|
1163 |
$output = ob_get_clean();
|
1164 |
|
1165 |
-
wp_send_json_success(array('output' => $output));
|
1166 |
}
|
1167 |
|
1168 |
-
public function tutor_quiz_builder_delete_answer(){
|
1169 |
tutils()->checking_nonce();
|
1170 |
|
1171 |
global $wpdb;
|
1172 |
-
$answer_id = sanitize_text_field($_POST['answer_id']);
|
1173 |
-
|
1174 |
-
if(!tutils()->can_user_manage('quiz_answer', $answer_id)) {
|
1175 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
1176 |
}
|
1177 |
|
1178 |
-
$wpdb->delete($wpdb->prefix.'tutor_quiz_question_answers', array('answer_id' => esc_sql( $answer_id ) ));
|
1179 |
wp_send_json_success();
|
1180 |
}
|
1181 |
|
1182 |
/**
|
1183 |
* Save quiz questions sorting
|
1184 |
*/
|
1185 |
-
public function tutor_quiz_question_sorting(){
|
1186 |
tutils()->checking_nonce();
|
1187 |
|
1188 |
global $wpdb;
|
1189 |
|
1190 |
-
$question_ids = tutor_utils()->avalue_dot('sorted_question_ids', $_POST);
|
1191 |
-
if (is_array($question_ids) && count($question_ids) ){
|
1192 |
$i = 0;
|
1193 |
-
foreach ($question_ids as $key => $question_id){
|
1194 |
-
if(tutils()->can_user_manage('question', $question_id)) {
|
1195 |
$i++;
|
1196 |
-
$wpdb->update($wpdb->prefix.'tutor_quiz_questions', array('question_order' => $i), array('question_id' => $question_id));
|
1197 |
}
|
1198 |
}
|
1199 |
}
|
1200 |
-
|
1201 |
|
1202 |
/**
|
1203 |
* Save sorting data for quiz answers
|
1204 |
*/
|
1205 |
-
public function tutor_quiz_answer_sorting(){
|
1206 |
tutils()->checking_nonce();
|
1207 |
|
1208 |
-
|
1209 |
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
if(tutils()->can_user_manage('quiz_answer', $answer_id)) {
|
1215 |
$i++;
|
1216 |
-
|
1217 |
}
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
|
1222 |
/**
|
1223 |
* Mark answer as correct
|
1224 |
*/
|
1225 |
|
1226 |
-
|
1227 |
tutils()->checking_nonce();
|
1228 |
|
1229 |
-
|
1230 |
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
if(!tutils()->can_user_manage('quiz_answer', $answer_id)) {
|
1235 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
1236 |
}
|
1237 |
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
|
1245 |
/**
|
1246 |
* Update quiz settings from modal
|
1247 |
*
|
1248 |
* @since : v.1.0.0
|
1249 |
*/
|
1250 |
-
public function tutor_quiz_modal_update_settings(){
|
1251 |
tutils()->checking_nonce();
|
1252 |
-
//while creating quiz if creating step is not follow then it may throw error that why check added
|
1253 |
-
$quiz_id
|
1254 |
$current_topic_id = sanitize_text_field( $_POST['topic_id'] );
|
1255 |
-
$course_id
|
1256 |
|
1257 |
$quiz_option = tutor_utils()->sanitize_array( $_POST['quiz_option'] );
|
1258 |
-
|
1259 |
-
if( !tutils()->can_user_manage('quiz', $quiz_id) ) {
|
1260 |
-
wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
1261 |
}
|
1262 |
|
1263 |
-
update_post_meta($quiz_id, 'tutor_quiz_option', $quiz_option);
|
1264 |
-
do_action('tutor_quiz_settings_updated', $quiz_id);
|
1265 |
|
1266 |
-
|
1267 |
ob_start();
|
1268 |
-
include
|
1269 |
$course_contents = ob_get_clean();
|
1270 |
|
1271 |
wp_send_json_success( array( 'course_contents' => $course_contents ) );
|
1272 |
}
|
1273 |
|
1274 |
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
|
1279 |
/**
|
1280 |
* Rendering quiz for frontend
|
1281 |
-
|
1282 |
-
|
1283 |
*/
|
1284 |
|
1285 |
-
public function tutor_render_quiz_content(){
|
1286 |
|
1287 |
tutils()->checking_nonce();
|
1288 |
|
1289 |
-
$quiz_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('quiz_id', $_POST));
|
1290 |
|
1291 |
-
if(!tutils()->has_enrolled_content_access('quiz', $quiz_id)) {
|
1292 |
-
wp_send_json_error( array('message'=>__('Access Denied.', 'tutor')) );
|
1293 |
}
|
1294 |
|
1295 |
ob_start();
|
1296 |
global $post;
|
1297 |
|
1298 |
-
$post = get_post($quiz_id);
|
1299 |
-
setup_postdata($post);
|
1300 |
-
//tutor_lesson_content();
|
1301 |
|
1302 |
single_quiz_contents();
|
1303 |
wp_reset_postdata();
|
1304 |
|
1305 |
$html = ob_get_clean();
|
1306 |
-
wp_send_json_success(array('html' => $html));
|
1307 |
}
|
1308 |
|
1309 |
-
}
|
11 |
|
12 |
namespace TUTOR;
|
13 |
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
exit;
|
16 |
+
}
|
17 |
|
18 |
class Quiz {
|
19 |
|
20 |
+
private $allowed_attributes = array(
|
21 |
+
'src' => array(),
|
22 |
+
'style' => array(),
|
23 |
+
'class' => array(),
|
24 |
+
'id' => array(),
|
25 |
+
'href' => array(),
|
26 |
+
'alt' => array(),
|
27 |
'title' => array(),
|
28 |
'type' => array(),
|
29 |
'controls' => array(),
|
30 |
'muted' => array(),
|
31 |
+
'loop' => array(),
|
32 |
'poster' => array(),
|
33 |
'preload' => array(),
|
34 |
'autoplay' => array(),
|
35 |
'width' => array(),
|
36 |
+
'height' => array(),
|
37 |
);
|
38 |
+
|
39 |
private $allowed_html = array( 'img', 'b', 'i', 'br', 'a', 'audio', 'video', 'source' );
|
40 |
|
41 |
public function __construct() {
|
|
|
|
|
42 |
|
43 |
+
add_action( 'save_post_tutor_quiz', array( $this, 'save_quiz_meta' ) );
|
44 |
+
|
45 |
+
add_action( 'wp_ajax_tutor_load_quiz_builder_modal', array( $this, 'tutor_load_quiz_builder_modal' ) );
|
46 |
+
add_action( 'wp_ajax_remove_quiz_from_post', array( $this, 'remove_quiz_from_post' ) );
|
47 |
|
48 |
+
add_action( 'wp_ajax_tutor_quiz_timeout', array( $this, 'tutor_quiz_timeout' ) );
|
49 |
|
50 |
+
// User take the quiz
|
51 |
+
add_action( 'template_redirect', array( $this, 'start_the_quiz' ) );
|
52 |
+
add_action( 'template_redirect', array( $this, 'answering_quiz' ) );
|
53 |
+
add_action( 'template_redirect', array( $this, 'finishing_quiz_attempt' ) );
|
54 |
|
55 |
+
add_action( 'admin_action_review_quiz_answer', array( $this, 'review_quiz_answer' ) );
|
56 |
+
add_action( 'wp_ajax_review_quiz_answer', array( $this, 'review_quiz_answer' ) );
|
57 |
+
add_action( 'wp_ajax_tutor_instructor_feedback', array( $this, 'tutor_instructor_feedback' ) ); // Instructor Feedback Action
|
58 |
|
59 |
/**
|
60 |
* New Design Quiz
|
61 |
*/
|
62 |
|
63 |
+
add_action( 'wp_ajax_tutor_create_quiz_and_load_modal', array( $this, 'tutor_create_quiz_and_load_modal' ) );
|
64 |
+
add_action( 'wp_ajax_tutor_delete_quiz_by_id', array( $this, 'tutor_delete_quiz_by_id' ) );
|
65 |
+
add_action( 'wp_ajax_tutor_quiz_builder_quiz_update', array( $this, 'tutor_quiz_builder_quiz_update' ) );
|
66 |
+
add_action( 'wp_ajax_tutor_load_edit_quiz_modal', array( $this, 'tutor_load_edit_quiz_modal' ) );
|
67 |
+
add_action( 'wp_ajax_tutor_quiz_builder_get_question_form', array( $this, 'tutor_quiz_builder_get_question_form' ) );
|
68 |
+
add_action( 'wp_ajax_tutor_quiz_modal_update_question', array( $this, 'tutor_quiz_modal_update_question' ) );
|
69 |
+
add_action( 'wp_ajax_tutor_quiz_builder_question_delete', array( $this, 'tutor_quiz_builder_question_delete' ) );
|
70 |
+
add_action( 'wp_ajax_tutor_quiz_add_question_answers', array( $this, 'tutor_quiz_add_question_answers' ) );
|
71 |
+
add_action( 'wp_ajax_tutor_quiz_edit_question_answer', array( $this, 'tutor_quiz_edit_question_answer' ) );
|
72 |
+
add_action( 'wp_ajax_tutor_save_quiz_answer_options', array( $this, 'tutor_save_quiz_answer_options' ) );
|
73 |
+
add_action( 'wp_ajax_tutor_update_quiz_answer_options', array( $this, 'tutor_update_quiz_answer_options' ) );
|
74 |
+
add_action( 'wp_ajax_tutor_quiz_builder_get_answers_by_question', array( $this, 'tutor_quiz_builder_get_answers_by_question' ) );
|
75 |
+
add_action( 'wp_ajax_tutor_quiz_builder_delete_answer', array( $this, 'tutor_quiz_builder_delete_answer' ) );
|
76 |
+
add_action( 'wp_ajax_tutor_quiz_question_sorting', array( $this, 'tutor_quiz_question_sorting' ) );
|
77 |
+
add_action( 'wp_ajax_tutor_quiz_answer_sorting', array( $this, 'tutor_quiz_answer_sorting' ) );
|
78 |
+
add_action( 'wp_ajax_tutor_mark_answer_as_correct', array( $this, 'tutor_mark_answer_as_correct' ) );
|
79 |
+
add_action( 'wp_ajax_tutor_quiz_modal_update_settings', array( $this, 'tutor_quiz_modal_update_settings' ) );
|
80 |
|
81 |
/**
|
82 |
+
* Frontend Stuff
|
83 |
+
*/
|
84 |
+
add_action( 'wp_ajax_tutor_render_quiz_content', array( $this, 'tutor_render_quiz_content' ) );
|
85 |
|
86 |
/**
|
87 |
* Quiz abandon action
|
88 |
+
*
|
89 |
* @since 1.9.6
|
90 |
*/
|
91 |
+
add_action( 'wp_ajax_tutor_quiz_abandon', array( $this, 'tutor_quiz_abandon' ) );
|
92 |
|
93 |
$this->prepare_allowed_html();
|
94 |
}
|
95 |
|
96 |
private function prepare_allowed_html() {
|
97 |
+
|
98 |
$allowed = array();
|
99 |
|
100 |
+
foreach ( $this->allowed_html as $tag ) {
|
101 |
+
$allowed[ $tag ] = $this->allowed_attributes;
|
102 |
}
|
103 |
|
104 |
$this->allowed_html = $allowed;
|
105 |
}
|
106 |
|
107 |
+
public function tutor_instructor_feedback() {
|
108 |
tutils()->checking_nonce();
|
109 |
|
110 |
+
$feedback = sanitize_text_field( $_POST['feedback'] );
|
111 |
+
$attempt_id = (int) tutor_utils()->avalue_dot( 'attempts_id', tutor_sanitize_data( $_POST ) );
|
112 |
|
113 |
+
if ( $attempt_id && tutils()->can_user_manage( 'attempt', $attempt_id ) ) {
|
114 |
+
update_post_meta( $attempt_id, 'instructor_feedback', $feedback );
|
115 |
+
do_action( 'tutor_quiz/attempt/submitted/feedback', $attempt_id );
|
116 |
|
117 |
+
wp_send_json_success();
|
118 |
}
|
119 |
}
|
120 |
|
121 |
+
public function save_quiz_meta( $post_ID ) {
|
122 |
+
if ( isset( $_POST['quiz_option'] ) ) {
|
123 |
+
$quiz_option = tutor_utils()->sanitize_array( $_POST['quiz_option'] );
|
124 |
+
update_post_meta( $post_ID, 'tutor_quiz_option', $quiz_option );
|
125 |
}
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
* Tutor Quiz Builder Modal
|
130 |
*/
|
131 |
+
public function tutor_load_quiz_builder_modal() {
|
132 |
tutils()->checking_nonce();
|
133 |
|
134 |
ob_start();
|
135 |
+
include tutor()->path . 'views/modal/add_quiz.php';
|
136 |
$output = ob_get_clean();
|
137 |
|
138 |
+
wp_send_json_success( array( 'output' => $output ) );
|
139 |
}
|
140 |
|
141 |
+
public function remove_quiz_from_post() {
|
142 |
tutils()->checking_nonce();
|
143 |
|
144 |
global $wpdb;
|
145 |
+
$quiz_id = (int) tutor_utils()->avalue_dot( 'quiz_id', tutor_sanitize_data($_POST) );
|
146 |
|
147 |
+
if ( ! tutils()->can_user_manage( 'quiz', $quiz_id ) ) {
|
148 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
149 |
}
|
150 |
|
151 |
+
$wpdb->update( $wpdb->posts, array( 'post_parent' => 0 ), array( 'ID' => $quiz_id ) );
|
152 |
wp_send_json_success();
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
*
|
157 |
+
* Start Quiz from here...
|
158 |
+
*
|
159 |
+
* @since v.1.0.0
|
160 |
*/
|
161 |
|
162 |
+
public function start_the_quiz() {
|
163 |
+
if ( ! isset( $_POST['tutor_action'] ) || $_POST['tutor_action'] !== 'tutor_start_quiz' ) {
|
164 |
return;
|
165 |
}
|
166 |
+
// Checking nonce
|
167 |
tutor_utils()->checking_nonce();
|
168 |
|
169 |
+
if ( ! is_user_logged_in() ) {
|
170 |
+
// TODO: need to set a view in the next version
|
171 |
+
die( 'Please sign in to do this operation' );
|
172 |
}
|
173 |
|
174 |
global $wpdb;
|
175 |
|
176 |
$user_id = get_current_user_id();
|
177 |
+
$user = get_userdata( $user_id );
|
178 |
|
179 |
+
$quiz_id = (int) sanitize_text_field( $_POST['quiz_id'] );
|
180 |
|
181 |
+
$quiz = get_post( $quiz_id );
|
182 |
+
$course = tutor_utils()->get_course_by_quiz( $quiz_id );
|
183 |
+
if ( empty( $course->ID ) ) {
|
184 |
+
die( 'There is something went wrong with course, please check if quiz attached with a course' );
|
185 |
+
}
|
186 |
|
187 |
+
do_action( 'tutor_quiz/start/before', $quiz_id, $user_id );
|
188 |
|
189 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
190 |
|
191 |
+
$tutor_quiz_option = (array) maybe_unserialize( get_post_meta( $quiz_id, 'tutor_quiz_option', true ) );
|
192 |
+
$attempts_allowed = tutor_utils()->get_quiz_option( $quiz_id, 'attempts_allowed', 0 );
|
193 |
|
194 |
+
$time_limit = tutor_utils()->get_quiz_option( $quiz_id, 'time_limit.time_value' );
|
195 |
$time_limit_seconds = 0;
|
196 |
+
$time_type = 'seconds';
|
197 |
+
if ( $time_limit ) {
|
198 |
+
$time_type = tutor_utils()->get_quiz_option( $quiz_id, 'time_limit.time_type' );
|
199 |
|
200 |
+
switch ( $time_type ) {
|
201 |
case 'seconds':
|
202 |
$time_limit_seconds = $time_limit;
|
203 |
break;
|
216 |
}
|
217 |
}
|
218 |
|
219 |
+
$max_question_allowed = tutor_utils()->max_questions_for_take_quiz( $quiz_id );
|
220 |
$tutor_quiz_option['time_limit']['time_limit_seconds'] = $time_limit_seconds;
|
221 |
|
222 |
$attempt_data = array(
|
223 |
+
'course_id' => $course->ID,
|
224 |
+
'quiz_id' => $quiz_id,
|
225 |
+
'user_id' => $user_id,
|
226 |
+
'total_questions' => $max_question_allowed,
|
227 |
+
'total_answered_questions' => 0,
|
228 |
+
'attempt_info' => maybe_serialize( $tutor_quiz_option ),
|
229 |
+
'attempt_status' => 'attempt_started',
|
230 |
+
'attempt_ip' => tutor_utils()->get_ip(),
|
231 |
+
'attempt_started_at' => $date,
|
232 |
+
);
|
233 |
+
|
234 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_attempts', $attempt_data );
|
235 |
$attempt_id = (int) $wpdb->insert_id;
|
236 |
|
237 |
+
do_action( 'tutor_quiz/start/after', $quiz_id, $user_id, $attempt_id );
|
238 |
|
239 |
+
wp_redirect( get_permalink( $quiz_id ) );
|
240 |
die();
|
241 |
}
|
242 |
|
243 |
+
public function answering_quiz() {
|
244 |
|
245 |
+
if ( tutils()->array_get( 'tutor_action', $_POST ) !== 'tutor_answering_quiz_question' ) {
|
246 |
return;
|
247 |
}
|
248 |
+
// submit quiz attempts
|
249 |
self::tutor_quiz_attemp_submit();
|
250 |
|
251 |
+
wp_redirect( get_the_permalink() );
|
252 |
die();
|
253 |
}
|
254 |
|
255 |
/**
|
256 |
* Quiz abandon submission handler
|
257 |
+
*
|
258 |
* @return JSON response
|
259 |
+
*
|
260 |
* @since 1.9.6
|
261 |
*/
|
262 |
+
public function tutor_quiz_abandon() {
|
263 |
+
if ( tutils()->array_get( 'tutor_action', $_POST ) !== 'tutor_answering_quiz_question' ) {
|
264 |
return;
|
265 |
}
|
266 |
+
// submit quiz attempts
|
267 |
if ( self::tutor_quiz_attemp_submit() ) {
|
268 |
wp_send_json_success();
|
269 |
} else {
|
273 |
|
274 |
/**
|
275 |
* This is a unified method for handling normal quiz submit or abandon submit
|
276 |
+
*
|
277 |
* It will handle ajax or normal form submit and can be used with different hooks
|
278 |
+
*
|
279 |
* @return true | false
|
280 |
+
*
|
281 |
+
* @since 1.9.6
|
282 |
*/
|
283 |
public static function tutor_quiz_attemp_submit() {
|
284 |
tutor_utils()->checking_nonce();
|
285 |
|
286 |
+
$attempt_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( 'attempt_id', $_POST ) );
|
287 |
+
$attempt = tutor_utils()->get_attempt( $attempt_id );
|
288 |
+
$course_id = tutor_utils()->get_course_by_quiz( $attempt->quiz_id )->ID;
|
289 |
|
290 |
+
$attempt_answers = isset( $_POST['attempt'] ) ? tutor_sanitize_data( $_POST['attempt'] ) : false;
|
291 |
+
if ( ! is_user_logged_in() ) {
|
292 |
+
die( 'Please sign in to do this operation' );
|
293 |
}
|
294 |
|
295 |
global $wpdb;
|
296 |
$user_id = get_current_user_id();
|
297 |
|
298 |
+
do_action( 'tutor_quiz/attempt_analysing/before', $attempt_id );
|
299 |
|
300 |
+
if ( $attempt_answers && is_array( $attempt_answers ) && count( $attempt_answers ) ) {
|
301 |
+
foreach ( $attempt_answers as $attempt_id => $attempt_answer ) {
|
302 |
|
303 |
+
/**
|
304 |
+
* Get total marks of all question comes
|
305 |
+
*/
|
306 |
+
$question_ids = tutor_utils()->avalue_dot( 'quiz_question_ids', $attempt_answer );
|
307 |
+
if ( is_array( $question_ids ) && count( $question_ids ) ) {
|
308 |
+
$question_ids_string = "'" . implode( "','", $question_ids ) . "'";
|
309 |
+
$total_question_marks = $wpdb->get_var( "SELECT SUM(question_mark) FROM {$wpdb->prefix}tutor_quiz_questions WHERE question_id IN({$question_ids_string}) ;" );
|
310 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempts', array( 'total_marks' => $total_question_marks ), array( 'attempt_id' => $attempt_id ) );
|
311 |
+
}
|
312 |
|
313 |
+
if ( ! $attempt || $user_id != $attempt->user_id ) {
|
314 |
+
die( 'Operation not allowed, attempt not found or permission denied' );
|
315 |
+
}
|
316 |
|
317 |
+
$quiz_answers = tutor_utils()->avalue_dot( 'quiz_question', $attempt_answer );
|
318 |
|
319 |
+
$total_marks = 0;
|
320 |
+
$review_required = false;
|
321 |
|
322 |
+
if ( tutils()->count( $quiz_answers ) ) {
|
323 |
|
324 |
+
foreach ( $quiz_answers as $question_id => $answers ) {
|
325 |
+
$question = tutor_utils()->get_quiz_question_by_id( $question_id );
|
326 |
+
$question_type = $question->question_type;
|
327 |
|
328 |
+
$is_answer_was_correct = false;
|
329 |
+
$given_answer = '';
|
330 |
|
331 |
+
if ( $question_type === 'true_false' || $question_type === 'single_choice' ) {
|
332 |
|
333 |
+
if ( ! is_numeric( $answers ) || ! $answers ) {
|
334 |
wp_send_json_error();
|
335 |
exit;
|
336 |
}
|
337 |
|
338 |
+
$given_answer = $answers;
|
339 |
+
$is_answer_was_correct = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT is_correct FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE answer_id = %d ", $answers ) );
|
340 |
|
341 |
+
} elseif ( $question_type === 'multiple_choice' ) {
|
342 |
|
343 |
$given_answer = (array) ( $answers );
|
344 |
+
|
345 |
+
$given_answer = array_filter(
|
346 |
+
$given_answer,
|
347 |
+
function( $id ) {
|
348 |
+
return is_numeric( $id ) && $id > 0;
|
349 |
+
}
|
350 |
+
);
|
351 |
+
|
352 |
+
$get_original_answers = (array) $wpdb->get_col(
|
353 |
+
$wpdb->prepare(
|
354 |
+
"SELECT
|
355 |
+
answer_id
|
356 |
+
FROM
|
357 |
+
{$wpdb->prefix}tutor_quiz_question_answers
|
358 |
+
WHERE
|
359 |
+
belongs_question_id = %d
|
360 |
+
AND belongs_question_type = %s
|
361 |
AND is_correct = 1 ;
|
362 |
+
",
|
363 |
+
$question->question_id,
|
364 |
+
$question_type
|
365 |
+
)
|
366 |
+
);
|
367 |
+
|
368 |
+
if ( count( array_diff( $get_original_answers, $given_answer ) ) === 0 && count( $get_original_answers ) === count( $given_answer ) ) {
|
369 |
+
$is_answer_was_correct = true;
|
370 |
}
|
371 |
$given_answer = maybe_serialize( $answers );
|
372 |
|
373 |
+
} elseif ( $question_type === 'fill_in_the_blank' ) {
|
374 |
+
|
375 |
+
$given_answer = (array) array_map( 'sanitize_text_field', $answers );
|
376 |
+
$given_answer = maybe_serialize( $given_answer );
|
377 |
|
378 |
+
$get_original_answer = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = %d AND belongs_question_type = %s ;", $question->question_id, $question_type ) );
|
379 |
+
$gap_answer = (array) explode( '|', $get_original_answer->answer_two_gap_match );
|
380 |
|
381 |
+
$gap_answer = array_map( 'sanitize_text_field', $gap_answer );
|
382 |
+
if ( strtolower( $given_answer ) == strtolower( maybe_serialize( $gap_answer ) ) ) {
|
383 |
+
$is_answer_was_correct = true;
|
384 |
+
}
|
385 |
+
} elseif ( $question_type === 'open_ended' || $question_type === 'short_answer' ) {
|
386 |
+
$review_required = true;
|
387 |
+
$given_answer = wp_kses_post( $answers );
|
388 |
|
389 |
+
} elseif ( $question_type === 'ordering' || $question_type === 'matching' || $question_type === 'image_matching' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
|
391 |
+
$given_answer = (array) array_map( 'sanitize_text_field', tutor_utils()->avalue_dot( 'answers', $answers ) );
|
392 |
+
$given_answer = maybe_serialize( $given_answer );
|
393 |
|
394 |
+
$get_original_answers = (array) $wpdb->get_col(
|
395 |
+
$wpdb->prepare(
|
396 |
+
"SELECT answer_id
|
397 |
+
FROM {$wpdb->prefix}tutor_quiz_question_answers
|
398 |
+
WHERE belongs_question_id = %d AND belongs_question_type = %s ORDER BY answer_order ASC ;",
|
399 |
+
$question->question_id,
|
400 |
+
$question_type
|
401 |
+
)
|
402 |
+
);
|
403 |
|
|
|
|
|
|
|
|
|
|
|
404 |
$get_original_answers = array_map( 'sanitize_text_field', $get_original_answers );
|
405 |
|
406 |
+
if ( $given_answer == maybe_serialize( $get_original_answers ) ) {
|
407 |
+
$is_answer_was_correct = true;
|
408 |
+
}
|
409 |
+
} elseif ( $question_type === 'image_answering' ) {
|
410 |
+
$image_inputs = tutor_utils()->avalue_dot( 'answer_id', $answers );
|
411 |
+
$image_inputs = (array) array_map( 'sanitize_text_field', $image_inputs );
|
412 |
+
$given_answer = maybe_serialize( $image_inputs );
|
413 |
+
$is_answer_was_correct = false;
|
414 |
+
|
415 |
+
$db_answer = $wpdb->get_col(
|
416 |
+
$wpdb->prepare(
|
417 |
+
"SELECT answer_title
|
418 |
+
FROM {$wpdb->prefix}tutor_quiz_question_answers
|
419 |
+
WHERE belongs_question_id = %d AND belongs_question_type = 'image_answering' ORDER BY answer_order asc ;",
|
420 |
+
$question_id
|
421 |
+
)
|
422 |
+
);
|
423 |
+
|
424 |
+
if ( is_array( $db_answer ) && count( $db_answer ) ) {
|
425 |
+
$is_answer_was_correct = ( strtolower( maybe_serialize( array_values( $image_inputs ) ) ) == strtolower( maybe_serialize( $db_answer ) ) );
|
426 |
+
}
|
427 |
+
}
|
428 |
+
|
429 |
+
$question_mark = $is_answer_was_correct ? $question->question_mark : 0;
|
430 |
+
$total_marks += $question_mark;
|
431 |
+
|
432 |
+
$answers_data = array(
|
433 |
+
'user_id' => $user_id,
|
434 |
+
'quiz_id' => $attempt->quiz_id,
|
435 |
+
'question_id' => $question_id,
|
436 |
+
'quiz_attempt_id' => $attempt_id,
|
437 |
+
'given_answer' => $given_answer,
|
438 |
+
'question_mark' => $question->question_mark,
|
439 |
+
'achieved_mark' => $question_mark,
|
440 |
+
'minus_mark' => 0,
|
441 |
+
'is_correct' => $is_answer_was_correct ? 1 : 0,
|
442 |
+
);
|
443 |
+
|
444 |
+
/*
|
445 |
+
check if question_type open ended or short ans the set is_correct default value null before saving
|
446 |
+
*/
|
447 |
+
if ( $question_type === 'open_ended' || $question_type === 'short_answer' ) {
|
448 |
+
$answers_data['is_correct'] = null;
|
449 |
}
|
450 |
+
|
451 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_attempt_answers', $answers_data );
|
452 |
+
}
|
453 |
+
}
|
454 |
+
|
455 |
+
$attempt_info = array(
|
456 |
+
'total_answered_questions' => tutils()->count( $quiz_answers ),
|
457 |
+
'earned_marks' => $total_marks,
|
458 |
+
'attempt_status' => 'attempt_ended',
|
459 |
+
'attempt_ended_at' => date( 'Y-m-d H:i:s', tutor_time() ),
|
460 |
+
);
|
461 |
+
|
462 |
+
if ( $review_required ) {
|
463 |
+
$attempt_info['attempt_status'] = 'review_required';
|
464 |
+
}
|
465 |
+
|
466 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempts', $attempt_info, array( 'attempt_id' => $attempt_id ) );
|
467 |
+
}
|
468 |
+
|
469 |
+
do_action( 'tutor_quiz/attempt_ended', $attempt_id, $course_id, $user_id );
|
470 |
return true;
|
471 |
+
}
|
472 |
return false;
|
473 |
}
|
474 |
|
475 |
|
476 |
/**
|
477 |
* Quiz attempt will be finish here
|
|
|
478 |
*/
|
479 |
|
480 |
+
public function finishing_quiz_attempt() {
|
481 |
|
482 |
+
if ( ! isset( $_POST['tutor_action'] ) || $_POST['tutor_action'] !== 'tutor_finish_quiz_attempt' ) {
|
483 |
return;
|
484 |
}
|
485 |
+
// Checking nonce
|
486 |
tutor_utils()->checking_nonce();
|
487 |
|
488 |
+
if ( ! is_user_logged_in() ) {
|
489 |
+
die( 'Please sign in to do this operation' );
|
490 |
}
|
491 |
|
492 |
global $wpdb;
|
493 |
|
494 |
+
$quiz_id = (int) sanitize_text_field( $_POST['quiz_id'] );
|
495 |
+
$attempt = tutor_utils()->is_started_quiz( $quiz_id );
|
496 |
$attempt_id = $attempt->attempt_id;
|
497 |
|
498 |
$attempt_info = array(
|
499 |
+
'total_answered_questions' => 0,
|
500 |
+
'earned_marks' => 0,
|
501 |
+
'attempt_status' => 'attempt_ended',
|
502 |
+
'attempt_ended_at' => date( 'Y-m-d H:i:s', tutor_time() ),
|
503 |
);
|
504 |
|
505 |
+
do_action( 'tutor_quiz_before_finish', $attempt_id, $quiz_id, $attempt->user_id );
|
506 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempts', $attempt_info, array( 'attempt_id' => $attempt_id ) );
|
507 |
+
do_action( 'tutor_quiz_finished', $attempt_id, $quiz_id, $attempt->user_id );
|
508 |
|
509 |
+
wp_redirect( tutor_utils()->input_old( '_wp_http_referer' ) );
|
510 |
}
|
511 |
|
512 |
/**
|
513 |
* Quiz timeout by ajax
|
514 |
*/
|
515 |
+
public function tutor_quiz_timeout() {
|
516 |
tutils()->checking_nonce();
|
517 |
|
518 |
global $wpdb;
|
519 |
|
520 |
+
$quiz_id = (int) sanitize_text_field( $_POST['quiz_id'] );
|
521 |
|
522 |
// if(!tutils()->can_user_manage('quiz', $quiz_id)) {
|
523 |
+
// wp_send_json_error( array('message'=>__('Access Denied', 'tutor')) );
|
524 |
// }
|
525 |
|
526 |
+
$attempt = tutor_utils()->is_started_quiz( $quiz_id );
|
527 |
|
528 |
+
if ( $attempt ) {
|
529 |
$attempt_id = $attempt->attempt_id;
|
530 |
|
531 |
$data = array(
|
532 |
+
'attempt_status' => 'attempt_timeout',
|
533 |
+
'attempt_ended_at' => date( 'Y-m-d H:i:s', tutor_time() ),
|
534 |
+
);
|
535 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempts', $data, array( 'attempt_id' => $attempt->attempt_id ) );
|
536 |
|
537 |
+
do_action( 'tutor_quiz_timeout', $attempt_id, $quiz_id, $attempt->user_id );
|
538 |
|
539 |
wp_send_json_success();
|
540 |
}
|
541 |
|
542 |
+
wp_send_json_error( __( 'Quiz has been timeout already', 'tutor' ) );
|
543 |
}
|
544 |
|
545 |
/**
|
547 |
*/
|
548 |
|
549 |
public function review_quiz_answer() {
|
550 |
+
|
551 |
+
tutils()->checking_nonce( strtolower( $_SERVER['REQUEST_METHOD'] ) );
|
552 |
|
553 |
global $wpdb;
|
554 |
|
555 |
+
$attempt_id = (int) sanitize_text_field( $_GET['attempt_id'] );
|
556 |
+
$attempt_answer_id = (int) sanitize_text_field( $_GET['attempt_answer_id'] );
|
557 |
+
$mark_as = sanitize_text_field( $_GET['mark_as'] );
|
558 |
|
559 |
+
if ( ! tutils()->can_user_manage( 'attempt', $attempt_id ) || ! tutils()->can_user_manage( 'attempt_answer', $attempt_answer_id ) ) {
|
560 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
561 |
}
|
562 |
|
563 |
+
$attempt_answer = $wpdb->get_row(
|
564 |
+
$wpdb->prepare(
|
565 |
+
"SELECT * FROM {$wpdb->prefix}tutor_quiz_attempt_answers
|
566 |
+
WHERE attempt_answer_id = %d ",
|
567 |
+
$attempt_answer_id
|
568 |
+
)
|
569 |
+
);
|
570 |
|
571 |
+
$attempt = tutor_utils()->get_attempt( $attempt_id );
|
572 |
+
$question = tutils()->get_quiz_question_by_id( $attempt_answer->question_id );
|
573 |
+
$course_id = $attempt->course_id;
|
574 |
+
$student_id = $attempt->user_id;
|
575 |
+
$previous_ans = $attempt_answer->is_correct;
|
576 |
|
577 |
+
do_action( 'tutor_quiz_review_answer_before', $attempt_answer_id, $attempt_id, $mark_as );
|
578 |
|
579 |
+
if ( $mark_as === 'correct' ) {
|
580 |
|
581 |
$answer_update_data = array(
|
582 |
'achieved_mark' => $attempt_answer->question_mark,
|
583 |
+
'is_correct' => 1,
|
584 |
);
|
585 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempt_answers', $answer_update_data, array( 'attempt_answer_id' => $attempt_answer_id ) );
|
586 |
+
if ( $previous_ans == 0 or $previous_ans == null ) {
|
587 |
+
|
588 |
+
// if previous answer was wrong or in review then add point as correct
|
|
|
589 |
$attempt_update_data = array(
|
590 |
+
'earned_marks' => $attempt->earned_marks + $attempt_answer->question_mark,
|
591 |
+
'is_manually_reviewed' => 1,
|
592 |
+
'manually_reviewed_at' => date( 'Y-m-d H:i:s', tutor_time() ),
|
593 |
);
|
594 |
|
|
|
595 |
}
|
596 |
+
|
597 |
+
if ( $question->question_type === 'open_ended' || $question->question_type === 'short_answer' ) {
|
598 |
+
$attempt_update_data['attempt_status'] = 'attempt_ended';
|
599 |
+
}
|
600 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempts', $attempt_update_data, array( 'attempt_id' => $attempt_id ) );
|
601 |
+
} elseif ( $mark_as === 'incorrect' ) {
|
|
|
|
|
602 |
|
603 |
$answer_update_data = array(
|
604 |
'achieved_mark' => '0.00',
|
605 |
+
'is_correct' => 0,
|
606 |
);
|
607 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempt_answers', $answer_update_data, array( 'attempt_answer_id' => $attempt_answer_id ) );
|
608 |
|
609 |
+
if ( $previous_ans == 1 ) {
|
610 |
|
611 |
+
// if previous ans was right then mynus
|
|
|
|
|
|
|
612 |
$attempt_update_data = array(
|
613 |
+
'earned_marks' => $attempt->earned_marks - $attempt_answer->question_mark,
|
614 |
+
'is_manually_reviewed' => 1,
|
615 |
+
'manually_reviewed_at' => date( 'Y-m-d H:i:s', tutor_time() ),
|
616 |
);
|
617 |
|
618 |
}
|
619 |
+
if ( $question->question_type === 'open_ended' || $question->question_type === 'short_answer' ) {
|
620 |
+
$attempt_update_data['attempt_status'] = 'attempt_ended';
|
621 |
+
}
|
622 |
+
|
623 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_attempts', $attempt_update_data, array( 'attempt_id' => $attempt_id ) );
|
624 |
}
|
625 |
+
do_action( 'tutor_quiz_review_answer_after', $attempt_answer_id, $attempt_id, $mark_as );
|
626 |
+
do_action( 'tutor_quiz/answer/review/after', $attempt_answer_id, $course_id, $student_id );
|
627 |
+
|
628 |
+
if ( wp_doing_ajax() ) {
|
629 |
+
wp_send_json_success();
|
630 |
+
} else {
|
631 |
+
wp_redirect( admin_url( 'admin.php?page=tutor_quiz_attempts&sub_page=view_attempt&attempt_id=' . $attempt_id ) );
|
|
|
|
|
632 |
}
|
633 |
|
634 |
die();
|
638 |
/**
|
639 |
* New Design Quiz
|
640 |
*/
|
641 |
+
public function tutor_create_quiz_and_load_modal() {
|
642 |
tutils()->checking_nonce();
|
643 |
|
644 |
+
$topic_id = sanitize_text_field( $_POST['topic_id'] );
|
645 |
+
$quiz_title = sanitize_text_field( $_POST['quiz_title'] );
|
646 |
+
$quiz_description = wp_kses( $_POST['quiz_description'], $this->allowed_html );
|
647 |
+
$next_order_id = tutor_utils()->get_next_course_content_order_id( $topic_id );
|
648 |
+
|
649 |
+
if ( ! tutils()->can_user_manage( 'topic', $topic_id ) ) {
|
650 |
+
wp_send_json_error(
|
651 |
+
array(
|
652 |
+
'message' => __( 'Access Denied', 'tutor' ),
|
653 |
+
'data' => tutor_sanitize_data($_POST),
|
654 |
+
)
|
655 |
+
);
|
656 |
}
|
657 |
|
658 |
$post_arr = array(
|
659 |
+
'post_type' => 'tutor_quiz',
|
660 |
+
'post_title' => $quiz_title,
|
661 |
+
'post_content' => $quiz_description,
|
662 |
+
'post_status' => 'publish',
|
663 |
+
'post_author' => get_current_user_id(),
|
664 |
+
'post_parent' => $topic_id,
|
665 |
+
'menu_order' => $next_order_id,
|
666 |
);
|
667 |
+
$quiz_id = wp_insert_post( $post_arr );
|
668 |
+
do_action( 'tutor_initial_quiz_created', $quiz_id );
|
669 |
|
670 |
ob_start();
|
671 |
+
include tutor()->path . 'views/modal/edit_quiz.php';
|
672 |
$output = ob_get_clean();
|
673 |
|
674 |
ob_start();
|
675 |
?>
|
676 |
+
<div id="tutor-quiz-<?php echo esc_attr( $quiz_id ); ?>" class="course-content-item tutor-quiz tutor-quiz-<?php echo $quiz_id; ?>">
|
677 |
+
<div class="tutor-lesson-top">
|
678 |
+
<i class="tutor-icon-move"></i>
|
679 |
+
<a href="javascript:;" class="open-tutor-quiz-modal" data-quiz-id="<?php echo $quiz_id; ?>" data-topic-id="<?php echo $topic_id; ?>">
|
680 |
+
<i class=" tutor-icon-doubt"></i>[<?php _e( 'QUIZ', 'tutor' ); ?>]
|
681 |
+
<?php echo stripslashes( $quiz_title ); ?>
|
682 |
+
</a>
|
683 |
+
<?php do_action( 'tutor_course_builder_before_quiz_btn_action', $quiz_id ); ?>
|
684 |
+
<a href="javascript:;" class="tutor-delete-quiz-btn" data-quiz-id="<?php echo $quiz_id; ?>"><i class="tutor-icon-garbage"></i></a>
|
685 |
+
</div>
|
686 |
+
</div>
|
687 |
<?php
|
688 |
$output_quiz_row = ob_get_clean();
|
689 |
|
690 |
+
wp_send_json_success(
|
691 |
+
array(
|
692 |
+
'output' => $output,
|
693 |
+
'output_quiz_row' => $output_quiz_row,
|
694 |
+
)
|
695 |
+
);
|
696 |
}
|
697 |
|
698 |
+
public function tutor_delete_quiz_by_id() {
|
699 |
tutils()->checking_nonce();
|
700 |
|
701 |
+
global $wpdb;
|
702 |
|
703 |
+
$quiz_id = (int) sanitize_text_field( $_POST['quiz_id'] );
|
704 |
+
$post = get_post( $quiz_id );
|
705 |
|
706 |
+
if ( ! tutils()->can_user_manage( 'quiz', $quiz_id ) ) {
|
707 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
|
|
708 |
}
|
709 |
|
710 |
+
if ( $post->post_type === 'tutor_quiz' ) {
|
711 |
+
do_action( 'tutor_delete_quiz_before', $quiz_id );
|
712 |
|
713 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_attempts', array( 'quiz_id' => $quiz_id ) );
|
714 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_attempt_answers', array( 'quiz_id' => $quiz_id ) );
|
715 |
|
716 |
+
$questions_ids = $wpdb->get_col( $wpdb->prepare( "SELECT question_id FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = %d ", $quiz_id ) );
|
717 |
+
|
718 |
+
if ( is_array( $questions_ids ) && count( $questions_ids ) ) {
|
719 |
+
$in_question_ids = "'" . implode( "','", $questions_ids ) . "'";
|
720 |
+
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id IN({$in_question_ids}) " );
|
721 |
}
|
|
|
|
|
722 |
|
723 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_questions', array( 'quiz_id' => $quiz_id ) );
|
|
|
724 |
|
725 |
+
wp_delete_post( $quiz_id, true );
|
726 |
+
delete_post_meta( $quiz_id, '_tutor_course_id_for_lesson' );
|
727 |
|
728 |
+
do_action( 'tutor_delete_quiz_after', $quiz_id );
|
729 |
|
730 |
+
wp_send_json_success();
|
731 |
+
}
|
732 |
|
733 |
+
wp_send_json_error();
|
734 |
+
}
|
735 |
|
736 |
/**
|
737 |
* Update Quiz from quiz builder modal
|
738 |
*
|
739 |
* @since v.1.0.0
|
740 |
*/
|
741 |
+
public function tutor_quiz_builder_quiz_update() {
|
742 |
tutils()->checking_nonce();
|
743 |
|
744 |
+
$quiz_id = sanitize_text_field( $_POST['quiz_id'] );
|
745 |
+
$topic_id = sanitize_text_field( $_POST['topic_id'] );
|
746 |
+
$quiz_title = sanitize_text_field( $_POST['quiz_title'] );
|
747 |
+
$quiz_description = wp_kses( $_POST['quiz_description'], $this->allowed_html );
|
748 |
|
749 |
+
if ( ! tutils()->can_user_manage( 'quiz', $quiz_id ) ) {
|
750 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
751 |
}
|
752 |
|
753 |
$post_arr = array(
|
754 |
+
'ID' => $quiz_id,
|
755 |
+
'post_title' => $quiz_title,
|
756 |
+
'post_content' => $quiz_description,
|
757 |
|
758 |
);
|
759 |
$quiz_id = wp_update_post( $post_arr );
|
760 |
|
761 |
+
do_action( 'tutor_quiz_updated', $quiz_id );
|
762 |
|
763 |
ob_start();
|
764 |
?>
|
765 |
+
<div class="tutor-lesson-top">
|
766 |
+
<i class="tutor-icon-move"></i>
|
767 |
+
<a href="javascript:;" class="open-tutor-quiz-modal" data-quiz-id="<?php echo esc_attr( $quiz_id ); ?>" data-topic-id="<?php echo esc_attr( $topic_id ); ?>">
|
768 |
+
<i class=" tutor-icon-doubt"></i>[<?php _e( 'QUIZ', 'tutor' ); ?>]
|
769 |
+
<?php echo stripslashes( $quiz_title ); ?>
|
770 |
+
</a>
|
771 |
+
<?php do_action( 'tutor_course_builder_before_quiz_btn_action', $quiz_id ); ?>
|
772 |
+
<a href="javascript:;" class="tutor-delete-quiz-btn" data-quiz-id="<?php echo esc_attr( $quiz_id ); ?>"><i class="tutor-icon-garbage"></i></a>
|
773 |
+
</div>
|
774 |
<?php
|
775 |
$output_quiz_row = ob_get_clean();
|
776 |
|
777 |
+
wp_send_json_success( array( 'output_quiz_row' => $output_quiz_row ) );
|
778 |
}
|
779 |
|
780 |
/**
|
782 |
*
|
783 |
* @since v.1.0.0
|
784 |
*/
|
785 |
+
public function tutor_load_edit_quiz_modal() {
|
786 |
tutils()->checking_nonce();
|
787 |
|
788 |
+
$quiz_id = sanitize_text_field( $_POST['quiz_id'] );
|
789 |
+
$topic_id = sanitize_text_field( $_POST['topic_id'] );
|
790 |
+
|
791 |
+
if ( ! tutils()->can_user_manage( 'quiz', $quiz_id ) ) {
|
792 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
793 |
}
|
794 |
+
|
795 |
ob_start();
|
796 |
+
include tutor()->path . 'views/modal/edit_quiz.php';
|
797 |
$output = ob_get_clean();
|
798 |
|
799 |
+
wp_send_json_success( array( 'output' => $output ) );
|
800 |
}
|
801 |
|
802 |
/**
|
804 |
*
|
805 |
* @since v.1.0.0
|
806 |
*/
|
807 |
+
public function tutor_quiz_builder_get_question_form() {
|
808 |
tutils()->checking_nonce();
|
809 |
|
810 |
global $wpdb;
|
811 |
+
$quiz_id = sanitize_text_field( $_POST['quiz_id'] );
|
812 |
+
$question_id = sanitize_text_field( tutor_utils()->avalue_dot( 'question_id', $_POST ) );
|
813 |
|
814 |
+
if ( ! tutils()->can_user_manage( 'quiz', $quiz_id ) ) {
|
815 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
816 |
}
|
817 |
+
|
818 |
+
if ( ! $question_id ) {
|
819 |
+
$next_question_id = tutor_utils()->quiz_next_question_id();
|
820 |
+
$next_question_order = tutor_utils()->quiz_next_question_order_id( $quiz_id );
|
821 |
|
822 |
$new_question_data = array(
|
823 |
+
'quiz_id' => $quiz_id,
|
824 |
+
'question_title' => __( 'Question', 'tutor' ) . ' ' . $next_question_id,
|
825 |
+
'question_description' => '',
|
826 |
+
'question_type' => 'true_false',
|
827 |
+
'question_mark' => 1,
|
828 |
+
'question_settings' => maybe_serialize( array() ),
|
829 |
+
'question_order' => esc_sql( $next_question_order ),
|
830 |
);
|
831 |
|
832 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_questions', $new_question_data );
|
833 |
$question_id = $wpdb->insert_id;
|
834 |
}
|
835 |
|
836 |
+
$question = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_quiz_questions where question_id = %d ", $question_id ) );
|
837 |
|
838 |
ob_start();
|
839 |
+
include tutor()->path . 'views/modal/question_form.php';
|
840 |
$output = ob_get_clean();
|
841 |
|
842 |
+
wp_send_json_success( array( 'output' => $output ) );
|
843 |
}
|
844 |
|
845 |
+
public function tutor_quiz_modal_update_question() {
|
846 |
tutils()->checking_nonce();
|
847 |
|
848 |
global $wpdb;
|
849 |
|
850 |
+
$question_data = tutor_sanitize_data( $_POST['tutor_quiz_question'] );
|
851 |
|
852 |
+
foreach ( $question_data as $question_id => $question ) {
|
853 |
|
854 |
+
if ( ! tutils()->can_user_manage( 'question', $question_id ) ) {
|
855 |
continue;
|
856 |
}
|
857 |
|
858 |
+
$question_title = sanitize_text_field( $question['question_title'] );
|
859 |
+
$question_description = wp_kses( $question['question_description'], $this->allowed_html ); // sanitize_text_field($question['question_description']);
|
860 |
+
$question_type = sanitize_text_field( $question['question_type'] );
|
861 |
+
$question_mark = sanitize_text_field( $question['question_mark'] );
|
862 |
|
863 |
+
unset( $question['question_title'] );
|
864 |
+
unset( $question['question_description'] );
|
865 |
|
866 |
$data = array(
|
867 |
+
'question_title' => $question_title,
|
868 |
+
'question_description' => $question_description,
|
869 |
+
'question_type' => $question_type,
|
870 |
+
'question_mark' => $question_mark,
|
871 |
+
'question_settings' => maybe_serialize( $question ),
|
872 |
);
|
873 |
|
874 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_questions', $data, array( 'question_id' => $question_id ) );
|
|
|
875 |
|
876 |
/**
|
877 |
* Validation
|
878 |
*/
|
879 |
+
if ( $question_type === 'true_false' || $question_type === 'single_choice' ) {
|
880 |
+
$question_options = tutils()->get_answers_by_quiz_question( $question_id );
|
881 |
+
if ( tutils()->count( $question_options ) ) {
|
882 |
+
$required_validate = true;
|
883 |
+
foreach ( $question_options as $question_option ) {
|
884 |
+
if ( $question_option->is_correct ) {
|
885 |
+
$required_validate = false;
|
886 |
+
}
|
887 |
+
}
|
888 |
+
if ( $required_validate ) {
|
889 |
+
$validation_msg = "<p class='tutor-error-msg'>" . __( 'Please select the correct answer', 'tutor' ) . '</p>';
|
890 |
+
wp_send_json_error( array( 'validation_msg' => $validation_msg ) );
|
891 |
+
}
|
892 |
+
} else {
|
893 |
+
$validation_msg = "<p class='tutor-error-msg'>" . __( 'Please make sure you have added more than one option and saved them', 'tutor' ) . '</p>';
|
894 |
+
wp_send_json_error( array( 'validation_msg' => $validation_msg ) );
|
895 |
+
}
|
896 |
+
}
|
897 |
}
|
898 |
|
899 |
wp_send_json_success();
|
900 |
}
|
901 |
|
902 |
+
public function tutor_quiz_builder_question_delete() {
|
903 |
tutils()->checking_nonce();
|
904 |
|
905 |
global $wpdb;
|
906 |
|
907 |
+
$question_id = sanitize_text_field( tutor_utils()->avalue_dot( 'question_id', $_POST ) );
|
908 |
+
|
909 |
+
if ( ! tutils()->can_user_manage( 'question', $question_id ) ) {
|
910 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
911 |
}
|
912 |
|
913 |
+
if ( $question_id ) {
|
914 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_questions', array( 'question_id' => esc_sql( $question_id ) ) );
|
915 |
}
|
916 |
|
917 |
wp_send_json_success();
|
922 |
*
|
923 |
* @since v.1.0.0
|
924 |
*/
|
925 |
+
public function tutor_quiz_add_question_answers() {
|
926 |
tutils()->checking_nonce();
|
927 |
|
928 |
+
$question_id = sanitize_text_field( $_POST['question_id'] );
|
929 |
+
$question = tutor_utils()->avalue_dot( $question_id, $_POST['tutor_quiz_question'] );
|
930 |
$question_type = $question['question_type'];
|
931 |
|
932 |
+
if ( ! tutils()->can_user_manage( 'question', $question_id ) ) {
|
933 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
934 |
}
|
935 |
|
936 |
ob_start();
|
937 |
+
include tutor()->path . 'views/modal/question_answer_form.php';
|
938 |
$output = ob_get_clean();
|
939 |
|
940 |
+
wp_send_json_success( array( 'output' => $output ) );
|
941 |
}
|
942 |
|
943 |
/**
|
944 |
* Edit Answer Form
|
945 |
+
*
|
946 |
+
* @since v.1.0.0
|
947 |
*/
|
948 |
+
public function tutor_quiz_edit_question_answer() {
|
949 |
tutils()->checking_nonce();
|
950 |
|
951 |
+
$answer_id = (int) sanitize_text_field( $_POST['answer_id'] );
|
952 |
+
|
953 |
+
if ( ! tutils()->can_user_manage( 'quiz_answer', $answer_id ) ) {
|
954 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
955 |
+
}
|
956 |
|
957 |
+
$old_answer = tutor_utils()->get_answer_by_id( $answer_id );
|
958 |
+
foreach ( $old_answer as $old_answer ) {
|
959 |
}
|
960 |
+
$question_id = $old_answer->belongs_question_id;
|
|
|
|
|
|
|
961 |
$question_type = $old_answer->belongs_question_type;
|
962 |
|
963 |
ob_start();
|
964 |
+
include tutor()->path . 'views/modal/question_answer_edit_form.php';
|
965 |
$output = ob_get_clean();
|
966 |
|
967 |
+
wp_send_json_success( array( 'output' => $output ) );
|
968 |
+
}
|
969 |
|
970 |
+
public function tutor_save_quiz_answer_options() {
|
971 |
tutils()->checking_nonce();
|
972 |
|
973 |
global $wpdb;
|
974 |
|
975 |
+
$questions = tutor_sanitize_data( $_POST['tutor_quiz_question'] );
|
976 |
+
$answers = tutor_sanitize_data( $_POST['quiz_answer'] );
|
977 |
|
978 |
+
foreach ( $answers as $question_id => $answer ) {
|
979 |
|
980 |
+
if ( ! tutils()->can_user_manage( 'question', $question_id ) ) {
|
981 |
continue;
|
982 |
}
|
983 |
|
984 |
+
$question = tutor_utils()->avalue_dot( $question_id, $questions );
|
985 |
$question_type = $question['question_type'];
|
986 |
|
987 |
+
// Getting next sorting order
|
988 |
+
$next_order_id = (int) $wpdb->get_var(
|
989 |
+
$wpdb->prepare(
|
990 |
+
"SELECT MAX(answer_order)
|
991 |
+
FROM {$wpdb->prefix}tutor_quiz_question_answers
|
992 |
+
where belongs_question_id = %d
|
993 |
+
AND belongs_question_type = %s ",
|
994 |
+
$question_id,
|
995 |
+
esc_sql( $question_type )
|
996 |
+
)
|
997 |
+
);
|
998 |
|
999 |
$next_order_id = $next_order_id + 1;
|
1000 |
|
1001 |
+
if ( $question ) {
|
1002 |
+
if ( $question_type === 'true_false' ) {
|
1003 |
+
$wpdb->delete(
|
1004 |
+
$wpdb->prefix . 'tutor_quiz_question_answers',
|
1005 |
+
array(
|
1006 |
+
'belongs_question_id' => $question_id,
|
1007 |
+
'belongs_question_type' => $question_type,
|
1008 |
+
)
|
1009 |
+
);
|
1010 |
$data_true_false = array(
|
1011 |
array(
|
1012 |
+
'belongs_question_id' => esc_sql( $question_id ),
|
1013 |
'belongs_question_type' => $question_type,
|
1014 |
+
'answer_title' => __( 'True', 'tutor' ),
|
1015 |
'is_correct' => $answer['true_false'] == 'true' ? 1 : 0,
|
1016 |
'answer_two_gap_match' => 'true',
|
1017 |
),
|
1018 |
array(
|
1019 |
+
'belongs_question_id' => esc_sql( $question_id ),
|
1020 |
'belongs_question_type' => $question_type,
|
1021 |
+
'answer_title' => __( 'False', 'tutor' ),
|
1022 |
'is_correct' => $answer['true_false'] == 'false' ? 1 : 0,
|
1023 |
'answer_two_gap_match' => 'false',
|
1024 |
),
|
1025 |
);
|
1026 |
|
1027 |
+
foreach ( $data_true_false as $true_false_data ) {
|
1028 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_question_answers', $true_false_data );
|
1029 |
}
|
1030 |
+
} elseif ( $question_type === 'multiple_choice' || $question_type === 'single_choice' || $question_type === 'ordering' ||
|
1031 |
+
$question_type === 'matching' || $question_type === 'image_matching' || $question_type === 'image_answering' ) {
|
|
|
1032 |
|
1033 |
$answer_data = array(
|
1034 |
'belongs_question_id' => sanitize_text_field( $question_id ),
|
1035 |
'belongs_question_type' => $question_type,
|
1036 |
'answer_title' => sanitize_text_field( $answer['answer_title'] ),
|
1037 |
+
'image_id' => isset( $answer['image_id'] ) ? $answer['image_id'] : 0,
|
1038 |
+
'answer_view_format' => isset( $answer['answer_view_format'] ) ? $answer['answer_view_format'] : 0,
|
1039 |
'answer_order' => $next_order_id,
|
1040 |
);
|
1041 |
+
if ( isset( $answer['matched_answer_title'] ) ) {
|
1042 |
$answer_data['answer_two_gap_match'] = sanitize_text_field( $answer['matched_answer_title'] );
|
1043 |
+
}
|
1044 |
|
1045 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_question_answers', $answer_data );
|
1046 |
|
1047 |
+
} elseif ( $question_type === 'fill_in_the_blank' ) {
|
1048 |
+
$wpdb->delete(
|
1049 |
+
$wpdb->prefix . 'tutor_quiz_question_answers',
|
1050 |
+
array(
|
1051 |
+
'belongs_question_id' => $question_id,
|
1052 |
+
'belongs_question_type' => $question_type,
|
1053 |
+
)
|
1054 |
+
);
|
1055 |
$answer_data = array(
|
1056 |
+
'belongs_question_id' => sanitize_text_field( $question_id ),
|
1057 |
'belongs_question_type' => $question_type,
|
1058 |
'answer_title' => sanitize_text_field( $answer['answer_title'] ),
|
1059 |
+
'answer_two_gap_match' => isset( $answer['answer_two_gap_match'] ) ? sanitize_text_field( trim( $answer['answer_two_gap_match'] ) ) : null,
|
1060 |
);
|
1061 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_question_answers', $answer_data );
|
1062 |
}
|
1063 |
}
|
1064 |
}
|
1068 |
|
1069 |
/**
|
1070 |
* Tutor Update Answer
|
1071 |
+
*
|
1072 |
+
* @since v.1.0.0
|
1073 |
*/
|
1074 |
+
public function tutor_update_quiz_answer_options() {
|
1075 |
tutils()->checking_nonce();
|
1076 |
|
1077 |
global $wpdb;
|
1078 |
|
1079 |
+
$answer_id = (int) sanitize_text_field( $_POST['tutor_quiz_answer_id'] );
|
1080 |
|
1081 |
+
if ( ! tutils()->can_user_manage( 'quiz_answer', $answer_id ) ) {
|
1082 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
1083 |
}
|
1084 |
|
1085 |
+
$questions = tutor_sanitize_data( $_POST['tutor_quiz_question'] );
|
1086 |
+
$answers = tutor_sanitize_data( $_POST['quiz_answer'] );
|
1087 |
|
1088 |
+
foreach ( $answers as $question_id => $answer ) {
|
1089 |
+
$question = tutor_utils()->avalue_dot( $question_id, $questions );
|
1090 |
$question_type = $question['question_type'];
|
1091 |
|
1092 |
+
if ( $question ) {
|
1093 |
+
if ( $question_type === 'multiple_choice' || $question_type === 'single_choice' || $question_type === 'ordering' || $question_type === 'matching' || $question_type === 'image_matching' || $question_type === 'fill_in_the_blank' || $question_type === 'image_answering' ) {
|
1094 |
|
1095 |
$answer_data = array(
|
1096 |
'belongs_question_id' => $question_id,
|
1097 |
'belongs_question_type' => $question_type,
|
1098 |
+
'answer_title' => sanitize_text_field( $answer['answer_title'] ),
|
1099 |
+
'image_id' => isset( $answer['image_id'] ) ? $answer['image_id'] : 0,
|
1100 |
+
'answer_view_format' => isset( $answer['answer_view_format'] ) ? sanitize_text_field( $answer['answer_view_format'] ) : '',
|
1101 |
);
|
1102 |
+
if ( isset( $answer['matched_answer_title'] ) ) {
|
1103 |
+
$answer_data['answer_two_gap_match'] = sanitize_text_field( $answer['matched_answer_title'] );
|
1104 |
}
|
1105 |
|
1106 |
+
if ( $question_type === 'fill_in_the_blank' ) {
|
1107 |
+
$answer_data['answer_two_gap_match'] = isset( $answer['answer_two_gap_match'] ) ? sanitize_text_field( trim( $answer['answer_two_gap_match'] ) ) : null;
|
1108 |
}
|
1109 |
|
1110 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_question_answers', $answer_data, array( 'answer_id' => $answer_id ) );
|
1111 |
}
|
1112 |
}
|
1113 |
}
|
1114 |
|
1115 |
+
// die(print_r($_POST));
|
1116 |
wp_send_json_success();
|
1117 |
+
}
|
1118 |
|
1119 |
+
public function tutor_quiz_builder_get_answers_by_question() {
|
1120 |
tutils()->checking_nonce();
|
1121 |
|
1122 |
global $wpdb;
|
1123 |
+
$question_id = sanitize_text_field( $_POST['question_id'] );
|
1124 |
+
$question_type = sanitize_text_field( $_POST['question_type'] );
|
1125 |
|
1126 |
+
if ( ! tutils()->can_user_manage( 'question', $question_id ) ) {
|
1127 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
1128 |
}
|
1129 |
|
1130 |
+
$question = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE question_id = %d ", $question_id ) );
|
1131 |
+
$answers = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers where belongs_question_id = %d AND belongs_question_type = %s order by answer_order asc ;", $question_id, esc_sql( $question_type ) ) );
|
1132 |
|
1133 |
ob_start();
|
1134 |
|
1135 |
+
switch ( $question_type ) {
|
1136 |
case 'true_false':
|
1137 |
+
echo '<label>' . __( 'Answer options & mark correct', 'tutor' ) . '</label>';
|
1138 |
break;
|
1139 |
case 'ordering':
|
1140 |
+
echo '<label>' . __( 'Make sure you’re saving the answers in the right order. Students will have to match this order exactly.', 'tutor' ) . '</label>';
|
1141 |
break;
|
1142 |
}
|
1143 |
|
1144 |
+
if ( is_array( $answers ) && count( $answers ) ) {
|
1145 |
+
foreach ( $answers as $answer ) {
|
1146 |
?>
|
1147 |
+
<div class="tutor-quiz-answer-wrap" data-answer-id="<?php echo esc_attr( $answer->answer_id ); ?>">
|
1148 |
+
<div class="tutor-quiz-answer">
|
1149 |
+
<span class="tutor-quiz-answer-title">
|
1150 |
+
<?php
|
1151 |
+
echo stripslashes( $answer->answer_title );
|
1152 |
+
if ( $answer->belongs_question_type === 'fill_in_the_blank' ) {
|
1153 |
+
echo ' (' . __( 'Answer', 'tutor' ) . ' : ';
|
1154 |
+
echo '<strong>' . stripslashes( $answer->answer_two_gap_match ) . '</strong>)';
|
1155 |
+
}
|
1156 |
+
if ( $answer->belongs_question_type === 'matching' ) {
|
1157 |
+
echo ' - ' . stripslashes( $answer->answer_two_gap_match );
|
1158 |
+
}
|
1159 |
+
?>
|
1160 |
+
</span>
|
1161 |
|
1162 |
<?php
|
1163 |
+
if ( $answer->image_id ) {
|
1164 |
+
echo '<span class="tutor-question-answer-image"><img src="' . wp_get_attachment_image_url( $answer->image_id ) . '" /> </span>';
|
1165 |
}
|
1166 |
+
if ( $question_type === 'true_false' || $question_type === 'single_choice' ) {
|
1167 |
?>
|
1168 |
+
<span class="tutor-quiz-answers-mark-correct-wrap">
|
1169 |
+
<input type="radio" name="mark_as_correct[<?php echo $answer->belongs_question_id; ?>]" value="<?php echo $answer->answer_id; ?>" title="<?php _e( 'Mark as correct', 'tutor' ); ?>" <?php checked( 1, $answer->is_correct ); ?> >
|
1170 |
+
</span>
|
1171 |
<?php
|
1172 |
+
} elseif ( $question_type === 'multiple_choice' ) {
|
1173 |
?>
|
1174 |
+
<span class="tutor-quiz-answers-mark-correct-wrap">
|
1175 |
+
<input type="checkbox" name="mark_as_correct[<?php echo $answer->belongs_question_id; ?>]" value="<?php echo $answer->answer_id; ?>" title="<?php _e( 'Mark as correct', 'tutor' ); ?>" <?php checked( 1, $answer->is_correct ); ?> >
|
1176 |
+
</span>
|
1177 |
<?php
|
1178 |
}
|
1179 |
?>
|
1180 |
+
<?php if ( 'true_false' != $question_type ) : ?>
|
1181 |
<span class="tutor-quiz-answer-edit">
|
1182 |
<a href="javascript:;"><i class="tutor-icon-pencil"></i> </a>
|
1183 |
</span>
|
1184 |
+
<?php endif; ?>
|
1185 |
+
<span class="tutor-quiz-answer-sort-icon"><i class="tutor-icon-menu-2"></i> </span>
|
1186 |
+
</div>
|
1187 |
+
<?php if ( 'true_false' != $question_type ) : ?>
|
1188 |
<div class="tutor-quiz-answer-trash-wrap">
|
1189 |
+
<a href="javascript:;" class="answer-trash-btn" data-answer-id="<?php echo esc_attr( $answer->answer_id ); ?>"><i class="tutor-icon-garbage"></i> </a>
|
1190 |
</div>
|
1191 |
+
<?php endif; ?>
|
1192 |
+
</div>
|
1193 |
<?php
|
1194 |
}
|
1195 |
}
|
1196 |
$output = ob_get_clean();
|
1197 |
|
1198 |
+
wp_send_json_success( array( 'output' => $output ) );
|
1199 |
}
|
1200 |
|
1201 |
+
public function tutor_quiz_builder_delete_answer() {
|
1202 |
tutils()->checking_nonce();
|
1203 |
|
1204 |
global $wpdb;
|
1205 |
+
$answer_id = sanitize_text_field( $_POST['answer_id'] );
|
1206 |
+
|
1207 |
+
if ( ! tutils()->can_user_manage( 'quiz_answer', $answer_id ) ) {
|
1208 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
1209 |
}
|
1210 |
|
1211 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_quiz_question_answers', array( 'answer_id' => esc_sql( $answer_id ) ) );
|
1212 |
wp_send_json_success();
|
1213 |
}
|
1214 |
|
1215 |
/**
|
1216 |
* Save quiz questions sorting
|
1217 |
*/
|
1218 |
+
public function tutor_quiz_question_sorting() {
|
1219 |
tutils()->checking_nonce();
|
1220 |
|
1221 |
global $wpdb;
|
1222 |
|
1223 |
+
$question_ids = tutor_utils()->avalue_dot( 'sorted_question_ids', tutor_sanitize_data($_POST) );
|
1224 |
+
if ( is_array( $question_ids ) && count( $question_ids ) ) {
|
1225 |
$i = 0;
|
1226 |
+
foreach ( $question_ids as $key => $question_id ) {
|
1227 |
+
if ( tutils()->can_user_manage( 'question', $question_id ) ) {
|
1228 |
$i++;
|
1229 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_questions', array( 'question_order' => $i ), array( 'question_id' => $question_id ) );
|
1230 |
}
|
1231 |
}
|
1232 |
}
|
1233 |
+
}
|
1234 |
|
1235 |
/**
|
1236 |
* Save sorting data for quiz answers
|
1237 |
*/
|
1238 |
+
public function tutor_quiz_answer_sorting() {
|
1239 |
tutils()->checking_nonce();
|
1240 |
|
1241 |
+
global $wpdb;
|
1242 |
|
1243 |
+
if ( ! empty( $_POST['sorted_answer_ids'] ) && is_array( $_POST['sorted_answer_ids'] ) && count( $_POST['sorted_answer_ids'] ) ) {
|
1244 |
+
$answer_ids = tutor_sanitize_data( $_POST['sorted_answer_ids'] );
|
1245 |
+
$i = 0;
|
1246 |
+
foreach ( $answer_ids as $key => $answer_id ) {
|
1247 |
+
if ( tutils()->can_user_manage( 'quiz_answer', $answer_id ) ) {
|
1248 |
$i++;
|
1249 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_question_answers', array( 'answer_order' => $i ), array( 'answer_id' => $answer_id ) );
|
1250 |
}
|
1251 |
+
}
|
1252 |
+
}
|
1253 |
+
}
|
1254 |
|
1255 |
/**
|
1256 |
* Mark answer as correct
|
1257 |
*/
|
1258 |
|
1259 |
+
public function tutor_mark_answer_as_correct() {
|
1260 |
tutils()->checking_nonce();
|
1261 |
|
1262 |
+
global $wpdb;
|
1263 |
|
1264 |
+
$answer_id = sanitize_text_field( $_POST['answer_id'] );
|
1265 |
+
$inputValue = sanitize_text_field( $_POST['inputValue'] );
|
1266 |
+
|
1267 |
+
if ( ! tutils()->can_user_manage( 'quiz_answer', $answer_id ) ) {
|
1268 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
1269 |
}
|
1270 |
|
1271 |
+
$answer = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE answer_id = %d LIMIT 0,1 ;", $answer_id ) );
|
1272 |
+
if ( $answer->belongs_question_type === 'single_choice' ) {
|
1273 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_question_answers', array( 'is_correct' => 0 ), array( 'belongs_question_id' => esc_sql( $answer->belongs_question_id ) ) );
|
1274 |
+
}
|
1275 |
+
$wpdb->update( $wpdb->prefix . 'tutor_quiz_question_answers', array( 'is_correct' => esc_sql( $inputValue ) ), array( 'answer_id' => esc_sql( $answer_id ) ) );
|
1276 |
+
}
|
1277 |
|
1278 |
/**
|
1279 |
* Update quiz settings from modal
|
1280 |
*
|
1281 |
* @since : v.1.0.0
|
1282 |
*/
|
1283 |
+
public function tutor_quiz_modal_update_settings() {
|
1284 |
tutils()->checking_nonce();
|
1285 |
+
// while creating quiz if creating step is not follow then it may throw error that why check added
|
1286 |
+
$quiz_id = ( isset( $_POST['quiz_id'] ) ) ? sanitize_text_field( $_POST['quiz_id'] ) : '';
|
1287 |
$current_topic_id = sanitize_text_field( $_POST['topic_id'] );
|
1288 |
+
$course_id = tutor_utils()->get_course_id_by( 'topic', sanitize_textarea_field( $current_topic_id ) );
|
1289 |
|
1290 |
$quiz_option = tutor_utils()->sanitize_array( $_POST['quiz_option'] );
|
1291 |
+
|
1292 |
+
if ( ! tutils()->can_user_manage( 'quiz', $quiz_id ) ) {
|
1293 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied', 'tutor' ) ) );
|
1294 |
}
|
1295 |
|
1296 |
+
update_post_meta( $quiz_id, 'tutor_quiz_option', $quiz_option );
|
1297 |
+
do_action( 'tutor_quiz_settings_updated', $quiz_id );
|
1298 |
|
1299 |
+
// @since 1.9.6
|
1300 |
ob_start();
|
1301 |
+
include tutor()->path . 'views/metabox/course-contents.php';
|
1302 |
$course_contents = ob_get_clean();
|
1303 |
|
1304 |
wp_send_json_success( array( 'course_contents' => $course_contents ) );
|
1305 |
}
|
1306 |
|
1307 |
|
1308 |
+
// =========================//
|
1309 |
+
// Front end stuffs
|
1310 |
+
// =========================//
|
1311 |
|
1312 |
/**
|
1313 |
* Rendering quiz for frontend
|
1314 |
+
*
|
1315 |
+
* @since v.1.0.0
|
1316 |
*/
|
1317 |
|
1318 |
+
public function tutor_render_quiz_content() {
|
1319 |
|
1320 |
tutils()->checking_nonce();
|
1321 |
|
1322 |
+
$quiz_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( 'quiz_id', $_POST ) );
|
1323 |
|
1324 |
+
if ( ! tutils()->has_enrolled_content_access( 'quiz', $quiz_id ) ) {
|
1325 |
+
wp_send_json_error( array( 'message' => __( 'Access Denied.', 'tutor' ) ) );
|
1326 |
}
|
1327 |
|
1328 |
ob_start();
|
1329 |
global $post;
|
1330 |
|
1331 |
+
$post = get_post( $quiz_id );
|
1332 |
+
setup_postdata( $post );
|
1333 |
+
// tutor_lesson_content();
|
1334 |
|
1335 |
single_quiz_contents();
|
1336 |
wp_reset_postdata();
|
1337 |
|
1338 |
$html = ob_get_clean();
|
1339 |
+
wp_send_json_success( array( 'html' => $html ) );
|
1340 |
}
|
1341 |
|
1342 |
+
}
|
classes/Quiz_Attempts_List.php
CHANGED
@@ -1,135 +1,139 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
if (! class_exists('Tutor_List_Table')){
|
8 |
-
include_once tutor()->path.'classes/Tutor_List_Table.php';
|
9 |
}
|
10 |
|
11 |
class Quiz_Attempts_List extends \Tutor_List_Table {
|
12 |
|
13 |
const QUIZ_ATTEMPT_PAGE = 'tutor_quiz_attempts';
|
14 |
|
15 |
-
function __construct(){
|
16 |
global $status, $page;
|
17 |
|
18 |
-
//Set parent defaults
|
19 |
-
parent::__construct(
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
24 |
}
|
25 |
|
26 |
-
function column_default($item, $column_name){
|
27 |
-
switch($column_name){
|
28 |
case 'unknown_col':
|
29 |
return $item->$column_name;
|
30 |
default:
|
31 |
-
//return print_r($item,true); //Show the whole array for troubleshooting purposes
|
32 |
}
|
33 |
}
|
34 |
|
35 |
-
function column_student($item){
|
36 |
$actions = array();
|
37 |
|
38 |
-
$actions['answer'] = sprintf('<a href="?page=%s&sub_page=%s&attempt_id=%s">'.__('Review', 'tutor').'</a>'
|
39 |
-
|
40 |
|
41 |
-
$quiz_title
|
42 |
-
$quiz_title .=
|
43 |
-
|
44 |
-
if ($item->attempt_ended_at){
|
45 |
-
$ended_ago_time
|
46 |
-
$attempt_started_at = date_format(date_create($item->attempt_started_at), 'd M, Y, h:i a');
|
47 |
-
$quiz_title
|
48 |
}
|
49 |
|
50 |
-
//Return the title contents
|
51 |
-
return sprintf(
|
|
|
52 |
$quiz_title,
|
53 |
$item->attempt_id,
|
54 |
-
$this->row_actions($actions)
|
55 |
);
|
56 |
}
|
57 |
|
58 |
-
function column_quiz($item){
|
59 |
return $item->post_title;
|
60 |
}
|
61 |
|
62 |
-
function column_cb($item){
|
63 |
return sprintf(
|
64 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
65 |
-
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label ("instructor")
|
66 |
-
/*$2%s*/ $item->attempt_id //The value of the checkbox should be the record's id
|
67 |
);
|
68 |
}
|
69 |
|
70 |
-
function column_course($item) {
|
71 |
-
$quiz = tutor_utils()->get_course_by_quiz($item->quiz_id);
|
72 |
|
73 |
-
if ($quiz) {
|
74 |
$title = get_the_title( $quiz->ID );
|
75 |
-
return
|
76 |
}
|
77 |
}
|
78 |
|
79 |
-
function column_total_questions($item) {
|
80 |
echo $item->total_questions;
|
81 |
}
|
82 |
|
83 |
-
function column_earned_marks($item){
|
84 |
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
|
89 |
-
|
90 |
-
|
91 |
|
92 |
-
|
93 |
-
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
return $output;
|
102 |
}
|
103 |
|
104 |
-
function column_attempt_status($item){
|
105 |
-
$status = ucwords(str_replace('quiz_', '', $item->attempt_status));
|
106 |
|
107 |
-
return
|
108 |
}
|
109 |
|
110 |
-
function get_columns(){
|
111 |
$columns = array(
|
112 |
-
'cb'
|
113 |
-
'student'
|
114 |
-
'quiz'
|
115 |
-
'course'
|
116 |
-
'total_questions'
|
117 |
-
'earned_marks'
|
118 |
-
//'attempt_status' => __('Attempt Status', 'tutor'),
|
119 |
);
|
120 |
return $columns;
|
121 |
}
|
122 |
|
123 |
function get_sortable_columns() {
|
124 |
$sortable_columns = array(
|
125 |
-
//'display_name' => array('title',false), //true means it's already sorted
|
126 |
);
|
127 |
return $sortable_columns;
|
128 |
}
|
129 |
|
130 |
function get_bulk_actions() {
|
131 |
$actions = array(
|
132 |
-
'delete'
|
133 |
);
|
134 |
return $actions;
|
135 |
}
|
@@ -137,13 +141,13 @@ class Quiz_Attempts_List extends \Tutor_List_Table {
|
|
137 |
function process_bulk_action() {
|
138 |
global $wpdb;
|
139 |
|
140 |
-
//Detect when a bulk action is being triggered...
|
141 |
-
if( 'delete' === $this->current_action() ) {
|
142 |
-
if ( empty($_GET['attempt']) || ! is_array($_GET['attempt'])){
|
143 |
return;
|
144 |
}
|
145 |
|
146 |
-
$attempt_ids = array_map('sanitize_text_field', $_GET['attempt']);
|
147 |
$attempt_ids = array_map( 'absint', $attempt_ids );
|
148 |
|
149 |
tutor_utils()->delete_quiz_attempt( $attempt_ids );
|
@@ -155,11 +159,11 @@ class Quiz_Attempts_List extends \Tutor_List_Table {
|
|
155 |
|
156 |
$per_page = 20;
|
157 |
|
158 |
-
$columns
|
159 |
-
$hidden
|
160 |
$sortable = $this->get_sortable_columns();
|
161 |
|
162 |
-
$this->_column_headers = array($columns, $hidden, $sortable);
|
163 |
$this->process_bulk_action();
|
164 |
|
165 |
$current_page = $this->get_pagenum();
|
@@ -168,39 +172,40 @@ class Quiz_Attempts_List extends \Tutor_List_Table {
|
|
168 |
$this->items = array();
|
169 |
|
170 |
if ( current_user_can( 'administrator' ) ) {
|
171 |
-
|
172 |
$this->items = tutor_utils()->get_quiz_attempts( ( $current_page - 1 ) * $per_page, $per_page, $search_filter, $course_filter, $date_filter, $order_filter );
|
173 |
|
174 |
-
$total_items = tutor_utils()->get_total_quiz_attempts();
|
175 |
|
176 |
-
} elseif ( current_user_can( 'tutor_instructor' ) ){
|
177 |
/**
|
178 |
* Instructors course specific quiz attempts
|
179 |
*/
|
180 |
-
$user_id
|
181 |
-
$get_assigned_courses_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id'
|
182 |
|
183 |
-
$custom_author_query = "
|
184 |
-
if (is_array($get_assigned_courses_ids) && count($get_assigned_courses_ids)){
|
185 |
-
$in_query_pre
|
186 |
-
$custom_author_query = "
|
187 |
}
|
188 |
$course_post_type = tutor()->course_post_type;
|
189 |
-
$get_course_ids
|
190 |
|
191 |
-
if (is_array($get_course_ids) && count($get_course_ids)){
|
192 |
|
193 |
-
$this->items = tutor_utils()->get_quiz_attempts_by_course_ids(( $current_page - 1 ) * $per_page, $per_page, $get_course_ids, $search_filter, $course_filter, $date_filter, $order_filter );
|
194 |
-
|
195 |
-
$total_items = tutor_utils()->get_total_quiz_attempts_by_course_ids($get_course_ids);
|
196 |
-
}
|
197 |
|
|
|
|
|
198 |
}
|
199 |
|
200 |
-
$this->set_pagination_args(
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
|
|
|
|
205 |
}
|
206 |
-
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
if ( ! class_exists( 'Tutor_List_Table' ) ) {
|
9 |
+
include_once tutor()->path . 'classes/Tutor_List_Table.php';
|
10 |
}
|
11 |
|
12 |
class Quiz_Attempts_List extends \Tutor_List_Table {
|
13 |
|
14 |
const QUIZ_ATTEMPT_PAGE = 'tutor_quiz_attempts';
|
15 |
|
16 |
+
function __construct() {
|
17 |
global $status, $page;
|
18 |
|
19 |
+
// Set parent defaults
|
20 |
+
parent::__construct(
|
21 |
+
array(
|
22 |
+
'singular' => 'attempt', // singular name of the listed records
|
23 |
+
'plural' => 'attempts', // plural name of the listed records
|
24 |
+
'ajax' => false, // does this table support ajax?
|
25 |
+
)
|
26 |
+
);
|
27 |
}
|
28 |
|
29 |
+
function column_default( $item, $column_name ) {
|
30 |
+
switch ( $column_name ) {
|
31 |
case 'unknown_col':
|
32 |
return $item->$column_name;
|
33 |
default:
|
34 |
+
// return print_r($item,true); //Show the whole array for troubleshooting purposes
|
35 |
}
|
36 |
}
|
37 |
|
38 |
+
function column_student( $item ) {
|
39 |
$actions = array();
|
40 |
|
41 |
+
$actions['answer'] = sprintf( '<a href="?page=%s&sub_page=%s&attempt_id=%s">' . __( 'Review', 'tutor' ) . '</a>', $_REQUEST['page'], 'view_attempt', $item->attempt_id );
|
42 |
+
// $actions['delete'] = sprintf('<a href="?page=%s&action=%s&attempt_id=%s">Delete</a>',$_REQUEST['page'],'delete',$item->attempt_id);
|
43 |
|
44 |
+
$quiz_title = '<p><strong>' . $item->display_name . '</strong></p>';
|
45 |
+
$quiz_title .= '<p>' . $item->user_email . '</p>';
|
46 |
+
// @since 1.9.5 instead of showing time ago showing original date time
|
47 |
+
if ( $item->attempt_ended_at ) {
|
48 |
+
$ended_ago_time = human_time_diff( strtotime( $item->attempt_ended_at ), tutor_time() ) . __( ' ago', 'tutor' );
|
49 |
+
$attempt_started_at = date_format( date_create( $item->attempt_started_at ), 'd M, Y, h:i a' );
|
50 |
+
$quiz_title .= '<span>' . $attempt_started_at . '</span>';
|
51 |
}
|
52 |
|
53 |
+
// Return the title contents
|
54 |
+
return sprintf(
|
55 |
+
'%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
|
56 |
$quiz_title,
|
57 |
$item->attempt_id,
|
58 |
+
$this->row_actions( $actions )
|
59 |
);
|
60 |
}
|
61 |
|
62 |
+
function column_quiz( $item ) {
|
63 |
return $item->post_title;
|
64 |
}
|
65 |
|
66 |
+
function column_cb( $item ) {
|
67 |
return sprintf(
|
68 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
69 |
+
/*$1%s*/ $this->_args['singular'], // Let's simply repurpose the table's singular label ("instructor")
|
70 |
+
/*$2%s*/ $item->attempt_id // The value of the checkbox should be the record's id
|
71 |
);
|
72 |
}
|
73 |
|
74 |
+
function column_course( $item ) {
|
75 |
+
$quiz = tutor_utils()->get_course_by_quiz( $item->quiz_id );
|
76 |
|
77 |
+
if ( $quiz ) {
|
78 |
$title = get_the_title( $quiz->ID );
|
79 |
+
return '<a href="' . admin_url( "post.php?post={$quiz->ID}&action=edit" ) . '">' . $title . '</a>';
|
80 |
}
|
81 |
}
|
82 |
|
83 |
+
function column_total_questions( $item ) {
|
84 |
echo $item->total_questions;
|
85 |
}
|
86 |
|
87 |
+
function column_earned_marks( $item ) {
|
88 |
|
89 |
+
if ( $item->attempt_status === 'review_required' ) {
|
90 |
+
$output = ' <span class="result-review-required">' . __( 'Under Review', 'tutor' ) . '</span>';
|
91 |
+
} else {
|
92 |
|
93 |
+
$pass_mark_percent = tutor_utils()->get_quiz_option( $item->quiz_id, 'passing_grade', 0 );
|
94 |
+
$earned_percentage = $item->earned_marks > 0 ? ( number_format( ( $item->earned_marks * 100 ) / $item->total_marks ) ) : 0;
|
95 |
|
96 |
+
$output = $item->earned_marks . __( ' out of ', 'tutor' ) . $item->total_marks . '<br/>';
|
97 |
+
$output .= '(' . $earned_percentage . '%)' . __( ' pass ', 'tutor' ) . '(' . $pass_mark_percent . ' %)<br/>';
|
98 |
|
99 |
+
if ( $earned_percentage >= $pass_mark_percent ) {
|
100 |
+
$output .= '<span class="result-pass"> ' . __( 'Pass', 'tutor' ) . '</span>';
|
101 |
+
} else {
|
102 |
+
$output .= '<span class="result-fail"> ' . __( 'Fail', 'tutor' ) . '</span>';
|
103 |
+
}
|
104 |
+
}
|
105 |
return $output;
|
106 |
}
|
107 |
|
108 |
+
function column_attempt_status( $item ) {
|
109 |
+
$status = ucwords( str_replace( 'quiz_', '', $item->attempt_status ) );
|
110 |
|
111 |
+
return '<span class="attempt-status-' . $item->attempt_status . '"> ' . $status . ' </span>';
|
112 |
}
|
113 |
|
114 |
+
function get_columns() {
|
115 |
$columns = array(
|
116 |
+
'cb' => '<input type="checkbox"/> ', // Render a checkbox instead of text
|
117 |
+
'student' => __( 'Students', 'tutor' ),
|
118 |
+
'quiz' => __( 'Quiz', 'tutor' ),
|
119 |
+
'course' => __( 'Course', 'tutor' ),
|
120 |
+
'total_questions' => __( 'Total Questions', 'tutor' ),
|
121 |
+
'earned_marks' => __( 'Earned Points', 'tutor' ),
|
122 |
+
// 'attempt_status' => __('Attempt Status', 'tutor'),
|
123 |
);
|
124 |
return $columns;
|
125 |
}
|
126 |
|
127 |
function get_sortable_columns() {
|
128 |
$sortable_columns = array(
|
129 |
+
// 'display_name' => array('title',false), //true means it's already sorted
|
130 |
);
|
131 |
return $sortable_columns;
|
132 |
}
|
133 |
|
134 |
function get_bulk_actions() {
|
135 |
$actions = array(
|
136 |
+
'delete' => 'Delete',
|
137 |
);
|
138 |
return $actions;
|
139 |
}
|
141 |
function process_bulk_action() {
|
142 |
global $wpdb;
|
143 |
|
144 |
+
// Detect when a bulk action is being triggered...
|
145 |
+
if ( 'delete' === $this->current_action() ) {
|
146 |
+
if ( empty( $_GET['attempt'] ) || ! is_array( $_GET['attempt'] ) ) {
|
147 |
return;
|
148 |
}
|
149 |
|
150 |
+
$attempt_ids = array_map( 'sanitize_text_field', $_GET['attempt'] );
|
151 |
$attempt_ids = array_map( 'absint', $attempt_ids );
|
152 |
|
153 |
tutor_utils()->delete_quiz_attempt( $attempt_ids );
|
159 |
|
160 |
$per_page = 20;
|
161 |
|
162 |
+
$columns = $this->get_columns();
|
163 |
+
$hidden = array();
|
164 |
$sortable = $this->get_sortable_columns();
|
165 |
|
166 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
167 |
$this->process_bulk_action();
|
168 |
|
169 |
$current_page = $this->get_pagenum();
|
172 |
$this->items = array();
|
173 |
|
174 |
if ( current_user_can( 'administrator' ) ) {
|
175 |
+
|
176 |
$this->items = tutor_utils()->get_quiz_attempts( ( $current_page - 1 ) * $per_page, $per_page, $search_filter, $course_filter, $date_filter, $order_filter );
|
177 |
|
178 |
+
$total_items = tutor_utils()->get_total_quiz_attempts();
|
179 |
|
180 |
+
} elseif ( current_user_can( 'tutor_instructor' ) ) {
|
181 |
/**
|
182 |
* Instructors course specific quiz attempts
|
183 |
*/
|
184 |
+
$user_id = get_current_user_id();
|
185 |
+
$get_assigned_courses_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id' and user_id = % d", $user_id ) );
|
186 |
|
187 |
+
$custom_author_query = " and {$wpdb->posts} . post_author = {$user_id}";
|
188 |
+
if ( is_array( $get_assigned_courses_ids ) && count( $get_assigned_courses_ids ) ) {
|
189 |
+
$in_query_pre = implode( ',', $get_assigned_courses_ids );
|
190 |
+
$custom_author_query = " and ( {$wpdb->posts} . post_author = {$user_id} or {$wpdb->posts} . ID IN( {$in_query_pre} ) ) ";
|
191 |
}
|
192 |
$course_post_type = tutor()->course_post_type;
|
193 |
+
$get_course_ids = $wpdb->get_col( "SELECT ID from {$wpdb->posts} where post_type = '{$course_post_type}' $custom_author_query; " );
|
194 |
|
195 |
+
if ( is_array( $get_course_ids ) && count( $get_course_ids ) ) {
|
196 |
|
197 |
+
$this->items = tutor_utils()->get_quiz_attempts_by_course_ids( ( $current_page - 1 ) * $per_page, $per_page, $get_course_ids, $search_filter, $course_filter, $date_filter, $order_filter );
|
|
|
|
|
|
|
198 |
|
199 |
+
$total_items = tutor_utils()->get_total_quiz_attempts_by_course_ids( $get_course_ids );
|
200 |
+
}
|
201 |
}
|
202 |
|
203 |
+
$this->set_pagination_args(
|
204 |
+
array(
|
205 |
+
'total_items' => $total_items,
|
206 |
+
'per_page' => $per_page,
|
207 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
208 |
+
)
|
209 |
+
);
|
210 |
}
|
211 |
+
}
|
classes/Shortcode.php
CHANGED
@@ -20,7 +20,7 @@ class Shortcode {
|
|
20 |
'pp-left-middle',
|
21 |
'pp-left-full'
|
22 |
);
|
23 |
-
|
24 |
public function __construct() {
|
25 |
add_shortcode('tutor_student_registration_form', array($this, 'student_registration_form'));
|
26 |
add_shortcode('tutor_dashboard', array($this, 'tutor_dashboard'));
|
@@ -170,13 +170,13 @@ class Shortcode {
|
|
170 |
|
171 |
$previous_page = $page>0 ? $current_page-1 : null;
|
172 |
$next_page = (is_array($next_instructors) && count($next_instructors)>0) ? $current_page+1 : null;
|
173 |
-
|
174 |
$layout = sanitize_text_field(tutils()->array_get('layout', $atts, ''));
|
175 |
$layout = in_array($layout, $this->instructor_layout) ? $layout : tutor_utils()->get_option('instructor_list_layout', $this->instructor_layout[0]);
|
176 |
|
177 |
$payload=array(
|
178 |
-
'instructors' => is_array($instructors) ? $instructors : array(),
|
179 |
-
'next_page' => $next_page,
|
180 |
'previous_page' => $previous_page,
|
181 |
'column_count' => sanitize_text_field(tutils()->array_get('column_per_row', $atts, 3)),
|
182 |
'layout' => $layout,
|
@@ -186,7 +186,7 @@ class Shortcode {
|
|
186 |
|
187 |
return $payload;
|
188 |
}
|
189 |
-
|
190 |
/**
|
191 |
* @param $atts
|
192 |
*
|
@@ -198,11 +198,11 @@ class Shortcode {
|
|
198 |
|
199 |
!is_array( $atts ) ? $atts = array() : 0;
|
200 |
|
201 |
-
$current_page = (int)tutor_utils()->array_get('instructor-page', $_GET, 1);
|
202 |
$current_page = $current_page>=1 ? $current_page : 1;
|
203 |
-
|
204 |
$show_filter = isset( $atts['filter'] ) ? $atts['filter']=='on' : tutor_utils()->get_option( 'instructor_list_show_filter', false );
|
205 |
-
|
206 |
// Get instructor list to sow
|
207 |
$payload = $this->prepare_instructor_list($current_page, $atts);
|
208 |
$payload['show_filter'] = $show_filter;
|
@@ -212,7 +212,7 @@ class Shortcode {
|
|
212 |
$content = ob_get_clean();
|
213 |
|
214 |
if($show_filter) {
|
215 |
-
|
216 |
$course_cats = get_terms( array(
|
217 |
'taxonomy' => 'course-category',
|
218 |
'hide_empty' => true,
|
@@ -222,7 +222,7 @@ class Shortcode {
|
|
222 |
$attributes = $payload;
|
223 |
unset( $attributes['instructors'] );
|
224 |
|
225 |
-
$payload = array(
|
226 |
'show_filter' => $show_filter,
|
227 |
'content' => $content,
|
228 |
'categories' => $course_cats,
|
@@ -232,7 +232,7 @@ class Shortcode {
|
|
232 |
ob_start();
|
233 |
|
234 |
tutor_load_template('shortcode.instructor-filter', $payload);
|
235 |
-
|
236 |
$content = ob_get_clean();
|
237 |
}
|
238 |
|
@@ -242,11 +242,11 @@ class Shortcode {
|
|
242 |
public function load_filtered_instructor() {
|
243 |
tutor_utils()->checking_nonce();
|
244 |
|
245 |
-
$attributes = (array)tutils()->array_get('attributes', $_POST, array());
|
246 |
$current_page = (int)sanitize_text_field(tutils()->array_get('current_page', $attributes, 1));
|
247 |
$keyword = (string)sanitize_text_field(tutils()->array_get('keyword', $_POST, ''));
|
248 |
|
249 |
-
$category = (array)tutils()->array_get('category', $_POST, array());
|
250 |
$category = array_filter($category, function($cat) {
|
251 |
return is_numeric($cat);
|
252 |
});
|
@@ -256,7 +256,7 @@ class Shortcode {
|
|
256 |
tutor_load_template('shortcode.tutor-instructor', $payload);
|
257 |
exit;
|
258 |
}
|
259 |
-
|
260 |
/**
|
261 |
* Show layout selection dashboard in instructor setting
|
262 |
*/
|
20 |
'pp-left-middle',
|
21 |
'pp-left-full'
|
22 |
);
|
23 |
+
|
24 |
public function __construct() {
|
25 |
add_shortcode('tutor_student_registration_form', array($this, 'student_registration_form'));
|
26 |
add_shortcode('tutor_dashboard', array($this, 'tutor_dashboard'));
|
170 |
|
171 |
$previous_page = $page>0 ? $current_page-1 : null;
|
172 |
$next_page = (is_array($next_instructors) && count($next_instructors)>0) ? $current_page+1 : null;
|
173 |
+
|
174 |
$layout = sanitize_text_field(tutils()->array_get('layout', $atts, ''));
|
175 |
$layout = in_array($layout, $this->instructor_layout) ? $layout : tutor_utils()->get_option('instructor_list_layout', $this->instructor_layout[0]);
|
176 |
|
177 |
$payload=array(
|
178 |
+
'instructors' => is_array($instructors) ? $instructors : array(),
|
179 |
+
'next_page' => $next_page,
|
180 |
'previous_page' => $previous_page,
|
181 |
'column_count' => sanitize_text_field(tutils()->array_get('column_per_row', $atts, 3)),
|
182 |
'layout' => $layout,
|
186 |
|
187 |
return $payload;
|
188 |
}
|
189 |
+
|
190 |
/**
|
191 |
* @param $atts
|
192 |
*
|
198 |
|
199 |
!is_array( $atts ) ? $atts = array() : 0;
|
200 |
|
201 |
+
$current_page = (int)tutor_utils()->array_get('instructor-page', tutor_sanitize_data($_GET), 1);
|
202 |
$current_page = $current_page>=1 ? $current_page : 1;
|
203 |
+
|
204 |
$show_filter = isset( $atts['filter'] ) ? $atts['filter']=='on' : tutor_utils()->get_option( 'instructor_list_show_filter', false );
|
205 |
+
|
206 |
// Get instructor list to sow
|
207 |
$payload = $this->prepare_instructor_list($current_page, $atts);
|
208 |
$payload['show_filter'] = $show_filter;
|
212 |
$content = ob_get_clean();
|
213 |
|
214 |
if($show_filter) {
|
215 |
+
|
216 |
$course_cats = get_terms( array(
|
217 |
'taxonomy' => 'course-category',
|
218 |
'hide_empty' => true,
|
222 |
$attributes = $payload;
|
223 |
unset( $attributes['instructors'] );
|
224 |
|
225 |
+
$payload = array(
|
226 |
'show_filter' => $show_filter,
|
227 |
'content' => $content,
|
228 |
'categories' => $course_cats,
|
232 |
ob_start();
|
233 |
|
234 |
tutor_load_template('shortcode.instructor-filter', $payload);
|
235 |
+
|
236 |
$content = ob_get_clean();
|
237 |
}
|
238 |
|
242 |
public function load_filtered_instructor() {
|
243 |
tutor_utils()->checking_nonce();
|
244 |
|
245 |
+
$attributes = (array)tutils()->array_get('attributes', tutor_sanitize_data($_POST), array());
|
246 |
$current_page = (int)sanitize_text_field(tutils()->array_get('current_page', $attributes, 1));
|
247 |
$keyword = (string)sanitize_text_field(tutils()->array_get('keyword', $_POST, ''));
|
248 |
|
249 |
+
$category = (array)tutils()->array_get('category', tutor_sanitize_data($_POST), array());
|
250 |
$category = array_filter($category, function($cat) {
|
251 |
return is_numeric($cat);
|
252 |
});
|
256 |
tutor_load_template('shortcode.tutor-instructor', $payload);
|
257 |
exit;
|
258 |
}
|
259 |
+
|
260 |
/**
|
261 |
* Show layout selection dashboard in instructor setting
|
262 |
*/
|
classes/Student.php
CHANGED
@@ -33,7 +33,7 @@ class Student {
|
|
33 |
// Action must be register, and registrtion must be enabled in dashoard
|
34 |
return;
|
35 |
}
|
36 |
-
|
37 |
//Checking nonce
|
38 |
tutor_utils()->checking_nonce();
|
39 |
|
@@ -45,19 +45,19 @@ class Student {
|
|
45 |
'password' => __('Password field is required', 'tutor'),
|
46 |
'password_confirmation' => __('Password Confirmation field is required', 'tutor'),
|
47 |
));
|
48 |
-
|
49 |
|
50 |
$validation_errors = array();
|
51 |
|
52 |
/*
|
53 |
*registration_errors
|
54 |
-
*push into validation_errors
|
55 |
*/
|
56 |
$errors = apply_filters('registration_errors',new \WP_Error,'','');
|
57 |
-
foreach ($errors->errors as $key => $value)
|
58 |
{
|
59 |
$validation_errors[$key] = $value[0];
|
60 |
-
|
61 |
}
|
62 |
|
63 |
foreach ($required_fields as $required_key => $required_value){
|
@@ -104,7 +104,7 @@ class Student {
|
|
104 |
|
105 |
do_action('tutor_after_student_signup', $user_id);
|
106 |
//since 1.9.8 do enroll if guest attempt to enroll
|
107 |
-
do_action( 'tutor_do_enroll_after_login_if_attempt', $_POST['tutor_course_enroll_attempt'] );
|
108 |
//Redirect page
|
109 |
$redirect_page = tutils()->array_get('redirect_to', $_REQUEST);
|
110 |
if ( ! $redirect_page){
|
@@ -133,7 +133,7 @@ class Student {
|
|
133 |
}
|
134 |
|
135 |
$user_id = get_current_user_id();
|
136 |
-
|
137 |
//Checking nonce
|
138 |
tutor_utils()->checking_nonce();
|
139 |
do_action('tutor_profile_update_before', $user_id);
|
33 |
// Action must be register, and registrtion must be enabled in dashoard
|
34 |
return;
|
35 |
}
|
36 |
+
|
37 |
//Checking nonce
|
38 |
tutor_utils()->checking_nonce();
|
39 |
|
45 |
'password' => __('Password field is required', 'tutor'),
|
46 |
'password_confirmation' => __('Password Confirmation field is required', 'tutor'),
|
47 |
));
|
48 |
+
|
49 |
|
50 |
$validation_errors = array();
|
51 |
|
52 |
/*
|
53 |
*registration_errors
|
54 |
+
*push into validation_errors
|
55 |
*/
|
56 |
$errors = apply_filters('registration_errors',new \WP_Error,'','');
|
57 |
+
foreach ($errors->errors as $key => $value)
|
58 |
{
|
59 |
$validation_errors[$key] = $value[0];
|
60 |
+
|
61 |
}
|
62 |
|
63 |
foreach ($required_fields as $required_key => $required_value){
|
104 |
|
105 |
do_action('tutor_after_student_signup', $user_id);
|
106 |
//since 1.9.8 do enroll if guest attempt to enroll
|
107 |
+
do_action( 'tutor_do_enroll_after_login_if_attempt', tutor_sanitize_data($_POST['tutor_course_enroll_attempt']) );
|
108 |
//Redirect page
|
109 |
$redirect_page = tutils()->array_get('redirect_to', $_REQUEST);
|
110 |
if ( ! $redirect_page){
|
133 |
}
|
134 |
|
135 |
$user_id = get_current_user_id();
|
136 |
+
|
137 |
//Checking nonce
|
138 |
tutor_utils()->checking_nonce();
|
139 |
do_action('tutor_profile_update_before', $user_id);
|
classes/Taxonomies.php
CHANGED
@@ -104,7 +104,7 @@ class Taxonomies{
|
|
104 |
<div class="form-field term-thumbnail-wrap">
|
105 |
<div id="course-category_thumbnail" style="float: left; margin-right: 10px;"><img src="<?php echo esc_url( $image ); ?>" width="60px" height="60px" /></div>
|
106 |
<div style="line-height: 60px;">
|
107 |
-
<input type="hidden" id="course-category_thumbnail_id" name="course_category_thumbnail_id" value="<?php echo
|
108 |
<button type="button" class="upload_image_button button"><?php esc_html_e( 'Upload/Add image', 'tutor' ); ?></button>
|
109 |
<button type="button" class="remove_image_button button"><?php esc_html_e( 'Remove image', 'tutor' ); ?></button>
|
110 |
</div>
|
@@ -210,10 +210,10 @@ class Taxonomies{
|
|
210 |
|
211 |
// Prevent esc_url from breaking spaces in urls for image embeds. Ref: https://core.trac.wordpress.org/ticket/23605 .
|
212 |
$image = str_replace( ' ', '%20', $image );
|
213 |
-
$columns .= '<img src="' . esc_url( $image ) . '" alt="' .
|
214 |
}
|
215 |
if ( 'handle' === $column ) {
|
216 |
-
$columns .= '<input type="hidden" name="term_id" value="' .
|
217 |
}
|
218 |
return $columns;
|
219 |
}
|
104 |
<div class="form-field term-thumbnail-wrap">
|
105 |
<div id="course-category_thumbnail" style="float: left; margin-right: 10px;"><img src="<?php echo esc_url( $image ); ?>" width="60px" height="60px" /></div>
|
106 |
<div style="line-height: 60px;">
|
107 |
+
<input type="hidden" id="course-category_thumbnail_id" name="course_category_thumbnail_id" value="<?php echo $thumbnail_id; ?>" />
|
108 |
<button type="button" class="upload_image_button button"><?php esc_html_e( 'Upload/Add image', 'tutor' ); ?></button>
|
109 |
<button type="button" class="remove_image_button button"><?php esc_html_e( 'Remove image', 'tutor' ); ?></button>
|
110 |
</div>
|
210 |
|
211 |
// Prevent esc_url from breaking spaces in urls for image embeds. Ref: https://core.trac.wordpress.org/ticket/23605 .
|
212 |
$image = str_replace( ' ', '%20', $image );
|
213 |
+
$columns .= '<img src="' . esc_url( $image ) . '" alt="' . __( 'Thumbnail', 'tutor' ) . '" class="wp-post-image" height="48" width="48" />';
|
214 |
}
|
215 |
if ( 'handle' === $column ) {
|
216 |
+
$columns .= '<input type="hidden" name="term_id" value="' . $id . '" />';
|
217 |
}
|
218 |
return $columns;
|
219 |
}
|
classes/Template.php
CHANGED
@@ -141,7 +141,7 @@ class Template extends Tutor_Base {
|
|
141 |
if ($wp_query->is_single && ! empty($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] === $this->course_post_type){
|
142 |
|
143 |
do_action( 'single_course_template_before_load', get_the_ID() );
|
144 |
-
|
145 |
$student_must_login_to_view_course = tutor_utils()->get_option('student_must_login_to_view_course');
|
146 |
if ($student_must_login_to_view_course){
|
147 |
if ( ! is_user_logged_in() ) {
|
@@ -223,7 +223,7 @@ class Template extends Tutor_Base {
|
|
223 |
if(get_post_meta($course_id, '_tutor_is_public_course', true)=='yes' && !tutor_utils()->is_course_purchasable($course_id)){
|
224 |
$template = tutor_get_template( 'single-lesson' );
|
225 |
}
|
226 |
-
|
227 |
return apply_filters('tutor_lesson_template', $template);
|
228 |
}
|
229 |
return $template;
|
@@ -334,7 +334,7 @@ class Template extends Tutor_Base {
|
|
334 |
global $wp;
|
335 |
$full_path = explode('/', trim( str_replace( get_home_url(), '', home_url( $wp->request ) ), '/' ) );
|
336 |
$template = tutor_get_template( end($full_path)=='create-course' ? implode('/', $full_path) : 'dashboard' );
|
337 |
-
|
338 |
/**
|
339 |
* Check page page permission
|
340 |
*
|
141 |
if ($wp_query->is_single && ! empty($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] === $this->course_post_type){
|
142 |
|
143 |
do_action( 'single_course_template_before_load', get_the_ID() );
|
144 |
+
|
145 |
$student_must_login_to_view_course = tutor_utils()->get_option('student_must_login_to_view_course');
|
146 |
if ($student_must_login_to_view_course){
|
147 |
if ( ! is_user_logged_in() ) {
|
223 |
if(get_post_meta($course_id, '_tutor_is_public_course', true)=='yes' && !tutor_utils()->is_course_purchasable($course_id)){
|
224 |
$template = tutor_get_template( 'single-lesson' );
|
225 |
}
|
226 |
+
|
227 |
return apply_filters('tutor_lesson_template', $template);
|
228 |
}
|
229 |
return $template;
|
334 |
global $wp;
|
335 |
$full_path = explode('/', trim( str_replace( get_home_url(), '', home_url( $wp->request ) ), '/' ) );
|
336 |
$template = tutor_get_template( end($full_path)=='create-course' ? implode('/', $full_path) : 'dashboard' );
|
337 |
+
|
338 |
/**
|
339 |
* Check page page permission
|
340 |
*
|
classes/TutorEDD.php
CHANGED
@@ -115,7 +115,7 @@ class TutorEDD extends Tutor_Base {
|
|
115 |
}
|
116 |
|
117 |
public function save_course_meta($post_ID) {
|
118 |
-
$product_id = tutor_utils()->avalue_dot('_tutor_course_product_id', $_POST);
|
119 |
|
120 |
if ($product_id !== '-1') {
|
121 |
$product_id = (int) $product_id;
|
115 |
}
|
116 |
|
117 |
public function save_course_meta($post_ID) {
|
118 |
+
$product_id = tutor_utils()->avalue_dot('_tutor_course_product_id', tutor_sanitize_data($_POST));
|
119 |
|
120 |
if ($product_id !== '-1') {
|
121 |
$product_id = (int) $product_id;
|
classes/Tutor_List_Table.php
CHANGED
@@ -7,8 +7,9 @@
|
|
7 |
*/
|
8 |
|
9 |
|
10 |
-
if ( ! defined( 'ABSPATH' ) )
|
11 |
exit;
|
|
|
12 |
|
13 |
/**
|
14 |
* Base class for displaying a list of items in an ajaxified HTML table.
|
@@ -94,10 +95,24 @@ class Tutor_List_Table {
|
|
94 |
*
|
95 |
* @var array
|
96 |
*/
|
97 |
-
protected $compat_methods = array(
|
98 |
-
'
|
99 |
-
'
|
100 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
/**
|
103 |
* Constructor.
|
@@ -125,21 +140,25 @@ class Tutor_List_Table {
|
|
125 |
* }
|
126 |
*/
|
127 |
public function __construct( $args = array() ) {
|
128 |
-
$args = wp_parse_args(
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
134 |
|
135 |
$this->screen = convert_to_screen( $args['screen'] );
|
136 |
|
137 |
add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
|
138 |
|
139 |
-
if (
|
140 |
$args['plural'] = $this->screen->base;
|
|
|
141 |
|
142 |
-
$args['plural']
|
143 |
$args['singular'] = sanitize_key( $args['singular'] );
|
144 |
|
145 |
$this->_args = $args;
|
@@ -152,7 +171,7 @@ class Tutor_List_Table {
|
|
152 |
if ( empty( $this->modes ) ) {
|
153 |
$this->modes = array(
|
154 |
'list' => __( 'List View' ),
|
155 |
-
'excerpt' => __( 'Excerpt View' )
|
156 |
);
|
157 |
}
|
158 |
}
|
@@ -241,6 +260,7 @@ class Tutor_List_Table {
|
|
241 |
|
242 |
/**
|
243 |
* Prepares the list of items for displaying.
|
|
|
244 |
* @uses Tutor_List_Table::set_pagination_args()
|
245 |
*
|
246 |
* @since 3.1.0
|
@@ -258,14 +278,18 @@ class Tutor_List_Table {
|
|
258 |
* @param array|string $args Array or string of arguments with information about the pagination.
|
259 |
*/
|
260 |
protected function set_pagination_args( $args ) {
|
261 |
-
$args = wp_parse_args(
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
|
|
|
|
|
|
266 |
|
267 |
-
if (
|
268 |
$args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
|
|
|
269 |
|
270 |
// Redirect if page number is invalid and headers are not already sent.
|
271 |
if ( ! headers_sent() && ! wp_doing_ajax() && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
|
@@ -290,8 +314,8 @@ class Tutor_List_Table {
|
|
290 |
return $this->get_pagenum();
|
291 |
}
|
292 |
|
293 |
-
if ( isset( $this->_pagination_args[$key] ) ) {
|
294 |
-
return $this->_pagination_args[$key];
|
295 |
}
|
296 |
}
|
297 |
|
@@ -303,7 +327,7 @@ class Tutor_List_Table {
|
|
303 |
* @return bool
|
304 |
*/
|
305 |
public function has_items() {
|
306 |
-
return !empty( $this->items );
|
307 |
}
|
308 |
|
309 |
/**
|
@@ -324,22 +348,27 @@ class Tutor_List_Table {
|
|
324 |
* @param string $input_id ID attribute value for the search input field.
|
325 |
*/
|
326 |
public function search_box( $text, $input_id ) {
|
327 |
-
if ( empty( $_REQUEST['s'] ) &&
|
328 |
-
|
|
|
329 |
|
330 |
$input_id = $input_id . '-search-input';
|
331 |
|
332 |
-
if ( ! empty( $_REQUEST['orderby'] ) )
|
333 |
echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
|
334 |
-
|
|
|
335 |
echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
|
336 |
-
|
|
|
337 |
echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
|
338 |
-
|
|
|
339 |
echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
|
|
|
340 |
?>
|
341 |
<p class="search-box">
|
342 |
-
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo $text; ?>:</label>
|
343 |
<input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s" value="<?php _admin_search_query(); ?>" />
|
344 |
<?php submit_button( $text, '', '', false, array( 'id' => 'search-submit' ) ); ?>
|
345 |
</p>
|
@@ -351,24 +380,24 @@ class Tutor_List_Table {
|
|
351 |
* get course list
|
352 |
* @param $selected | optional
|
353 |
*/
|
354 |
-
public function course_dropdown($selected = ''){
|
355 |
-
$courses = (current_user_can('administrator')) ? tutils()->get_courses() : tutils()->get_courses_by_instructor();
|
356 |
-
$markup
|
357 |
<div class="alignright">
|
358 |
-
<label>'.__('Course', 'tutor-pro').'</label>
|
359 |
<select class="tutor-assignment-course-sorting">
|
360 |
-
<option value="0">'.__('All','tutor').'</option>
|
361 |
OPTIONS_PLACEHOLDER
|
362 |
-
</select>
|
363 |
</div>
|
364 |
';
|
365 |
$options = '';
|
366 |
foreach ( $courses as $course ) {
|
367 |
-
$options .= '<option value="' . $course->ID . '" ' . selected( $selected
|
368 |
}
|
369 |
-
|
370 |
$content = str_replace( 'OPTIONS_PLACEHOLDER', $options, $markup );
|
371 |
-
echo $content;
|
372 |
}
|
373 |
|
374 |
/**
|
@@ -377,22 +406,22 @@ class Tutor_List_Table {
|
|
377 |
* @param $selected | optional
|
378 |
*/
|
379 |
|
380 |
-
public function sorting_order($selected='DESC'){
|
381 |
-
$orders
|
382 |
-
$markup
|
383 |
<div class="alignright">
|
384 |
-
<label>'.__('Sort By', 'tutor').'</label>
|
385 |
<select class="tutor-assignment-order-sorting">
|
386 |
OPTION_PLACEHOLDER
|
387 |
-
</select>
|
388 |
</div>
|
389 |
';
|
390 |
$options = '';
|
391 |
-
foreach( $orders as $order ) {
|
392 |
-
$options .= '<option value="' . $order . '" '. selected( $selected, $order, false ) . '> '. __( $order, 'tutor' ) . ' </option>';
|
393 |
-
}
|
394 |
$content = str_replace( 'OPTION_PLACEHOLDER', $options, $markup );
|
395 |
-
echo $content;
|
396 |
}
|
397 |
/**
|
398 |
* @since 1.8.0
|
@@ -404,14 +433,14 @@ class Tutor_List_Table {
|
|
404 |
$placeholder = __( get_option( 'date_format' ), 'tutor' );
|
405 |
$date_filter = sanitize_text_field( tutor_utils()->array_get( 'date', $_GET, '' ) );
|
406 |
$date_input = '' !== $date_filter ? tutor_get_formated_date( get_option( 'date_format' ), $date_filter ) : '';
|
407 |
-
$markup
|
408 |
<div class="alignright assignment-date-box">
|
409 |
-
<label>'.__('Date', 'tutor').'</label>
|
410 |
<input type="" class="tutor_date_picker tutor-assignment-date-sorting" placeholder="' . $placeholder . '" value="' . $date_input . '">
|
411 |
<i class="tutor-icon-calendar"></i>
|
412 |
</div>
|
413 |
-
';
|
414 |
-
echo $markup;
|
415 |
}
|
416 |
|
417 |
/**
|
@@ -445,17 +474,18 @@ class Tutor_List_Table {
|
|
445 |
*/
|
446 |
$views = apply_filters( "views_{$this->screen->id}", $views );
|
447 |
|
448 |
-
if ( empty( $views ) )
|
449 |
return;
|
|
|
450 |
|
451 |
$this->screen->render_screen_reader_content( 'heading_views' );
|
452 |
|
453 |
-
echo
|
454 |
foreach ( $views as $class => $view ) {
|
455 |
$views[ $class ] = "\t<li class='$class'>$view";
|
456 |
}
|
457 |
-
echo implode(
|
458 |
-
echo
|
459 |
}
|
460 |
|
461 |
/**
|
@@ -494,28 +524,29 @@ class Tutor_List_Table {
|
|
494 |
* @param array $actions An array of the available bulk actions.
|
495 |
*/
|
496 |
$this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
|
497 |
-
$two
|
498 |
} else {
|
499 |
$two = '2';
|
500 |
}
|
501 |
|
502 |
-
if ( empty( $this->_actions ) )
|
503 |
return;
|
|
|
504 |
|
505 |
echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>';
|
506 |
-
echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . "
|
507 |
-
echo '<option value="-1">' . __( 'Bulk Actions', 'tutor' ) .
|
508 |
|
509 |
foreach ( $this->_actions as $name => $title ) {
|
510 |
$class = 'edit' === $name ? ' class="hide-if-no-js"' : '';
|
511 |
|
512 |
-
echo
|
513 |
}
|
514 |
|
515 |
-
echo
|
516 |
|
517 |
-
submit_button( __( 'Apply' ), 'action', '', false, array( 'id' =>
|
518 |
-
echo
|
519 |
}
|
520 |
|
521 |
/**
|
@@ -526,14 +557,17 @@ class Tutor_List_Table {
|
|
526 |
* @return string|false The action name or False if no action was selected
|
527 |
*/
|
528 |
public function current_action() {
|
529 |
-
if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) )
|
530 |
return false;
|
|
|
531 |
|
532 |
-
if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
|
533 |
return $_REQUEST['action'];
|
|
|
534 |
|
535 |
-
if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
|
536 |
return $_REQUEST['action2'];
|
|
|
537 |
|
538 |
return false;
|
539 |
}
|
@@ -544,27 +578,29 @@ class Tutor_List_Table {
|
|
544 |
* @since 3.1.0
|
545 |
*
|
546 |
* @param array $actions The list of actions
|
547 |
-
* @param bool
|
548 |
* @return string
|
549 |
*/
|
550 |
protected function row_actions( $actions, $always_visible = false ) {
|
551 |
$action_count = count( $actions );
|
552 |
-
$i
|
553 |
|
554 |
-
if (
|
555 |
return '';
|
|
|
556 |
|
557 |
-
$out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
|
558 |
foreach ( $actions as $action => $link ) {
|
559 |
++$i;
|
560 |
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
561 |
-
$out
|
562 |
}
|
563 |
$out .= '</div>';
|
564 |
|
565 |
$out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>';
|
566 |
|
567 |
-
return $out;
|
|
|
568 |
}
|
569 |
|
570 |
/**
|
@@ -596,16 +632,21 @@ class Tutor_List_Table {
|
|
596 |
if ( ! isset( $_GET['post_status'] ) || 'trash' !== $_GET['post_status'] ) {
|
597 |
$extra_checks .= " AND post_status != 'trash'";
|
598 |
} elseif ( isset( $_GET['post_status'] ) ) {
|
599 |
-
$extra_checks = $wpdb->prepare( ' AND post_status = %s', $_GET['post_status'] );
|
600 |
}
|
601 |
|
602 |
-
$months = $wpdb->get_results(
|
|
|
|
|
603 |
SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
|
604 |
FROM $wpdb->posts
|
605 |
WHERE post_type = %s
|
606 |
$extra_checks
|
607 |
ORDER BY post_date DESC
|
608 |
-
",
|
|
|
|
|
|
|
609 |
|
610 |
/**
|
611 |
* Filters the 'Months' drop-down results.
|
@@ -619,8 +660,9 @@ class Tutor_List_Table {
|
|
619 |
|
620 |
$month_count = count( $months );
|
621 |
|
622 |
-
if (
|
623 |
return;
|
|
|
624 |
|
625 |
$m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
|
626 |
?>
|
@@ -629,13 +671,15 @@ class Tutor_List_Table {
|
|
629 |
<option<?php selected( $m, 0 ); ?> value="0"><?php _e( 'All dates' ); ?></option>
|
630 |
<?php
|
631 |
foreach ( $months as $arc_row ) {
|
632 |
-
if ( 0 == $arc_row->year )
|
633 |
continue;
|
|
|
634 |
|
635 |
$month = zeroise( $arc_row->month, 2 );
|
636 |
-
$year
|
637 |
|
638 |
-
printf(
|
|
|
639 |
selected( $m, $year . $month, false ),
|
640 |
esc_attr( $arc_row->year . $month ),
|
641 |
/* translators: 1: month name, 2: 4-digit year */
|
@@ -661,10 +705,11 @@ class Tutor_List_Table {
|
|
661 |
<?php
|
662 |
foreach ( $this->modes as $mode => $title ) {
|
663 |
$classes = array( 'view-' . $mode );
|
664 |
-
if ( $current_mode === $mode )
|
665 |
$classes[] = 'current';
|
|
|
666 |
printf(
|
667 |
-
"<a href='%s' class='%s' id='view-switch-$mode'><span class='screen-reader-text'>%s</span></a
|
668 |
esc_url( add_query_arg( 'mode', $mode ) ),
|
669 |
implode( ' ', $classes ),
|
670 |
$title
|
@@ -687,39 +732,60 @@ class Tutor_List_Table {
|
|
687 |
$approved_comments = get_comments_number();
|
688 |
|
689 |
$approved_comments_number = number_format_i18n( $approved_comments );
|
690 |
-
$pending_comments_number
|
691 |
|
692 |
$approved_only_phrase = sprintf( _n( '%s comment', '%s comments', $approved_comments ), $approved_comments_number );
|
693 |
-
$approved_phrase
|
694 |
-
$pending_phrase
|
695 |
|
696 |
// No comments at all.
|
697 |
if ( ! $approved_comments && ! $pending_comments ) {
|
698 |
-
printf(
|
|
|
699 |
__( 'No comments' )
|
700 |
);
|
701 |
// Approved comments have different display depending on some conditions.
|
702 |
} elseif ( $approved_comments ) {
|
703 |
-
printf(
|
704 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
705 |
$approved_comments_number,
|
706 |
$pending_comments ? $approved_phrase : $approved_only_phrase
|
707 |
);
|
708 |
} else {
|
709 |
-
printf(
|
|
|
710 |
$approved_comments_number,
|
711 |
$pending_comments ? __( 'No approved comments' ) : __( 'No comments' )
|
712 |
);
|
713 |
}
|
714 |
|
715 |
if ( $pending_comments ) {
|
716 |
-
printf(
|
717 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
718 |
$pending_comments_number,
|
719 |
$pending_phrase
|
720 |
);
|
721 |
} else {
|
722 |
-
printf(
|
|
|
723 |
$pending_comments_number,
|
724 |
$approved_comments ? __( 'No pending comments' ) : __( 'No comments' )
|
725 |
);
|
@@ -736,8 +802,9 @@ class Tutor_List_Table {
|
|
736 |
public function get_pagenum() {
|
737 |
$pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
|
738 |
|
739 |
-
if ( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] )
|
740 |
$pagenum = $this->_pagination_args['total_pages'];
|
|
|
741 |
|
742 |
return max( 1, $pagenum );
|
743 |
}
|
@@ -753,8 +820,9 @@ class Tutor_List_Table {
|
|
753 |
*/
|
754 |
protected function get_items_per_page( $option, $default = 20 ) {
|
755 |
$per_page = (int) get_user_option( $option );
|
756 |
-
if ( empty( $per_page ) || $per_page < 1 )
|
757 |
$per_page = $default;
|
|
|
758 |
|
759 |
/**
|
760 |
* Filters the number of items to be displayed on each page of the list table.
|
@@ -784,8 +852,8 @@ class Tutor_List_Table {
|
|
784 |
return;
|
785 |
}
|
786 |
|
787 |
-
$total_items
|
788 |
-
$total_pages
|
789 |
$infinite_scroll = false;
|
790 |
if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
|
791 |
$infinite_scroll = $this->_pagination_args['infinite_scroll'];
|
@@ -797,7 +865,7 @@ class Tutor_List_Table {
|
|
797 |
|
798 |
$output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';
|
799 |
|
800 |
-
$current
|
801 |
$removable_query_args = wp_removable_query_args();
|
802 |
|
803 |
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
|
@@ -813,7 +881,7 @@ class Tutor_List_Table {
|
|
813 |
|
814 |
if ( $current == 1 ) {
|
815 |
$disable_first = true;
|
816 |
-
$disable_prev
|
817 |
}
|
818 |
if ( $current == 2 ) {
|
819 |
$disable_first = true;
|
@@ -829,7 +897,8 @@ class Tutor_List_Table {
|
|
829 |
if ( $disable_first ) {
|
830 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">«</span>';
|
831 |
} else {
|
832 |
-
$page_links[] = sprintf(
|
|
|
833 |
esc_url( remove_query_arg( 'paged', $current_url ) ),
|
834 |
__( 'First page' ),
|
835 |
'«'
|
@@ -839,8 +908,9 @@ class Tutor_List_Table {
|
|
839 |
if ( $disable_prev ) {
|
840 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">‹</span>';
|
841 |
} else {
|
842 |
-
$page_links[] = sprintf(
|
843 |
-
|
|
|
844 |
__( 'Previous page' ),
|
845 |
'‹'
|
846 |
);
|
@@ -850,20 +920,22 @@ class Tutor_List_Table {
|
|
850 |
$html_current_page = $current;
|
851 |
$total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
|
852 |
} else {
|
853 |
-
$html_current_page = sprintf(
|
|
|
854 |
'<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
|
855 |
$current,
|
856 |
strlen( $total_pages )
|
857 |
);
|
858 |
}
|
859 |
-
$html_total_pages = sprintf(
|
860 |
-
$page_links[]
|
861 |
|
862 |
if ( $disable_next ) {
|
863 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">›</span>';
|
864 |
} else {
|
865 |
-
$page_links[] = sprintf(
|
866 |
-
|
|
|
867 |
__( 'Next page' ),
|
868 |
'›'
|
869 |
);
|
@@ -872,7 +944,8 @@ class Tutor_List_Table {
|
|
872 |
if ( $disable_last ) {
|
873 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">»</span>';
|
874 |
} else {
|
875 |
-
$page_links[] = sprintf(
|
|
|
876 |
esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
|
877 |
__( 'Last page' ),
|
878 |
'»'
|
@@ -883,16 +956,16 @@ class Tutor_List_Table {
|
|
883 |
if ( ! empty( $infinite_scroll ) ) {
|
884 |
$pagination_links_class .= ' hide-if-js';
|
885 |
}
|
886 |
-
$output .=
|
887 |
|
888 |
if ( $total_pages ) {
|
889 |
$page_class = $total_pages < 2 ? ' one-page' : '';
|
890 |
} else {
|
891 |
$page_class = ' no-pages';
|
892 |
}
|
893 |
-
$this->_pagination =
|
894 |
|
895 |
-
echo $this->_pagination;
|
896 |
}
|
897 |
|
898 |
/**
|
@@ -933,7 +1006,7 @@ class Tutor_List_Table {
|
|
933 |
*/
|
934 |
protected function get_default_primary_column_name() {
|
935 |
$columns = $this->get_columns();
|
936 |
-
$column
|
937 |
|
938 |
if ( empty( $columns ) ) {
|
939 |
return $column;
|
@@ -978,7 +1051,7 @@ class Tutor_List_Table {
|
|
978 |
// If the primary column doesn't exist fall back to the
|
979 |
// first non-checkbox column.
|
980 |
if ( ! isset( $columns[ $default ] ) ) {
|
981 |
-
$default =
|
982 |
}
|
983 |
|
984 |
/**
|
@@ -989,7 +1062,7 @@ class Tutor_List_Table {
|
|
989 |
* @param string $default Column name default for the specific list table, e.g. 'name'.
|
990 |
* @param string $context Screen ID for specific list table, e.g. 'plugins'.
|
991 |
*/
|
992 |
-
$column
|
993 |
|
994 |
if ( empty( $column ) || ! isset( $columns[ $column ] ) ) {
|
995 |
$column = $default;
|
@@ -1019,7 +1092,7 @@ class Tutor_List_Table {
|
|
1019 |
}
|
1020 |
|
1021 |
$columns = get_column_headers( $this->screen );
|
1022 |
-
$hidden
|
1023 |
|
1024 |
$sortable_columns = $this->get_sortable_columns();
|
1025 |
/**
|
@@ -1032,21 +1105,23 @@ class Tutor_List_Table {
|
|
1032 |
*
|
1033 |
* @param array $sortable_columns An array of sortable columns.
|
1034 |
*/
|
1035 |
-
$_sortable = apply_filters(
|
1036 |
|
1037 |
$sortable = array();
|
1038 |
foreach ( $_sortable as $id => $data ) {
|
1039 |
-
if ( empty( $data ) )
|
1040 |
continue;
|
|
|
1041 |
|
1042 |
$data = (array) $data;
|
1043 |
-
if ( !isset( $data[1] ) )
|
1044 |
$data[1] = false;
|
|
|
1045 |
|
1046 |
-
$sortable[$id] = $data;
|
1047 |
}
|
1048 |
|
1049 |
-
$primary
|
1050 |
$this->_column_headers = array( $columns, $hidden, $sortable, $primary );
|
1051 |
|
1052 |
return $this->_column_headers;
|
@@ -1061,7 +1136,7 @@ class Tutor_List_Table {
|
|
1061 |
*/
|
1062 |
public function get_column_count() {
|
1063 |
list ( $columns, $hidden ) = $this->get_column_info();
|
1064 |
-
$hidden
|
1065 |
return count( $columns ) - count( $hidden );
|
1066 |
}
|
1067 |
|
@@ -1081,7 +1156,7 @@ class Tutor_List_Table {
|
|
1081 |
$current_url = remove_query_arg( 'paged', $current_url );
|
1082 |
|
1083 |
if ( isset( $_GET['orderby'] ) ) {
|
1084 |
-
$current_orderby = $_GET['orderby'];
|
1085 |
} else {
|
1086 |
$current_orderby = '';
|
1087 |
}
|
@@ -1094,8 +1169,7 @@ class Tutor_List_Table {
|
|
1094 |
|
1095 |
if ( ! empty( $columns['cb'] ) ) {
|
1096 |
static $cb_counter = 1;
|
1097 |
-
$columns['cb']
|
1098 |
-
. '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
|
1099 |
$cb_counter++;
|
1100 |
}
|
1101 |
|
@@ -1106,24 +1180,25 @@ class Tutor_List_Table {
|
|
1106 |
$class[] = 'hidden';
|
1107 |
}
|
1108 |
|
1109 |
-
if ( 'cb' === $column_key )
|
1110 |
$class[] = 'check-column';
|
1111 |
-
elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) )
|
1112 |
$class[] = 'num';
|
|
|
1113 |
|
1114 |
if ( $column_key === $primary ) {
|
1115 |
$class[] = 'column-primary';
|
1116 |
}
|
1117 |
|
1118 |
-
if ( isset( $sortable[$column_key] ) ) {
|
1119 |
-
list( $orderby, $desc_first ) = $sortable[$column_key];
|
1120 |
|
1121 |
if ( $current_orderby === $orderby ) {
|
1122 |
-
$order
|
1123 |
$class[] = 'sorted';
|
1124 |
$class[] = $current_order;
|
1125 |
} else {
|
1126 |
-
$order
|
1127 |
$class[] = 'sortable';
|
1128 |
$class[] = $desc_first ? 'asc' : 'desc';
|
1129 |
}
|
@@ -1131,14 +1206,15 @@ class Tutor_List_Table {
|
|
1131 |
$column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
|
1132 |
}
|
1133 |
|
1134 |
-
$tag
|
1135 |
$scope = ( 'th' === $tag ) ? 'scope="col"' : '';
|
1136 |
-
$id
|
1137 |
|
1138 |
-
if ( !empty( $class ) )
|
1139 |
$class = "class='" . join( ' ', $class ) . "'";
|
|
|
1140 |
|
1141 |
-
echo "<$tag $scope $id $class>$column_display_name</$tag>";
|
1142 |
}
|
1143 |
}
|
1144 |
|
@@ -1147,27 +1223,30 @@ class Tutor_List_Table {
|
|
1147 |
*
|
1148 |
* @since 3.1.0
|
1149 |
*/
|
1150 |
-
public function display($enable_sorting_field_with_bulk_action = false) {
|
1151 |
$singular = $this->_args['singular'];
|
1152 |
if ( $enable_sorting_field_with_bulk_action ) {
|
1153 |
-
$this->display_sorting_fields(
|
1154 |
} else {
|
1155 |
-
$this->display_tablenav('top');
|
1156 |
}
|
1157 |
|
1158 |
$this->screen->render_screen_reader_content( 'heading_list' );
|
1159 |
?>
|
1160 |
-
<table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
|
1161 |
<thead>
|
1162 |
<tr>
|
1163 |
<?php $this->print_column_headers(); ?>
|
1164 |
</tr>
|
1165 |
</thead>
|
1166 |
|
1167 |
-
<tbody id="the-list"
|
|
|
1168 |
if ( $singular ) {
|
1169 |
-
echo
|
1170 |
-
}
|
|
|
|
|
1171 |
<?php $this->display_rows_or_placeholder(); ?>
|
1172 |
</tbody>
|
1173 |
|
@@ -1206,11 +1285,12 @@ class Tutor_List_Table {
|
|
1206 |
?>
|
1207 |
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
1208 |
|
1209 |
-
<?php if ( $this->has_items() ): ?>
|
1210 |
<div class="alignleft actions bulkactions">
|
1211 |
<?php $this->bulk_actions( $which ); ?>
|
1212 |
</div>
|
1213 |
-
|
|
|
1214 |
$this->extra_tablenav( $which );
|
1215 |
$this->pagination( $which );
|
1216 |
?>
|
@@ -1222,85 +1302,86 @@ class Tutor_List_Table {
|
|
1222 |
|
1223 |
/**
|
1224 |
* Sorting fields added on tutor table
|
1225 |
-
*
|
1226 |
* Course id | Search | Date | Order
|
1227 |
-
*
|
1228 |
* @since 1.9.5
|
1229 |
*/
|
1230 |
protected function display_sorting_fields() {
|
1231 |
-
$search_filter
|
1232 |
-
$course_id
|
1233 |
-
$date_filter
|
1234 |
-
$order_filter
|
1235 |
-
$which
|
1236 |
?>
|
1237 |
<div class="tutor-sorting-bulk-action-wrapper">
|
1238 |
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
1239 |
-
<?php if ( $this->has_items() ): ?>
|
1240 |
<div class="alignleft actions bulkactions">
|
1241 |
<?php $this->bulk_actions( $which ); ?>
|
1242 |
</div>
|
1243 |
-
|
|
|
1244 |
$this->extra_tablenav( $which );
|
1245 |
|
1246 |
?>
|
1247 |
</div>
|
1248 |
-
|
1249 |
<div class="tutor-admin-search-box-container" style="margin:0px;">
|
1250 |
|
1251 |
<div>
|
1252 |
-
<div class="menu-label"><?php _e('Courses', 'tutor'); ?></div>
|
1253 |
<div>
|
1254 |
<?php
|
1255 |
-
//get courses
|
1256 |
-
$courses = (current_user_can('administrator')) ? tutils()->get_courses() : tutils()->get_courses_by_instructor();
|
1257 |
?>
|
1258 |
|
1259 |
<select class="tutor-report-category tutor-announcement-course-sorting">
|
1260 |
-
|
1261 |
-
<option value=""><?php _e('All', 'tutor'); ?></option>
|
1262 |
-
|
1263 |
-
<?php if ($courses) : ?>
|
1264 |
-
<?php foreach ($courses as $course) : ?>
|
1265 |
-
<option value="<?php echo esc_attr($course->ID) ?>" <?php selected($course_id, $course->ID, 'selected') ?>>
|
1266 |
-
<?php echo $course->post_title; ?>
|
1267 |
</option>
|
1268 |
<?php endforeach; ?>
|
1269 |
<?php else : ?>
|
1270 |
-
<option value=""><?php _e('No course found', 'tutor'); ?></option>
|
1271 |
<?php endif; ?>
|
1272 |
</select>
|
1273 |
</div>
|
1274 |
</div>
|
1275 |
|
1276 |
<div>
|
1277 |
-
<div class="menu-label"><?php _e('Sort By', 'tutor'); ?></div>
|
1278 |
<div>
|
1279 |
<select class="tutor-report-sort tutor-announcement-order-sorting">
|
1280 |
-
<option <?php selected($order_filter, 'ASC'); ?>>ASC</option>
|
1281 |
-
<option <?php selected($order_filter, 'DESC'); ?>>DESC</option>
|
1282 |
</select>
|
1283 |
</div>
|
1284 |
</div>
|
1285 |
|
1286 |
<div>
|
1287 |
-
<div class="menu-label"><?php _e('Date', 'tutor'); ?></div>
|
1288 |
<div class="date-range-input">
|
1289 |
-
<input type="text" class="tutor_date_picker tutor-announcement-date-sorting" id="tutor-announcement-datepicker" placeholder="<?php _e( get_option( 'date_format' )
|
1290 |
<i class="tutor-icon-calendar"></i>
|
1291 |
</div>
|
1292 |
</div>
|
1293 |
|
1294 |
<div class="tutor-search-form-group">
|
1295 |
-
<div class="menu-label"><?php _e('Search', 'tutor'); ?></div>
|
1296 |
<div style="position:relative;">
|
1297 |
-
<input type="text" name="search" class="tutor-report-search tutor-announcement-search-field" value="<?php echo $search_filter; ?>" autocomplete="off" placeholder="<?php _e('Search', 'tutor'); ?>" />
|
1298 |
<button class="tutor-report-search-btn tutor-announcement-search-sorting"><i class="tutor-icon-magnifying-glass-1"></i></button>
|
1299 |
</div>
|
1300 |
</div>
|
1301 |
-
|
1302 |
-
</div>
|
1303 |
-
</div>
|
1304 |
<?php
|
1305 |
}
|
1306 |
|
@@ -1334,8 +1415,9 @@ class Tutor_List_Table {
|
|
1334 |
* @since 3.1.0
|
1335 |
*/
|
1336 |
public function display_rows() {
|
1337 |
-
foreach ( $this->items as $item )
|
1338 |
$this->single_row( $item );
|
|
|
1339 |
}
|
1340 |
|
1341 |
/**
|
@@ -1388,7 +1470,7 @@ class Tutor_List_Table {
|
|
1388 |
// Instead of using esc_attr(), we strip tags to get closer to a user-friendly string.
|
1389 |
$data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"';
|
1390 |
|
1391 |
-
$attributes =
|
1392 |
|
1393 |
if ( 'cb' === $column_name ) {
|
1394 |
echo '<th scope="row" class="check-column">';
|
@@ -1403,15 +1485,15 @@ class Tutor_List_Table {
|
|
1403 |
$primary
|
1404 |
);
|
1405 |
} elseif ( method_exists( $this, 'column_' . $column_name ) ) {
|
1406 |
-
echo
|
1407 |
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
|
1408 |
echo $this->handle_row_actions( $item, $column_name, $primary );
|
1409 |
-
echo
|
1410 |
} else {
|
1411 |
-
echo
|
1412 |
echo $this->column_default( $item, $column_name );
|
1413 |
echo $this->handle_row_actions( $item, $column_name, $primary );
|
1414 |
-
echo
|
1415 |
}
|
1416 |
}
|
1417 |
}
|
@@ -1456,7 +1538,7 @@ class Tutor_List_Table {
|
|
1456 |
);
|
1457 |
}
|
1458 |
if ( isset( $this->_pagination_args['total_pages'] ) ) {
|
1459 |
-
$response['total_pages']
|
1460 |
$response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
|
1461 |
}
|
1462 |
|
@@ -1465,7 +1547,6 @@ class Tutor_List_Table {
|
|
1465 |
|
1466 |
/**
|
1467 |
* Send required variables to JavaScript land
|
1468 |
-
*
|
1469 |
*/
|
1470 |
public function _js_vars() {
|
1471 |
$args = array(
|
@@ -1473,9 +1554,9 @@ class Tutor_List_Table {
|
|
1473 |
'screen' => array(
|
1474 |
'id' => $this->screen->id,
|
1475 |
'base' => $this->screen->base,
|
1476 |
-
)
|
1477 |
);
|
1478 |
|
1479 |
-
printf( "<script type='text/javascript'>list_args = %s;</script
|
1480 |
}
|
1481 |
}
|
7 |
*/
|
8 |
|
9 |
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
exit;
|
12 |
+
}
|
13 |
|
14 |
/**
|
15 |
* Base class for displaying a list of items in an ajaxified HTML table.
|
95 |
*
|
96 |
* @var array
|
97 |
*/
|
98 |
+
protected $compat_methods = array(
|
99 |
+
'set_pagination_args',
|
100 |
+
'get_views',
|
101 |
+
'get_bulk_actions',
|
102 |
+
'bulk_actions',
|
103 |
+
'row_actions',
|
104 |
+
'months_dropdown',
|
105 |
+
'view_switcher',
|
106 |
+
'comments_bubble',
|
107 |
+
'get_items_per_page',
|
108 |
+
'pagination',
|
109 |
+
'get_sortable_columns',
|
110 |
+
'get_column_info',
|
111 |
+
'get_table_classes',
|
112 |
+
'display_tablenav',
|
113 |
+
'extra_tablenav',
|
114 |
+
'single_row_columns',
|
115 |
+
);
|
116 |
|
117 |
/**
|
118 |
* Constructor.
|
140 |
* }
|
141 |
*/
|
142 |
public function __construct( $args = array() ) {
|
143 |
+
$args = wp_parse_args(
|
144 |
+
$args,
|
145 |
+
array(
|
146 |
+
'plural' => '',
|
147 |
+
'singular' => '',
|
148 |
+
'ajax' => false,
|
149 |
+
'screen' => null,
|
150 |
+
)
|
151 |
+
);
|
152 |
|
153 |
$this->screen = convert_to_screen( $args['screen'] );
|
154 |
|
155 |
add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
|
156 |
|
157 |
+
if ( ! $args['plural'] ) {
|
158 |
$args['plural'] = $this->screen->base;
|
159 |
+
}
|
160 |
|
161 |
+
$args['plural'] = sanitize_key( $args['plural'] );
|
162 |
$args['singular'] = sanitize_key( $args['singular'] );
|
163 |
|
164 |
$this->_args = $args;
|
171 |
if ( empty( $this->modes ) ) {
|
172 |
$this->modes = array(
|
173 |
'list' => __( 'List View' ),
|
174 |
+
'excerpt' => __( 'Excerpt View' ),
|
175 |
);
|
176 |
}
|
177 |
}
|
260 |
|
261 |
/**
|
262 |
* Prepares the list of items for displaying.
|
263 |
+
*
|
264 |
* @uses Tutor_List_Table::set_pagination_args()
|
265 |
*
|
266 |
* @since 3.1.0
|
278 |
* @param array|string $args Array or string of arguments with information about the pagination.
|
279 |
*/
|
280 |
protected function set_pagination_args( $args ) {
|
281 |
+
$args = wp_parse_args(
|
282 |
+
$args,
|
283 |
+
array(
|
284 |
+
'total_items' => 0,
|
285 |
+
'total_pages' => 0,
|
286 |
+
'per_page' => 0,
|
287 |
+
)
|
288 |
+
);
|
289 |
|
290 |
+
if ( ! $args['total_pages'] && $args['per_page'] > 0 ) {
|
291 |
$args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
|
292 |
+
}
|
293 |
|
294 |
// Redirect if page number is invalid and headers are not already sent.
|
295 |
if ( ! headers_sent() && ! wp_doing_ajax() && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
|
314 |
return $this->get_pagenum();
|
315 |
}
|
316 |
|
317 |
+
if ( isset( $this->_pagination_args[ $key ] ) ) {
|
318 |
+
return $this->_pagination_args[ $key ];
|
319 |
}
|
320 |
}
|
321 |
|
327 |
* @return bool
|
328 |
*/
|
329 |
public function has_items() {
|
330 |
+
return ! empty( $this->items );
|
331 |
}
|
332 |
|
333 |
/**
|
348 |
* @param string $input_id ID attribute value for the search input field.
|
349 |
*/
|
350 |
public function search_box( $text, $input_id ) {
|
351 |
+
if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) {
|
352 |
+
return;
|
353 |
+
}
|
354 |
|
355 |
$input_id = $input_id . '-search-input';
|
356 |
|
357 |
+
if ( ! empty( $_REQUEST['orderby'] ) ) {
|
358 |
echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
|
359 |
+
}
|
360 |
+
if ( ! empty( $_REQUEST['order'] ) ) {
|
361 |
echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
|
362 |
+
}
|
363 |
+
if ( ! empty( $_REQUEST['post_mime_type'] ) ) {
|
364 |
echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
|
365 |
+
}
|
366 |
+
if ( ! empty( $_REQUEST['detached'] ) ) {
|
367 |
echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
|
368 |
+
}
|
369 |
?>
|
370 |
<p class="search-box">
|
371 |
+
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_attr( $text ); ?>:</label>
|
372 |
<input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="s" value="<?php _admin_search_query(); ?>" />
|
373 |
<?php submit_button( $text, '', '', false, array( 'id' => 'search-submit' ) ); ?>
|
374 |
</p>
|
380 |
* get course list
|
381 |
* @param $selected | optional
|
382 |
*/
|
383 |
+
public function course_dropdown( $selected = '' ) {
|
384 |
+
$courses = ( current_user_can( 'administrator' ) ) ? tutils()->get_courses() : tutils()->get_courses_by_instructor();
|
385 |
+
$markup = '
|
386 |
<div class="alignright">
|
387 |
+
<label>' . __( 'Course', 'tutor-pro' ) . '</label>
|
388 |
<select class="tutor-assignment-course-sorting">
|
389 |
+
<option value="0">' . __( 'All', 'tutor' ) . '</option>
|
390 |
OPTIONS_PLACEHOLDER
|
391 |
+
</select>
|
392 |
</div>
|
393 |
';
|
394 |
$options = '';
|
395 |
foreach ( $courses as $course ) {
|
396 |
+
$options .= '<option value="' . $course->ID . '" ' . selected( $selected, $course->ID, false ) . '> ' . $course->post_title . ' </option>';
|
397 |
}
|
398 |
+
|
399 |
$content = str_replace( 'OPTIONS_PLACEHOLDER', $options, $markup );
|
400 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
401 |
}
|
402 |
|
403 |
/**
|
406 |
* @param $selected | optional
|
407 |
*/
|
408 |
|
409 |
+
public function sorting_order( $selected = 'DESC' ) {
|
410 |
+
$orders = array( 'DESC', 'ASC' );
|
411 |
+
$markup = '
|
412 |
<div class="alignright">
|
413 |
+
<label>' . __( 'Sort By', 'tutor' ) . '</label>
|
414 |
<select class="tutor-assignment-order-sorting">
|
415 |
OPTION_PLACEHOLDER
|
416 |
+
</select>
|
417 |
</div>
|
418 |
';
|
419 |
$options = '';
|
420 |
+
foreach ( $orders as $order ) {
|
421 |
+
$options .= '<option value="' . $order . '" ' . selected( $selected, $order, false ) . '> ' . __( $order, 'tutor' ) . ' </option>';
|
422 |
+
}
|
423 |
$content = str_replace( 'OPTION_PLACEHOLDER', $options, $markup );
|
424 |
+
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
425 |
}
|
426 |
/**
|
427 |
* @since 1.8.0
|
433 |
$placeholder = __( get_option( 'date_format' ), 'tutor' );
|
434 |
$date_filter = sanitize_text_field( tutor_utils()->array_get( 'date', $_GET, '' ) );
|
435 |
$date_input = '' !== $date_filter ? tutor_get_formated_date( get_option( 'date_format' ), $date_filter ) : '';
|
436 |
+
$markup = '
|
437 |
<div class="alignright assignment-date-box">
|
438 |
+
<label>' . __( 'Date', 'tutor' ) . '</label>
|
439 |
<input type="" class="tutor_date_picker tutor-assignment-date-sorting" placeholder="' . $placeholder . '" value="' . $date_input . '">
|
440 |
<i class="tutor-icon-calendar"></i>
|
441 |
</div>
|
442 |
+
';
|
443 |
+
echo $markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
444 |
}
|
445 |
|
446 |
/**
|
474 |
*/
|
475 |
$views = apply_filters( "views_{$this->screen->id}", $views );
|
476 |
|
477 |
+
if ( empty( $views ) ) {
|
478 |
return;
|
479 |
+
}
|
480 |
|
481 |
$this->screen->render_screen_reader_content( 'heading_views' );
|
482 |
|
483 |
+
echo '<ul class="subsubsub">';
|
484 |
foreach ( $views as $class => $view ) {
|
485 |
$views[ $class ] = "\t<li class='$class'>$view";
|
486 |
}
|
487 |
+
echo implode( ' |</li>', $views ) . '</li>';
|
488 |
+
echo '</ul>';
|
489 |
}
|
490 |
|
491 |
/**
|
524 |
* @param array $actions An array of the available bulk actions.
|
525 |
*/
|
526 |
$this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
|
527 |
+
$two = '';
|
528 |
} else {
|
529 |
$two = '2';
|
530 |
}
|
531 |
|
532 |
+
if ( empty( $this->_actions ) ) {
|
533 |
return;
|
534 |
+
}
|
535 |
|
536 |
echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>';
|
537 |
+
echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . '">';
|
538 |
+
echo '<option value="-1">' . __( 'Bulk Actions', 'tutor' ) . '</option>';
|
539 |
|
540 |
foreach ( $this->_actions as $name => $title ) {
|
541 |
$class = 'edit' === $name ? ' class="hide-if-no-js"' : '';
|
542 |
|
543 |
+
echo '\t' . '<option value="' . $name . '"' . $class . '>' . $title . '</option>';
|
544 |
}
|
545 |
|
546 |
+
echo '</select>';
|
547 |
|
548 |
+
submit_button( __( 'Apply' ), 'action', '', false, array( 'id' => 'doaction' . $two ) );
|
549 |
+
echo '';
|
550 |
}
|
551 |
|
552 |
/**
|
557 |
* @return string|false The action name or False if no action was selected
|
558 |
*/
|
559 |
public function current_action() {
|
560 |
+
if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) ) {
|
561 |
return false;
|
562 |
+
}
|
563 |
|
564 |
+
if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) {
|
565 |
return $_REQUEST['action'];
|
566 |
+
}
|
567 |
|
568 |
+
if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ) {
|
569 |
return $_REQUEST['action2'];
|
570 |
+
}
|
571 |
|
572 |
return false;
|
573 |
}
|
578 |
* @since 3.1.0
|
579 |
*
|
580 |
* @param array $actions The list of actions
|
581 |
+
* @param bool $always_visible Whether the actions should be always visible
|
582 |
* @return string
|
583 |
*/
|
584 |
protected function row_actions( $actions, $always_visible = false ) {
|
585 |
$action_count = count( $actions );
|
586 |
+
$i = 0;
|
587 |
|
588 |
+
if ( ! $action_count ) {
|
589 |
return '';
|
590 |
+
}
|
591 |
|
592 |
+
$out = '<div class="' . esc_attr( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
|
593 |
foreach ( $actions as $action => $link ) {
|
594 |
++$i;
|
595 |
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
596 |
+
$out .= '<span class="' . $action . '">' . $link . $sep . '</span>';
|
597 |
}
|
598 |
$out .= '</div>';
|
599 |
|
600 |
$out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>';
|
601 |
|
602 |
+
return $out; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
603 |
+
|
604 |
}
|
605 |
|
606 |
/**
|
632 |
if ( ! isset( $_GET['post_status'] ) || 'trash' !== $_GET['post_status'] ) {
|
633 |
$extra_checks .= " AND post_status != 'trash'";
|
634 |
} elseif ( isset( $_GET['post_status'] ) ) {
|
635 |
+
$extra_checks = $wpdb->prepare( ' AND post_status = %s', tutor_sanitize_data($_GET['post_status']) );
|
636 |
}
|
637 |
|
638 |
+
$months = $wpdb->get_results(
|
639 |
+
$wpdb->prepare(
|
640 |
+
"
|
641 |
SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
|
642 |
FROM $wpdb->posts
|
643 |
WHERE post_type = %s
|
644 |
$extra_checks
|
645 |
ORDER BY post_date DESC
|
646 |
+
",
|
647 |
+
$post_type
|
648 |
+
)
|
649 |
+
);
|
650 |
|
651 |
/**
|
652 |
* Filters the 'Months' drop-down results.
|
660 |
|
661 |
$month_count = count( $months );
|
662 |
|
663 |
+
if ( ! $month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
|
664 |
return;
|
665 |
+
}
|
666 |
|
667 |
$m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
|
668 |
?>
|
671 |
<option<?php selected( $m, 0 ); ?> value="0"><?php _e( 'All dates' ); ?></option>
|
672 |
<?php
|
673 |
foreach ( $months as $arc_row ) {
|
674 |
+
if ( 0 == $arc_row->year ) {
|
675 |
continue;
|
676 |
+
}
|
677 |
|
678 |
$month = zeroise( $arc_row->month, 2 );
|
679 |
+
$year = $arc_row->year;
|
680 |
|
681 |
+
printf(
|
682 |
+
"<option %s value='%s'>%s</option>",
|
683 |
selected( $m, $year . $month, false ),
|
684 |
esc_attr( $arc_row->year . $month ),
|
685 |
/* translators: 1: month name, 2: 4-digit year */
|
705 |
<?php
|
706 |
foreach ( $this->modes as $mode => $title ) {
|
707 |
$classes = array( 'view-' . $mode );
|
708 |
+
if ( $current_mode === $mode ) {
|
709 |
$classes[] = 'current';
|
710 |
+
}
|
711 |
printf(
|
712 |
+
"<a href='%s' class='%s' id='view-switch-$mode'><span class='screen-reader-text'>%s</span></a>",
|
713 |
esc_url( add_query_arg( 'mode', $mode ) ),
|
714 |
implode( ' ', $classes ),
|
715 |
$title
|
732 |
$approved_comments = get_comments_number();
|
733 |
|
734 |
$approved_comments_number = number_format_i18n( $approved_comments );
|
735 |
+
$pending_comments_number = number_format_i18n( $pending_comments );
|
736 |
|
737 |
$approved_only_phrase = sprintf( _n( '%s comment', '%s comments', $approved_comments ), $approved_comments_number );
|
738 |
+
$approved_phrase = sprintf( _n( '%s approved comment', '%s approved comments', $approved_comments ), $approved_comments_number );
|
739 |
+
$pending_phrase = sprintf( _n( '%s pending comment', '%s pending comments', $pending_comments ), $pending_comments_number );
|
740 |
|
741 |
// No comments at all.
|
742 |
if ( ! $approved_comments && ! $pending_comments ) {
|
743 |
+
printf(
|
744 |
+
'<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>',
|
745 |
__( 'No comments' )
|
746 |
);
|
747 |
// Approved comments have different display depending on some conditions.
|
748 |
} elseif ( $approved_comments ) {
|
749 |
+
printf(
|
750 |
+
'<a href="%s" class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
751 |
+
esc_url(
|
752 |
+
add_query_arg(
|
753 |
+
array(
|
754 |
+
'p' => $post_id,
|
755 |
+
'comment_status' => 'approved',
|
756 |
+
),
|
757 |
+
admin_url( 'edit-comments.php' )
|
758 |
+
)
|
759 |
+
),
|
760 |
$approved_comments_number,
|
761 |
$pending_comments ? $approved_phrase : $approved_only_phrase
|
762 |
);
|
763 |
} else {
|
764 |
+
printf(
|
765 |
+
'<span class="post-com-count post-com-count-no-comments"><span class="comment-count comment-count-no-comments" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
|
766 |
$approved_comments_number,
|
767 |
$pending_comments ? __( 'No approved comments' ) : __( 'No comments' )
|
768 |
);
|
769 |
}
|
770 |
|
771 |
if ( $pending_comments ) {
|
772 |
+
printf(
|
773 |
+
'<a href="%s" class="post-com-count post-com-count-pending"><span class="comment-count-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
774 |
+
esc_url(
|
775 |
+
add_query_arg(
|
776 |
+
array(
|
777 |
+
'p' => $post_id,
|
778 |
+
'comment_status' => 'moderated',
|
779 |
+
),
|
780 |
+
admin_url( 'edit-comments.php' )
|
781 |
+
)
|
782 |
+
),
|
783 |
$pending_comments_number,
|
784 |
$pending_phrase
|
785 |
);
|
786 |
} else {
|
787 |
+
printf(
|
788 |
+
'<span class="post-com-count post-com-count-pending post-com-count-no-pending"><span class="comment-count comment-count-no-pending" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>',
|
789 |
$pending_comments_number,
|
790 |
$approved_comments ? __( 'No pending comments' ) : __( 'No comments' )
|
791 |
);
|
802 |
public function get_pagenum() {
|
803 |
$pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
|
804 |
|
805 |
+
if ( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] ) {
|
806 |
$pagenum = $this->_pagination_args['total_pages'];
|
807 |
+
}
|
808 |
|
809 |
return max( 1, $pagenum );
|
810 |
}
|
820 |
*/
|
821 |
protected function get_items_per_page( $option, $default = 20 ) {
|
822 |
$per_page = (int) get_user_option( $option );
|
823 |
+
if ( empty( $per_page ) || $per_page < 1 ) {
|
824 |
$per_page = $default;
|
825 |
+
}
|
826 |
|
827 |
/**
|
828 |
* Filters the number of items to be displayed on each page of the list table.
|
852 |
return;
|
853 |
}
|
854 |
|
855 |
+
$total_items = $this->_pagination_args['total_items'];
|
856 |
+
$total_pages = $this->_pagination_args['total_pages'];
|
857 |
$infinite_scroll = false;
|
858 |
if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
|
859 |
$infinite_scroll = $this->_pagination_args['infinite_scroll'];
|
865 |
|
866 |
$output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';
|
867 |
|
868 |
+
$current = $this->get_pagenum();
|
869 |
$removable_query_args = wp_removable_query_args();
|
870 |
|
871 |
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
|
881 |
|
882 |
if ( $current == 1 ) {
|
883 |
$disable_first = true;
|
884 |
+
$disable_prev = true;
|
885 |
}
|
886 |
if ( $current == 2 ) {
|
887 |
$disable_first = true;
|
897 |
if ( $disable_first ) {
|
898 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">«</span>';
|
899 |
} else {
|
900 |
+
$page_links[] = sprintf(
|
901 |
+
"<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
902 |
esc_url( remove_query_arg( 'paged', $current_url ) ),
|
903 |
__( 'First page' ),
|
904 |
'«'
|
908 |
if ( $disable_prev ) {
|
909 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">‹</span>';
|
910 |
} else {
|
911 |
+
$page_links[] = sprintf(
|
912 |
+
"<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
913 |
+
esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ),
|
914 |
__( 'Previous page' ),
|
915 |
'‹'
|
916 |
);
|
920 |
$html_current_page = $current;
|
921 |
$total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
|
922 |
} else {
|
923 |
+
$html_current_page = sprintf(
|
924 |
+
'%s<input class="current-page" id="current-page-selector" type="text" name="paged" value="%s" size="%d" aria-describedby="table-paging" /><span class="tablenav-paging-text">',
|
925 |
'<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
|
926 |
$current,
|
927 |
strlen( $total_pages )
|
928 |
);
|
929 |
}
|
930 |
+
$html_total_pages = sprintf( '<span class="total-pages">%s</span>', number_format_i18n( $total_pages ) );
|
931 |
+
$page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
|
932 |
|
933 |
if ( $disable_next ) {
|
934 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">›</span>';
|
935 |
} else {
|
936 |
+
$page_links[] = sprintf(
|
937 |
+
"<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
938 |
+
esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ),
|
939 |
__( 'Next page' ),
|
940 |
'›'
|
941 |
);
|
944 |
if ( $disable_last ) {
|
945 |
$page_links[] = '<span class="tablenav-pages-navspan" aria-hidden="true">»</span>';
|
946 |
} else {
|
947 |
+
$page_links[] = sprintf(
|
948 |
+
"<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
|
949 |
esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
|
950 |
__( 'Last page' ),
|
951 |
'»'
|
956 |
if ( ! empty( $infinite_scroll ) ) {
|
957 |
$pagination_links_class .= ' hide-if-js';
|
958 |
}
|
959 |
+
$output .= '<span class="' . $pagination_links_class . '">' . join( '', $page_links ) . '</span>';
|
960 |
|
961 |
if ( $total_pages ) {
|
962 |
$page_class = $total_pages < 2 ? ' one-page' : '';
|
963 |
} else {
|
964 |
$page_class = ' no-pages';
|
965 |
}
|
966 |
+
$this->_pagination = '<div class="tablenav-pages' . $page_class . '">' . $output . '</div>';
|
967 |
|
968 |
+
echo $this->_pagination; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
969 |
}
|
970 |
|
971 |
/**
|
1006 |
*/
|
1007 |
protected function get_default_primary_column_name() {
|
1008 |
$columns = $this->get_columns();
|
1009 |
+
$column = '';
|
1010 |
|
1011 |
if ( empty( $columns ) ) {
|
1012 |
return $column;
|
1051 |
// If the primary column doesn't exist fall back to the
|
1052 |
// first non-checkbox column.
|
1053 |
if ( ! isset( $columns[ $default ] ) ) {
|
1054 |
+
$default = self::get_default_primary_column_name();
|
1055 |
}
|
1056 |
|
1057 |
/**
|
1062 |
* @param string $default Column name default for the specific list table, e.g. 'name'.
|
1063 |
* @param string $context Screen ID for specific list table, e.g. 'plugins'.
|
1064 |
*/
|
1065 |
+
$column = apply_filters( 'list_table_primary_column', $default, $this->screen->id );
|
1066 |
|
1067 |
if ( empty( $column ) || ! isset( $columns[ $column ] ) ) {
|
1068 |
$column = $default;
|
1092 |
}
|
1093 |
|
1094 |
$columns = get_column_headers( $this->screen );
|
1095 |
+
$hidden = get_hidden_columns( $this->screen );
|
1096 |
|
1097 |
$sortable_columns = $this->get_sortable_columns();
|
1098 |
/**
|
1105 |
*
|
1106 |
* @param array $sortable_columns An array of sortable columns.
|
1107 |
*/
|
1108 |
+
$_sortable = apply_filters( 'manage_' . esc_attr( $this->screen->id ) . '_sortable_columns', $sortable_columns );
|
1109 |
|
1110 |
$sortable = array();
|
1111 |
foreach ( $_sortable as $id => $data ) {
|
1112 |
+
if ( empty( $data ) ) {
|
1113 |
continue;
|
1114 |
+
}
|
1115 |
|
1116 |
$data = (array) $data;
|
1117 |
+
if ( ! isset( $data[1] ) ) {
|
1118 |
$data[1] = false;
|
1119 |
+
}
|
1120 |
|
1121 |
+
$sortable[ $id ] = $data;
|
1122 |
}
|
1123 |
|
1124 |
+
$primary = $this->get_primary_column_name();
|
1125 |
$this->_column_headers = array( $columns, $hidden, $sortable, $primary );
|
1126 |
|
1127 |
return $this->_column_headers;
|
1136 |
*/
|
1137 |
public function get_column_count() {
|
1138 |
list ( $columns, $hidden ) = $this->get_column_info();
|
1139 |
+
$hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
|
1140 |
return count( $columns ) - count( $hidden );
|
1141 |
}
|
1142 |
|
1156 |
$current_url = remove_query_arg( 'paged', $current_url );
|
1157 |
|
1158 |
if ( isset( $_GET['orderby'] ) ) {
|
1159 |
+
$current_orderby = tutor_sanitize_data( $_GET['orderby'] );
|
1160 |
} else {
|
1161 |
$current_orderby = '';
|
1162 |
}
|
1169 |
|
1170 |
if ( ! empty( $columns['cb'] ) ) {
|
1171 |
static $cb_counter = 1;
|
1172 |
+
$columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>' . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
|
|
|
1173 |
$cb_counter++;
|
1174 |
}
|
1175 |
|
1180 |
$class[] = 'hidden';
|
1181 |
}
|
1182 |
|
1183 |
+
if ( 'cb' === $column_key ) {
|
1184 |
$class[] = 'check-column';
|
1185 |
+
} elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) {
|
1186 |
$class[] = 'num';
|
1187 |
+
}
|
1188 |
|
1189 |
if ( $column_key === $primary ) {
|
1190 |
$class[] = 'column-primary';
|
1191 |
}
|
1192 |
|
1193 |
+
if ( isset( $sortable[ $column_key ] ) ) {
|
1194 |
+
list( $orderby, $desc_first ) = $sortable[ $column_key ];
|
1195 |
|
1196 |
if ( $current_orderby === $orderby ) {
|
1197 |
+
$order = 'asc' === $current_order ? 'desc' : 'asc';
|
1198 |
$class[] = 'sorted';
|
1199 |
$class[] = $current_order;
|
1200 |
} else {
|
1201 |
+
$order = $desc_first ? 'desc' : 'asc';
|
1202 |
$class[] = 'sortable';
|
1203 |
$class[] = $desc_first ? 'asc' : 'desc';
|
1204 |
}
|
1206 |
$column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
|
1207 |
}
|
1208 |
|
1209 |
+
$tag = ( 'cb' === $column_key ) ? 'td' : 'th';
|
1210 |
$scope = ( 'th' === $tag ) ? 'scope="col"' : '';
|
1211 |
+
$id = $with_id ? "id='$column_key'" : '';
|
1212 |
|
1213 |
+
if ( ! empty( $class ) ) {
|
1214 |
$class = "class='" . join( ' ', $class ) . "'";
|
1215 |
+
}
|
1216 |
|
1217 |
+
echo ( "<$tag $scope $id $class>$column_display_name</$tag>" );
|
1218 |
}
|
1219 |
}
|
1220 |
|
1223 |
*
|
1224 |
* @since 3.1.0
|
1225 |
*/
|
1226 |
+
public function display( $enable_sorting_field_with_bulk_action = false ) {
|
1227 |
$singular = $this->_args['singular'];
|
1228 |
if ( $enable_sorting_field_with_bulk_action ) {
|
1229 |
+
$this->display_sorting_fields();
|
1230 |
} else {
|
1231 |
+
$this->display_tablenav( 'top' );
|
1232 |
}
|
1233 |
|
1234 |
$this->screen->render_screen_reader_content( 'heading_list' );
|
1235 |
?>
|
1236 |
+
<table class="wp-list-table <?php echo esc_attr( implode( ' ', $this->get_table_classes() ) ); ?>">
|
1237 |
<thead>
|
1238 |
<tr>
|
1239 |
<?php $this->print_column_headers(); ?>
|
1240 |
</tr>
|
1241 |
</thead>
|
1242 |
|
1243 |
+
<tbody id="the-list"
|
1244 |
+
<?php
|
1245 |
if ( $singular ) {
|
1246 |
+
echo 'data-wp-lists=list:' . $singular;
|
1247 |
+
}
|
1248 |
+
?>
|
1249 |
+
>
|
1250 |
<?php $this->display_rows_or_placeholder(); ?>
|
1251 |
</tbody>
|
1252 |
|
1285 |
?>
|
1286 |
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
1287 |
|
1288 |
+
<?php if ( $this->has_items() ) : ?>
|
1289 |
<div class="alignleft actions bulkactions">
|
1290 |
<?php $this->bulk_actions( $which ); ?>
|
1291 |
</div>
|
1292 |
+
<?php
|
1293 |
+
endif;
|
1294 |
$this->extra_tablenav( $which );
|
1295 |
$this->pagination( $which );
|
1296 |
?>
|
1302 |
|
1303 |
/**
|
1304 |
* Sorting fields added on tutor table
|
1305 |
+
*
|
1306 |
* Course id | Search | Date | Order
|
1307 |
+
*
|
1308 |
* @since 1.9.5
|
1309 |
*/
|
1310 |
protected function display_sorting_fields() {
|
1311 |
+
$search_filter = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
|
1312 |
+
$course_id = isset( $_GET['course-id'] ) ? sanitize_text_field( $_GET['course-id'] ) : '';
|
1313 |
+
$date_filter = isset( $_GET['date'] ) ? sanitize_text_field( $_GET['date'] ) : '';
|
1314 |
+
$order_filter = isset( $_GET['order'] ) ? sanitize_text_field( $_GET['order'] ) : '';
|
1315 |
+
$which = 'top';
|
1316 |
?>
|
1317 |
<div class="tutor-sorting-bulk-action-wrapper">
|
1318 |
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
1319 |
+
<?php if ( $this->has_items() ) : ?>
|
1320 |
<div class="alignleft actions bulkactions">
|
1321 |
<?php $this->bulk_actions( $which ); ?>
|
1322 |
</div>
|
1323 |
+
<?php
|
1324 |
+
endif;
|
1325 |
$this->extra_tablenav( $which );
|
1326 |
|
1327 |
?>
|
1328 |
</div>
|
1329 |
+
|
1330 |
<div class="tutor-admin-search-box-container" style="margin:0px;">
|
1331 |
|
1332 |
<div>
|
1333 |
+
<div class="menu-label"><?php _e( 'Courses', 'tutor' ); ?></div>
|
1334 |
<div>
|
1335 |
<?php
|
1336 |
+
// get courses
|
1337 |
+
$courses = ( current_user_can( 'administrator' ) ) ? tutils()->get_courses() : tutils()->get_courses_by_instructor();
|
1338 |
?>
|
1339 |
|
1340 |
<select class="tutor-report-category tutor-announcement-course-sorting">
|
1341 |
+
|
1342 |
+
<option value=""><?php _e( 'All', 'tutor' ); ?></option>
|
1343 |
+
|
1344 |
+
<?php if ( $courses ) : ?>
|
1345 |
+
<?php foreach ( $courses as $course ) : ?>
|
1346 |
+
<option value="<?php echo esc_attr( $course->ID ); ?>" <?php selected( $course_id, $course->ID, 'selected' ); ?>>
|
1347 |
+
<?php echo esc_attr( $course->post_title ); ?>
|
1348 |
</option>
|
1349 |
<?php endforeach; ?>
|
1350 |
<?php else : ?>
|
1351 |
+
<option value=""><?php _e( 'No course found', 'tutor' ); ?></option>
|
1352 |
<?php endif; ?>
|
1353 |
</select>
|
1354 |
</div>
|
1355 |
</div>
|
1356 |
|
1357 |
<div>
|
1358 |
+
<div class="menu-label"><?php _e( 'Sort By', 'tutor' ); ?></div>
|
1359 |
<div>
|
1360 |
<select class="tutor-report-sort tutor-announcement-order-sorting">
|
1361 |
+
<option <?php selected( $order_filter, 'ASC' ); ?>>ASC</option>
|
1362 |
+
<option <?php selected( $order_filter, 'DESC' ); ?>>DESC</option>
|
1363 |
</select>
|
1364 |
</div>
|
1365 |
</div>
|
1366 |
|
1367 |
<div>
|
1368 |
+
<div class="menu-label"><?php _e( 'Date', 'tutor' ); ?></div>
|
1369 |
<div class="date-range-input">
|
1370 |
+
<input type="text" class="tutor_date_picker tutor-announcement-date-sorting" id="tutor-announcement-datepicker" placeholder="<?php _e( get_option( 'date_format' ), 'tutor' ); ?>" value="<?php echo '' !== $date_filter ? tutor_get_formated_date( get_option( 'date_format' ), $date_filter ) : ''; ?>" autocomplete="off" />
|
1371 |
<i class="tutor-icon-calendar"></i>
|
1372 |
</div>
|
1373 |
</div>
|
1374 |
|
1375 |
<div class="tutor-search-form-group">
|
1376 |
+
<div class="menu-label"><?php _e( 'Search', 'tutor' ); ?></div>
|
1377 |
<div style="position:relative;">
|
1378 |
+
<input type="text" name="search" class="tutor-report-search tutor-announcement-search-field" value="<?php echo esc_attr( $search_filter ); ?>" autocomplete="off" placeholder="<?php _e( 'Search', 'tutor' ); ?>" />
|
1379 |
<button class="tutor-report-search-btn tutor-announcement-search-sorting"><i class="tutor-icon-magnifying-glass-1"></i></button>
|
1380 |
</div>
|
1381 |
</div>
|
1382 |
+
|
1383 |
+
</div>
|
1384 |
+
</div>
|
1385 |
<?php
|
1386 |
}
|
1387 |
|
1415 |
* @since 3.1.0
|
1416 |
*/
|
1417 |
public function display_rows() {
|
1418 |
+
foreach ( $this->items as $item ) {
|
1419 |
$this->single_row( $item );
|
1420 |
+
}
|
1421 |
}
|
1422 |
|
1423 |
/**
|
1470 |
// Instead of using esc_attr(), we strip tags to get closer to a user-friendly string.
|
1471 |
$data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"';
|
1472 |
|
1473 |
+
$attributes = 'class="' . $classes . '" ' . $data;
|
1474 |
|
1475 |
if ( 'cb' === $column_name ) {
|
1476 |
echo '<th scope="row" class="check-column">';
|
1485 |
$primary
|
1486 |
);
|
1487 |
} elseif ( method_exists( $this, 'column_' . $column_name ) ) {
|
1488 |
+
echo '<td ' . $attributes . '>';
|
1489 |
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
|
1490 |
echo $this->handle_row_actions( $item, $column_name, $primary );
|
1491 |
+
echo '</td>';
|
1492 |
} else {
|
1493 |
+
echo '<td ' . $attributes . '>';
|
1494 |
echo $this->column_default( $item, $column_name );
|
1495 |
echo $this->handle_row_actions( $item, $column_name, $primary );
|
1496 |
+
echo '</td>';
|
1497 |
}
|
1498 |
}
|
1499 |
}
|
1538 |
);
|
1539 |
}
|
1540 |
if ( isset( $this->_pagination_args['total_pages'] ) ) {
|
1541 |
+
$response['total_pages'] = $this->_pagination_args['total_pages'];
|
1542 |
$response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
|
1543 |
}
|
1544 |
|
1547 |
|
1548 |
/**
|
1549 |
* Send required variables to JavaScript land
|
|
|
1550 |
*/
|
1551 |
public function _js_vars() {
|
1552 |
$args = array(
|
1554 |
'screen' => array(
|
1555 |
'id' => $this->screen->id,
|
1556 |
'base' => $this->screen->base,
|
1557 |
+
),
|
1558 |
);
|
1559 |
|
1560 |
+
printf( "<script type='text/javascript'>list_args = %s;</script>", wp_json_encode( $args ) );
|
1561 |
}
|
1562 |
}
|
classes/Tutor_Setup.php
CHANGED
@@ -26,11 +26,11 @@ if ( ! defined( 'ABSPATH' ) )
|
|
26 |
}
|
27 |
return $final_arr;
|
28 |
}
|
29 |
-
|
30 |
|
31 |
public function tutor_setup_action(){
|
32 |
tutils()->checking_nonce();
|
33 |
-
|
34 |
$options = (array) maybe_unserialize(get_option('tutor_option'));
|
35 |
if (!isset($_POST['action']) || $_POST['action'] != 'setup_action' || !current_user_can( 'manage_options' )) {
|
36 |
return;
|
@@ -44,7 +44,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
44 |
if ($_POST[$key] == '') {
|
45 |
unset($options[$key]);
|
46 |
} else {
|
47 |
-
$options[$key] = $_POST[$key];
|
48 |
}
|
49 |
}
|
50 |
} else {
|
@@ -69,7 +69,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
69 |
}
|
70 |
}
|
71 |
update_option('tutor_withdraw_options', $payments);
|
72 |
-
|
73 |
// Add wizard flug
|
74 |
update_option('tutor_wizard', 'active');
|
75 |
|
@@ -95,7 +95,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
95 |
}
|
96 |
|
97 |
public function tutor_setup_generator() {
|
98 |
-
|
99 |
$i = 1;
|
100 |
$html = '';
|
101 |
$options = (array) maybe_unserialize(get_option('tutor_option'));
|
@@ -147,11 +147,11 @@ if ( ! defined( 'ABSPATH' ) )
|
|
147 |
$html .= '<span class="label-on">'.__('ON', 'tutor').'</span>';
|
148 |
$html .= '</label>';
|
149 |
break;
|
150 |
-
|
151 |
case 'text':
|
152 |
-
$html .= '<input type="text" name="'.$key.'" class="lesson-permalink" value="'.(isset($options[$key]) ? $options[$key] : '').'" />';
|
153 |
break;
|
154 |
-
|
155 |
case 'rows':
|
156 |
$html .= '<div class="content">';
|
157 |
$html .= '<div class="course-per-row">';
|
@@ -182,7 +182,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
182 |
$html .= '</div>';
|
183 |
$html .= '</div>';
|
184 |
break;
|
185 |
-
|
186 |
case 'radio':
|
187 |
if ( isset($field['options']) ) {
|
188 |
foreach ($field['options'] as $k => $val) {
|
@@ -191,7 +191,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
191 |
}
|
192 |
}
|
193 |
break;
|
194 |
-
|
195 |
case 'slider':
|
196 |
$available_times = array(
|
197 |
'seconds' => __( 'seconds' , 'tutor' ),
|
@@ -226,11 +226,11 @@ if ( ! defined( 'ABSPATH' ) )
|
|
226 |
$html .= '<h5>'.$val['desc'].'</h5>';
|
227 |
$html .= '</label>';
|
228 |
$html .= '</div>';
|
229 |
-
|
230 |
if (isset($options[$key]) && $options[$key] == $val['value']) {
|
231 |
$selected_data .= '<div class="selected">';
|
232 |
$selected_data .= '<h3>'.$val['title'].'</h3>';
|
233 |
-
$selected_data .= '<h5>'.$val['desc'].'</h5>';
|
234 |
$selected_data .= '</div>';
|
235 |
}
|
236 |
}
|
@@ -306,7 +306,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
306 |
|
307 |
case 'attempt':
|
308 |
$html .= '<div class="tutor-setting course-setting-wrapper">';
|
309 |
-
|
310 |
$html .= '<input type="hidden" name="quiz_attempts_allowed" value="'.$options[$key].'">';
|
311 |
|
312 |
$html .= '<div class="content">';
|
@@ -331,7 +331,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
331 |
$html .= '</div>';
|
332 |
$html .= '</div>';
|
333 |
break;
|
334 |
-
|
335 |
default:
|
336 |
# code...
|
337 |
break;
|
@@ -538,8 +538,8 @@ if ( ! defined( 'ABSPATH' ) )
|
|
538 |
'class' => 'tutor-show-hide',
|
539 |
'desc' => __('Choose your preferred withdrawal method from the options.', 'tutor')
|
540 |
),
|
541 |
-
|
542 |
-
|
543 |
)
|
544 |
),
|
545 |
|
@@ -548,7 +548,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
548 |
|
549 |
return $general_fields;
|
550 |
}
|
551 |
-
|
552 |
public function tutor_setup_wizard_settings() {
|
553 |
|
554 |
$options = (array) maybe_unserialize(get_option('tutor_option'));
|
@@ -572,15 +572,15 @@ if ( ! defined( 'ABSPATH' ) )
|
|
572 |
<?php wp_nonce_field( tutor()->nonce_action, tutor()->nonce ); ?>
|
573 |
<input type="hidden" name="action" value="setup_action">
|
574 |
<?php $course_marketplace = tutor_utils()->get_option('enable_course_marketplace'); ?>
|
575 |
-
<input type="hidden" name="enable_course_marketplace" class="enable_course_marketplace_data" value="<?php echo
|
576 |
<?php $earning = tutor_utils()->get_option('enable_tutor_earning'); ?>
|
577 |
-
<input type="hidden" name="enable_tutor_earning" class="enable_tutor_earning_data" value="<?php echo
|
578 |
<ul class="tutor-setup-content">
|
579 |
<?php $this->tutor_setup_generator(); ?>
|
580 |
<li>
|
581 |
<div class="tutor-setup-content-heading greetings">
|
582 |
<div class="header">
|
583 |
-
<img src="<?php echo tutor()->url . 'assets/images/greeting-img.jpg'; ?>" alt="greeting">
|
584 |
</div>
|
585 |
<div class="content">
|
586 |
<h2><?php _e('Congratulations, you’re all set!', 'tutor'); ?></h2>
|
@@ -588,8 +588,8 @@ if ( ! defined( 'ABSPATH' ) )
|
|
588 |
<p><?php _e( 'If you need further assistance, please don’t hesitate to contact us via our <a target="_blank" href="https://www.themeum.com/contact-us/">contact form.</a>', 'tutor' ); ?></p>
|
589 |
</div>
|
590 |
<div class="tutor-setup-content-footer footer">
|
591 |
-
<button class="tutor-redirect primary-btn" data-url="<?php echo admin_url('post-new.php?post_type=courses'); ?>"><?php _e('CREATE A NEW COURSE', 'tutor'); ?></button>
|
592 |
-
<button class="tutor-redirect primary-btn" data-url="<?php echo admin_url('admin.php?page=tutor-addons'); ?>"><?php _e('EXPLORE ADDONS', 'tutor'); ?></button>
|
593 |
</div>
|
594 |
</div>
|
595 |
</li>
|
@@ -605,7 +605,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
605 |
|
606 |
|
607 |
public function tutor_setup_wizard_action() {
|
608 |
-
|
609 |
$html = '<div class="tutor-setup-content-footer footer">';
|
610 |
$html .= '<div class="tutor-setup-btn-wrapper">';
|
611 |
$html .= '<button class="tutor-setup-previous previous animated-btn">';
|
@@ -637,34 +637,34 @@ if ( ! defined( 'ABSPATH' ) )
|
|
637 |
<div class="tutor-wizard-container">
|
638 |
<div class="tutor-wrapper-boarding tutor-setup-wizard-boarding active">
|
639 |
<div class="wizard-boarding-header">
|
640 |
-
<div><img src="<?php echo tutor()->url.'assets/images/tutor-logo.svg'; ?>" /></div>
|
641 |
<div><?php printf(__('Hello %s, welcome to Tutor LMS! Thank you for choosing us.', 'tutor'), $current_user->user_login); ?></div>
|
642 |
</div>
|
643 |
<div class="wizard-boarding-body">
|
644 |
<ul class="slider tutor-boarding">
|
645 |
<li>
|
646 |
|
647 |
-
<div class="slide-thumb"><img src="<?php echo tutor()->url . 'assets/images/scalable_lms_solution.jpg'; ?>" alt="<?php _e('A Powerful, Smart, and Scalable LMS Solution', 'tutor') ?>"/></div>
|
648 |
<div class="slide-title"><?php _e('A Powerful, Smart, and Scalable LMS Solution', 'tutor'); ?></div>
|
649 |
<div class="slide-subtitle"><?php _e('From individual instructors to vast eLearning platforms, Tutor LMS grows with you to create your ideal vision of an LMS website.', 'tutor'); ?></div>
|
650 |
</li>
|
651 |
<li>
|
652 |
-
<div class="slide-thumb"><img src="<?php echo tutor()->url . 'assets/images/extensive_course_builder.jpg'; ?>" alt="<?php _e('Extensive Course Builder', 'tutor') ?>"/></div>
|
653 |
<div class="slide-title"><?php _e('Extensive Course Builder', 'tutor'); ?></div>
|
654 |
<div class="slide-subtitle"><?php _e('Tutor LMS comes with a state-of-the-art frontend course builder. Construct rich and resourceful courses with ease.', 'tutor'); ?></div>
|
655 |
</li>
|
656 |
<li>
|
657 |
-
<div class="slide-thumb"><img src="<?php echo tutor()->url . 'assets/images/advanced_quiz_creator.jpg'; ?>" alt="<?php _e('Advanced Quiz Creator', 'tutor'); ?>"/></div>
|
658 |
<div class="slide-title"><?php _e('Advanced Quiz Creator', 'tutor'); ?></div>
|
659 |
<div class="slide-subtitle"><?php _e('Build interactive quizzes with the vast selection of question types and verify the learning of your students.', 'tutor'); ?></div>
|
660 |
</li>
|
661 |
<li>
|
662 |
-
<div class="slide-thumb"><img src="<?php echo tutor()->url . 'assets/images/freedom_with_ecommerce.jpg'; ?>" alt="<?php _e('Freedom With eCommerce', 'tutor'); ?>"/></div>
|
663 |
<div class="slide-title"><?php _e('Freedom With eCommerce', 'tutor'); ?></div>
|
664 |
<div class="slide-subtitle"><?php _e('Select an eCommerce plugin and sell courses any way you like and use any payment gateway you want!', 'tutor'); ?></div>
|
665 |
</li>
|
666 |
<li>
|
667 |
-
<div class="slide-thumb"><img src="<?php echo tutor()->url . 'assets/images/reports_and_analytics.jpg'; ?>" alt="<?php _e('Reports and Analytics', 'tutor'); ?>"/></div>
|
668 |
<div class="slide-title"><?php _e('Reports and Analytics', 'tutor'); ?></div>
|
669 |
<div class="slide-subtitle"><?php _e('Track what type of courses sell the most! Gain insights on user purchases, manage reviews and track quiz attempts.', 'tutor'); ?></div>
|
670 |
</li>
|
@@ -679,7 +679,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
679 |
</svg>
|
680 |
</button>
|
681 |
</div>
|
682 |
-
<div><a href="<?php echo admin_url(); ?>"><?php _e('I already know, skip this!', 'tutor'); ?></a></div>
|
683 |
</div>
|
684 |
</div>
|
685 |
</div>
|
@@ -692,7 +692,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
692 |
<div class="tutor-wizard-container">
|
693 |
<div class="tutor-wrapper-type tutor-setup-wizard-type">
|
694 |
<div class="wizard-type-header">
|
695 |
-
<div class="logo"><img src="<?php echo tutor()->url.'assets/images/tutor-logo.svg'; ?>" /></div>
|
696 |
<div class="title"><?php _e('Let’s get the platform up and running', 'tutor'); ?></div>
|
697 |
<div class="subtitle"><?php _e('Pick a category for your LMS platform. You can always update this later.', 'tutor'); ?></div>
|
698 |
</div>
|
@@ -701,7 +701,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
701 |
<input id="enable_course_marketplace-0" type="radio" name="enable_course_marketplace_setup" value="0" <?php if(!$course_marketplace){ echo 'checked'; } ?> />
|
702 |
<span class="icon"></span>
|
703 |
<label for="enable_course_marketplace-0">
|
704 |
-
<img src="<?php echo tutor()->url.'assets/images/single-marketplace.png'; ?>" />
|
705 |
<div class="title"><?php _e( 'Individual', 'tutor' ); ?></div>
|
706 |
<div class="subtitle"><?php _e( 'I want to start my solo journey as an educator and spread my knowledge.', 'tutor' ); ?></div>
|
707 |
</label>
|
@@ -711,7 +711,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
711 |
<input id="enable_course_marketplace-1" type="radio" name="enable_course_marketplace_setup" value="1" <?php if($course_marketplace){ echo 'checked'; } ?>/>
|
712 |
<span class="icon"></span>
|
713 |
<label for="enable_course_marketplace-1">
|
714 |
-
<img src="<?php echo tutor()->url.'assets/images/multiple-marketplace.png'; ?>" />
|
715 |
<div class="title"><?php _e( 'Marketplace', 'tutor' ); ?></div>
|
716 |
<div class="subtitle"><?php _e( 'I want to create an eLearning platform to let anyone earn by teaching online.', 'tutor' ); ?></div>
|
717 |
</label>
|
26 |
}
|
27 |
return $final_arr;
|
28 |
}
|
29 |
+
|
30 |
|
31 |
public function tutor_setup_action(){
|
32 |
tutils()->checking_nonce();
|
33 |
+
|
34 |
$options = (array) maybe_unserialize(get_option('tutor_option'));
|
35 |
if (!isset($_POST['action']) || $_POST['action'] != 'setup_action' || !current_user_can( 'manage_options' )) {
|
36 |
return;
|
44 |
if ($_POST[$key] == '') {
|
45 |
unset($options[$key]);
|
46 |
} else {
|
47 |
+
$options[$key] = tutor_sanitize_data($_POST[$key]);
|
48 |
}
|
49 |
}
|
50 |
} else {
|
69 |
}
|
70 |
}
|
71 |
update_option('tutor_withdraw_options', $payments);
|
72 |
+
|
73 |
// Add wizard flug
|
74 |
update_option('tutor_wizard', 'active');
|
75 |
|
95 |
}
|
96 |
|
97 |
public function tutor_setup_generator() {
|
98 |
+
|
99 |
$i = 1;
|
100 |
$html = '';
|
101 |
$options = (array) maybe_unserialize(get_option('tutor_option'));
|
147 |
$html .= '<span class="label-on">'.__('ON', 'tutor').'</span>';
|
148 |
$html .= '</label>';
|
149 |
break;
|
150 |
+
|
151 |
case 'text':
|
152 |
+
$html .= '<input type="text" name="'.$key.'" class="lesson-permalink" value="'.(isset($options[$key]) ? $options[$key] : '').'" />';
|
153 |
break;
|
154 |
+
|
155 |
case 'rows':
|
156 |
$html .= '<div class="content">';
|
157 |
$html .= '<div class="course-per-row">';
|
182 |
$html .= '</div>';
|
183 |
$html .= '</div>';
|
184 |
break;
|
185 |
+
|
186 |
case 'radio':
|
187 |
if ( isset($field['options']) ) {
|
188 |
foreach ($field['options'] as $k => $val) {
|
191 |
}
|
192 |
}
|
193 |
break;
|
194 |
+
|
195 |
case 'slider':
|
196 |
$available_times = array(
|
197 |
'seconds' => __( 'seconds' , 'tutor' ),
|
226 |
$html .= '<h5>'.$val['desc'].'</h5>';
|
227 |
$html .= '</label>';
|
228 |
$html .= '</div>';
|
229 |
+
|
230 |
if (isset($options[$key]) && $options[$key] == $val['value']) {
|
231 |
$selected_data .= '<div class="selected">';
|
232 |
$selected_data .= '<h3>'.$val['title'].'</h3>';
|
233 |
+
$selected_data .= '<h5>'.$val['desc'].'</h5>';
|
234 |
$selected_data .= '</div>';
|
235 |
}
|
236 |
}
|
306 |
|
307 |
case 'attempt':
|
308 |
$html .= '<div class="tutor-setting course-setting-wrapper">';
|
309 |
+
|
310 |
$html .= '<input type="hidden" name="quiz_attempts_allowed" value="'.$options[$key].'">';
|
311 |
|
312 |
$html .= '<div class="content">';
|
331 |
$html .= '</div>';
|
332 |
$html .= '</div>';
|
333 |
break;
|
334 |
+
|
335 |
default:
|
336 |
# code...
|
337 |
break;
|
538 |
'class' => 'tutor-show-hide',
|
539 |
'desc' => __('Choose your preferred withdrawal method from the options.', 'tutor')
|
540 |
),
|
541 |
+
|
542 |
+
|
543 |
)
|
544 |
),
|
545 |
|
548 |
|
549 |
return $general_fields;
|
550 |
}
|
551 |
+
|
552 |
public function tutor_setup_wizard_settings() {
|
553 |
|
554 |
$options = (array) maybe_unserialize(get_option('tutor_option'));
|
572 |
<?php wp_nonce_field( tutor()->nonce_action, tutor()->nonce ); ?>
|
573 |
<input type="hidden" name="action" value="setup_action">
|
574 |
<?php $course_marketplace = tutor_utils()->get_option('enable_course_marketplace'); ?>
|
575 |
+
<input type="hidden" name="enable_course_marketplace" class="enable_course_marketplace_data" value="<?php echo $course_marketplace ? 1 : 0; ?>">
|
576 |
<?php $earning = tutor_utils()->get_option('enable_tutor_earning'); ?>
|
577 |
+
<input type="hidden" name="enable_tutor_earning" class="enable_tutor_earning_data" value="<?php echo $earning ? 1 : 0; ?>">
|
578 |
<ul class="tutor-setup-content">
|
579 |
<?php $this->tutor_setup_generator(); ?>
|
580 |
<li>
|
581 |
<div class="tutor-setup-content-heading greetings">
|
582 |
<div class="header">
|
583 |
+
<img src="<?php echo esc_url(tutor()->url . 'assets/images/greeting-img.jpg'); ?>" alt="greeting">
|
584 |
</div>
|
585 |
<div class="content">
|
586 |
<h2><?php _e('Congratulations, you’re all set!', 'tutor'); ?></h2>
|
588 |
<p><?php _e( 'If you need further assistance, please don’t hesitate to contact us via our <a target="_blank" href="https://www.themeum.com/contact-us/">contact form.</a>', 'tutor' ); ?></p>
|
589 |
</div>
|
590 |
<div class="tutor-setup-content-footer footer">
|
591 |
+
<button class="tutor-redirect primary-btn" data-url="<?php echo esc_url( admin_url('post-new.php?post_type=courses') ); ?>"><?php _e('CREATE A NEW COURSE', 'tutor'); ?></button>
|
592 |
+
<button class="tutor-redirect primary-btn" data-url="<?php echo esc_url( admin_url('admin.php?page=tutor-addons') ); ?>"><?php _e('EXPLORE ADDONS', 'tutor'); ?></button>
|
593 |
</div>
|
594 |
</div>
|
595 |
</li>
|
605 |
|
606 |
|
607 |
public function tutor_setup_wizard_action() {
|
608 |
+
|
609 |
$html = '<div class="tutor-setup-content-footer footer">';
|
610 |
$html .= '<div class="tutor-setup-btn-wrapper">';
|
611 |
$html .= '<button class="tutor-setup-previous previous animated-btn">';
|
637 |
<div class="tutor-wizard-container">
|
638 |
<div class="tutor-wrapper-boarding tutor-setup-wizard-boarding active">
|
639 |
<div class="wizard-boarding-header">
|
640 |
+
<div><img src="<?php echo esc_url( tutor()->url.'assets/images/tutor-logo.svg' ); ?>" /></div>
|
641 |
<div><?php printf(__('Hello %s, welcome to Tutor LMS! Thank you for choosing us.', 'tutor'), $current_user->user_login); ?></div>
|
642 |
</div>
|
643 |
<div class="wizard-boarding-body">
|
644 |
<ul class="slider tutor-boarding">
|
645 |
<li>
|
646 |
|
647 |
+
<div class="slide-thumb"><img src="<?php echo esc_url( tutor()->url . 'assets/images/scalable_lms_solution.jpg' ); ?>" alt="<?php _e('A Powerful, Smart, and Scalable LMS Solution', 'tutor') ?>"/></div>
|
648 |
<div class="slide-title"><?php _e('A Powerful, Smart, and Scalable LMS Solution', 'tutor'); ?></div>
|
649 |
<div class="slide-subtitle"><?php _e('From individual instructors to vast eLearning platforms, Tutor LMS grows with you to create your ideal vision of an LMS website.', 'tutor'); ?></div>
|
650 |
</li>
|
651 |
<li>
|
652 |
+
<div class="slide-thumb"><img src="<?php echo esc_url( tutor()->url . 'assets/images/extensive_course_builder.jpg' ); ?>" alt="<?php _e('Extensive Course Builder', 'tutor') ?>"/></div>
|
653 |
<div class="slide-title"><?php _e('Extensive Course Builder', 'tutor'); ?></div>
|
654 |
<div class="slide-subtitle"><?php _e('Tutor LMS comes with a state-of-the-art frontend course builder. Construct rich and resourceful courses with ease.', 'tutor'); ?></div>
|
655 |
</li>
|
656 |
<li>
|
657 |
+
<div class="slide-thumb"><img src="<?php echo esc_url( tutor()->url . 'assets/images/advanced_quiz_creator.jpg' ); ?>" alt="<?php _e('Advanced Quiz Creator', 'tutor'); ?>"/></div>
|
658 |
<div class="slide-title"><?php _e('Advanced Quiz Creator', 'tutor'); ?></div>
|
659 |
<div class="slide-subtitle"><?php _e('Build interactive quizzes with the vast selection of question types and verify the learning of your students.', 'tutor'); ?></div>
|
660 |
</li>
|
661 |
<li>
|
662 |
+
<div class="slide-thumb"><img src="<?php echo esc_url( tutor()->url . 'assets/images/freedom_with_ecommerce.jpg' ); ?>" alt="<?php _e('Freedom With eCommerce', 'tutor'); ?>"/></div>
|
663 |
<div class="slide-title"><?php _e('Freedom With eCommerce', 'tutor'); ?></div>
|
664 |
<div class="slide-subtitle"><?php _e('Select an eCommerce plugin and sell courses any way you like and use any payment gateway you want!', 'tutor'); ?></div>
|
665 |
</li>
|
666 |
<li>
|
667 |
+
<div class="slide-thumb"><img src="<?php echo esc_url( tutor()->url . 'assets/images/reports_and_analytics.jpg' ); ?>" alt="<?php _e('Reports and Analytics', 'tutor'); ?>"/></div>
|
668 |
<div class="slide-title"><?php _e('Reports and Analytics', 'tutor'); ?></div>
|
669 |
<div class="slide-subtitle"><?php _e('Track what type of courses sell the most! Gain insights on user purchases, manage reviews and track quiz attempts.', 'tutor'); ?></div>
|
670 |
</li>
|
679 |
</svg>
|
680 |
</button>
|
681 |
</div>
|
682 |
+
<div><a href="<?php echo esc_url( admin_url() ); ?>"><?php _e('I already know, skip this!', 'tutor'); ?></a></div>
|
683 |
</div>
|
684 |
</div>
|
685 |
</div>
|
692 |
<div class="tutor-wizard-container">
|
693 |
<div class="tutor-wrapper-type tutor-setup-wizard-type">
|
694 |
<div class="wizard-type-header">
|
695 |
+
<div class="logo"><img src="<?php echo esc_url( tutor()->url.'assets/images/tutor-logo.svg' ); ?>" /></div>
|
696 |
<div class="title"><?php _e('Let’s get the platform up and running', 'tutor'); ?></div>
|
697 |
<div class="subtitle"><?php _e('Pick a category for your LMS platform. You can always update this later.', 'tutor'); ?></div>
|
698 |
</div>
|
701 |
<input id="enable_course_marketplace-0" type="radio" name="enable_course_marketplace_setup" value="0" <?php if(!$course_marketplace){ echo 'checked'; } ?> />
|
702 |
<span class="icon"></span>
|
703 |
<label for="enable_course_marketplace-0">
|
704 |
+
<img src="<?php echo esc_url( tutor()->url.'assets/images/single-marketplace.png' ); ?>" />
|
705 |
<div class="title"><?php _e( 'Individual', 'tutor' ); ?></div>
|
706 |
<div class="subtitle"><?php _e( 'I want to start my solo journey as an educator and spread my knowledge.', 'tutor' ); ?></div>
|
707 |
</label>
|
711 |
<input id="enable_course_marketplace-1" type="radio" name="enable_course_marketplace_setup" value="1" <?php if($course_marketplace){ echo 'checked'; } ?>/>
|
712 |
<span class="icon"></span>
|
713 |
<label for="enable_course_marketplace-1">
|
714 |
+
<img src="<?php echo esc_url( tutor()->url.'assets/images/multiple-marketplace.png' ); ?>" />
|
715 |
<div class="title"><?php _e( 'Marketplace', 'tutor' ); ?></div>
|
716 |
<div class="subtitle"><?php _e( 'I want to create an eLearning platform to let anyone earn by teaching online.', 'tutor' ); ?></div>
|
717 |
</label>
|
classes/Upgrader.php
CHANGED
@@ -2,42 +2,41 @@
|
|
2 |
|
3 |
namespace TUTOR;
|
4 |
|
5 |
-
|
6 |
-
if ( ! defined( 'ABSPATH' ) )
|
7 |
exit;
|
|
|
8 |
|
9 |
class Upgrader {
|
10 |
|
11 |
public function __construct() {
|
12 |
-
add_action('admin_init', array($this, 'init_upgrader'));
|
13 |
|
14 |
$base_name = tutor()->basename;
|
15 |
-
add_action( 'in_plugin_update_message-'
|
16 |
|
17 |
/**
|
18 |
* Installing Gradebook Addon from TutorPro
|
19 |
-
*
|
20 |
*/
|
21 |
-
add_action('tutor_addon_before_enable_tutor-pro/addons/gradebook/gradebook.php', array($this, 'install_gradebook'));
|
22 |
-
add_action('tutor_addon_before_enable_tutor-pro/addons/tutor-email/tutor-email.php', array($this, 'install_tutor_email_queue'));
|
23 |
-
add_action('upgrader_process_complete', array($this, 'init_email_table_deployment'), 10, 2);
|
24 |
}
|
25 |
|
26 |
-
public function init_upgrader(){
|
27 |
$upgrades = $this->available_upgrades();
|
28 |
|
29 |
-
if (tutor_utils()->count($upgrades)){
|
30 |
-
foreach ($upgrades as $upgrade){
|
31 |
$this->{$upgrade}();
|
32 |
}
|
33 |
}
|
34 |
}
|
35 |
|
36 |
-
public function available_upgrades(){
|
37 |
-
$version = get_option('tutor_version');
|
38 |
|
39 |
$upgrades = array();
|
40 |
-
if ($version){
|
41 |
$upgrades[] = 'upgrade_to_1_3_1';
|
42 |
}
|
43 |
|
@@ -47,26 +46,26 @@ class Upgrader {
|
|
47 |
/**
|
48 |
* Upgrade to version 1.3.1
|
49 |
*/
|
50 |
-
public function upgrade_to_1_3_1(){
|
51 |
-
if (version_compare(get_option('tutor_version'), '1.3.1', '<')) {
|
52 |
global $wpdb;
|
53 |
|
54 |
-
if ( ! get_option('is_course_post_type_updated')){
|
55 |
-
$wpdb->update($wpdb->posts, array('post_type' => 'courses'), array('post_type' => 'course'));
|
56 |
-
update_option('is_course_post_type_updated', true);
|
57 |
-
update_option('tutor_version', '1.3.1');
|
58 |
flush_rewrite_rules();
|
59 |
}
|
60 |
}
|
61 |
}
|
62 |
|
63 |
|
64 |
-
public function in_plugin_update_message( $args, $response ){
|
65 |
-
$upgrade_notice = strip_tags(tutils()->array_get('upgrade_notice', $response));
|
66 |
-
if ($upgrade_notice){
|
67 |
-
$upgrade_notice =
|
68 |
|
69 |
-
echo apply_filters( 'tutor_in_plugin_update_message', $upgrade_notice ? '</p> <div class="tutor_plugin_update_notice">'
|
70 |
}
|
71 |
}
|
72 |
|
@@ -76,16 +75,16 @@ class Upgrader {
|
|
76 |
*
|
77 |
* @since v.1.4.2
|
78 |
*/
|
79 |
-
public function install_gradebook(){
|
80 |
global $wpdb;
|
81 |
|
82 |
-
$exists_gradebook_table
|
83 |
-
$exists_gradebook_results_table = $wpdb->query("SHOW TABLES LIKE '{$wpdb->tutor_gradebooks_results}';");
|
84 |
-
$charset_collate
|
85 |
|
86 |
-
require_once
|
87 |
|
88 |
-
if ( ! $exists_gradebook_table){
|
89 |
$gradebook_table = "CREATE TABLE IF NOT EXISTS {$wpdb->tutor_gradebooks} (
|
90 |
gradebook_id int(11) NOT NULL AUTO_INCREMENT,
|
91 |
grade_name varchar(50) DEFAULT NULL,
|
@@ -98,7 +97,7 @@ class Upgrader {
|
|
98 |
) $charset_collate;";
|
99 |
dbDelta( $gradebook_table );
|
100 |
}
|
101 |
-
if ( ! $exists_gradebook_results_table){
|
102 |
$gradebook_results = "CREATE TABLE IF NOT EXISTS {$wpdb->tutor_gradebooks_results} (
|
103 |
gradebook_result_id int(11) NOT NULL AUTO_INCREMENT,
|
104 |
user_id int(11) DEFAULT NULL,
|
@@ -120,11 +119,11 @@ class Upgrader {
|
|
120 |
|
121 |
}
|
122 |
|
123 |
-
public function init_email_table_deployment($upgrader_object, $options ) {
|
124 |
|
125 |
-
if( is_object( $upgrader_object ) && is_array($upgrader_object->result) && isset($upgrader_object->result['destination_name']) && $upgrader_object->result['destination_name']=='tutor-pro' ) {
|
126 |
-
$addonConfig = tutor_utils()->get_addon_config('tutor-pro/addons/tutor-email/tutor-email.php');
|
127 |
-
$isEnable
|
128 |
|
129 |
$isEnable ? $this->install_tutor_email_queue() : 0;
|
130 |
}
|
@@ -138,10 +137,10 @@ class Upgrader {
|
|
138 |
public function install_tutor_email_queue() {
|
139 |
|
140 |
global $wpdb;
|
141 |
-
$exists_email_queue_table = $wpdb->query("SHOW TABLES LIKE '{$wpdb->tutor_email_queue}';");
|
142 |
-
$charset_collate
|
143 |
|
144 |
-
require_once
|
145 |
|
146 |
if ( ! $exists_email_queue_table ) {
|
147 |
$table = "CREATE TABLE IF NOT EXISTS {$wpdb->tutor_email_queue} (
|
@@ -152,8 +151,8 @@ class Upgrader {
|
|
152 |
headers text NOT NULL,
|
153 |
PRIMARY KEY (id)
|
154 |
) {$charset_collate};";
|
155 |
-
|
156 |
dbDelta( $table );
|
157 |
}
|
158 |
}
|
159 |
-
}
|
2 |
|
3 |
namespace TUTOR;
|
4 |
|
5 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
|
6 |
exit;
|
7 |
+
}
|
8 |
|
9 |
class Upgrader {
|
10 |
|
11 |
public function __construct() {
|
12 |
+
add_action( 'admin_init', array( $this, 'init_upgrader' ) );
|
13 |
|
14 |
$base_name = tutor()->basename;
|
15 |
+
add_action( 'in_plugin_update_message-' . $base_name, array( $this, 'in_plugin_update_message' ), 10, 2 );
|
16 |
|
17 |
/**
|
18 |
* Installing Gradebook Addon from TutorPro
|
|
|
19 |
*/
|
20 |
+
add_action( 'tutor_addon_before_enable_tutor-pro/addons/gradebook/gradebook.php', array( $this, 'install_gradebook' ) );
|
21 |
+
add_action( 'tutor_addon_before_enable_tutor-pro/addons/tutor-email/tutor-email.php', array( $this, 'install_tutor_email_queue' ) );
|
22 |
+
add_action( 'upgrader_process_complete', array( $this, 'init_email_table_deployment' ), 10, 2 );
|
23 |
}
|
24 |
|
25 |
+
public function init_upgrader() {
|
26 |
$upgrades = $this->available_upgrades();
|
27 |
|
28 |
+
if ( tutor_utils()->count( $upgrades ) ) {
|
29 |
+
foreach ( $upgrades as $upgrade ) {
|
30 |
$this->{$upgrade}();
|
31 |
}
|
32 |
}
|
33 |
}
|
34 |
|
35 |
+
public function available_upgrades() {
|
36 |
+
$version = get_option( 'tutor_version' );
|
37 |
|
38 |
$upgrades = array();
|
39 |
+
if ( $version ) {
|
40 |
$upgrades[] = 'upgrade_to_1_3_1';
|
41 |
}
|
42 |
|
46 |
/**
|
47 |
* Upgrade to version 1.3.1
|
48 |
*/
|
49 |
+
public function upgrade_to_1_3_1() {
|
50 |
+
if ( version_compare( get_option( 'tutor_version' ), '1.3.1', '<' ) ) {
|
51 |
global $wpdb;
|
52 |
|
53 |
+
if ( ! get_option( 'is_course_post_type_updated' ) ) {
|
54 |
+
$wpdb->update( $wpdb->posts, array( 'post_type' => 'courses' ), array( 'post_type' => 'course' ) );
|
55 |
+
update_option( 'is_course_post_type_updated', true );
|
56 |
+
update_option( 'tutor_version', '1.3.1' );
|
57 |
flush_rewrite_rules();
|
58 |
}
|
59 |
}
|
60 |
}
|
61 |
|
62 |
|
63 |
+
public function in_plugin_update_message( $args, $response ) {
|
64 |
+
$upgrade_notice = strip_tags( tutils()->array_get( 'upgrade_notice', $response ) );
|
65 |
+
if ( $upgrade_notice ) {
|
66 |
+
$upgrade_notice = '<span class="version"><code>v.' . $response->new_version . '</code></span> <br />' . $upgrade_notice;
|
67 |
|
68 |
+
echo apply_filters( 'tutor_in_plugin_update_message', ($upgrade_notice ? '</p> <div class="tutor_plugin_update_notice">' . $upgrade_notice . '</div> <p class="dummy">' : '') );
|
69 |
}
|
70 |
}
|
71 |
|
75 |
*
|
76 |
* @since v.1.4.2
|
77 |
*/
|
78 |
+
public function install_gradebook() {
|
79 |
global $wpdb;
|
80 |
|
81 |
+
$exists_gradebook_table = $wpdb->query( "SHOW TABLES LIKE '{$wpdb->tutor_gradebooks}';" );
|
82 |
+
$exists_gradebook_results_table = $wpdb->query( "SHOW TABLES LIKE '{$wpdb->tutor_gradebooks_results}';" );
|
83 |
+
$charset_collate = $wpdb->get_charset_collate();
|
84 |
|
85 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
86 |
|
87 |
+
if ( ! $exists_gradebook_table ) {
|
88 |
$gradebook_table = "CREATE TABLE IF NOT EXISTS {$wpdb->tutor_gradebooks} (
|
89 |
gradebook_id int(11) NOT NULL AUTO_INCREMENT,
|
90 |
grade_name varchar(50) DEFAULT NULL,
|
97 |
) $charset_collate;";
|
98 |
dbDelta( $gradebook_table );
|
99 |
}
|
100 |
+
if ( ! $exists_gradebook_results_table ) {
|
101 |
$gradebook_results = "CREATE TABLE IF NOT EXISTS {$wpdb->tutor_gradebooks_results} (
|
102 |
gradebook_result_id int(11) NOT NULL AUTO_INCREMENT,
|
103 |
user_id int(11) DEFAULT NULL,
|
119 |
|
120 |
}
|
121 |
|
122 |
+
public function init_email_table_deployment( $upgrader_object, $options ) {
|
123 |
|
124 |
+
if ( is_object( $upgrader_object ) && is_array( $upgrader_object->result ) && isset( $upgrader_object->result['destination_name'] ) && $upgrader_object->result['destination_name'] == 'tutor-pro' ) {
|
125 |
+
$addonConfig = tutor_utils()->get_addon_config( 'tutor-pro/addons/tutor-email/tutor-email.php' );
|
126 |
+
$isEnable = (bool) tutor_utils()->avalue_dot( 'is_enable', $addonConfig );
|
127 |
|
128 |
$isEnable ? $this->install_tutor_email_queue() : 0;
|
129 |
}
|
137 |
public function install_tutor_email_queue() {
|
138 |
|
139 |
global $wpdb;
|
140 |
+
$exists_email_queue_table = $wpdb->query( "SHOW TABLES LIKE '{$wpdb->tutor_email_queue}';" );
|
141 |
+
$charset_collate = $wpdb->get_charset_collate();
|
142 |
|
143 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
144 |
|
145 |
if ( ! $exists_email_queue_table ) {
|
146 |
$table = "CREATE TABLE IF NOT EXISTS {$wpdb->tutor_email_queue} (
|
151 |
headers text NOT NULL,
|
152 |
PRIMARY KEY (id)
|
153 |
) {$charset_collate};";
|
154 |
+
|
155 |
dbDelta( $table );
|
156 |
}
|
157 |
}
|
158 |
+
}
|
classes/User.php
CHANGED
@@ -2,8 +2,9 @@
|
|
2 |
|
3 |
namespace TUTOR;
|
4 |
|
5 |
-
if ( ! defined( 'ABSPATH' ) )
|
6 |
exit;
|
|
|
7 |
|
8 |
|
9 |
class User {
|
@@ -11,16 +12,16 @@ class User {
|
|
11 |
private static $hide_registration_notice = false;
|
12 |
|
13 |
public function __construct() {
|
14 |
-
add_action('edit_user_profile', array($this, 'edit_user_profile'));
|
15 |
-
add_action('show_user_profile', array($this, 'edit_user_profile'), 10, 1);
|
16 |
|
17 |
-
add_action('profile_update', array($this, 'profile_update'));
|
18 |
-
add_action('set_user_role', array($this, 'set_user_role'), 10, 3);
|
19 |
|
20 |
-
add_action('wp_ajax_tutor_user_photo_remove', array($this, 'tutor_user_photo_remove'));
|
21 |
-
add_action('wp_ajax_tutor_user_photo_upload', array($this, 'update_user_photo'));
|
22 |
-
|
23 |
-
add_action('tutor_options_after_instructors', array($this, 'tutor_instructor_profile_layout'));
|
24 |
// add_action('tutor_options_after_students', array($this, 'tutor_student_profile_layout'));
|
25 |
|
26 |
add_action( 'admin_notices', array( $this, 'show_registration_disabled' ) );
|
@@ -30,53 +31,64 @@ class User {
|
|
30 |
private $profile_layout = array(
|
31 |
'pp-circle',
|
32 |
'pp-rectangle',
|
33 |
-
'no-cp'
|
34 |
);
|
35 |
|
36 |
/**
|
37 |
* Show layout selection dashboard in instructor and student setting
|
38 |
*/
|
39 |
-
public function tutor_instructor_profile_layout(){
|
40 |
-
tutor_load_template(
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
42 |
-
public function tutor_student_profile_layout(){
|
43 |
-
tutor_load_template(
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
}
|
45 |
|
46 |
-
public function edit_user_profile($user){
|
47 |
-
include
|
48 |
}
|
49 |
|
50 |
-
private function delete_existing_user_photo($user_id, $type){
|
51 |
-
$meta_key = $type=='cover_photo' ? '_tutor_cover_photo' : '_tutor_profile_photo';
|
52 |
-
$photo_id = get_user_meta($user_id, $meta_key, true);
|
53 |
-
is_numeric($photo_id) ? wp_delete_attachment( $photo_id, true) : 0;
|
54 |
-
delete_user_meta( $user_id, $meta_key);
|
55 |
}
|
56 |
|
57 |
-
public function tutor_user_photo_remove(){
|
58 |
tutils()->checking_nonce();
|
59 |
-
|
60 |
-
$this->delete_existing_user_photo(get_current_user_id(), $_POST['photo_type']);
|
61 |
}
|
62 |
|
63 |
-
public function update_user_photo(){
|
64 |
tutils()->checking_nonce();
|
65 |
|
66 |
-
$user_id
|
67 |
-
$meta_key = $_POST['photo_type']=='cover_photo' ? '_tutor_cover_photo' : '_tutor_profile_photo';
|
68 |
-
|
69 |
/**
|
70 |
* Photo Update from profile
|
71 |
-
*
|
72 |
*/
|
73 |
-
$photo
|
74 |
-
$photo_size = tutils()->array_get('size', $photo);
|
75 |
-
$photo_type = tutils()->array_get('type', $photo);
|
76 |
|
77 |
-
if ($photo_size && strpos($photo_type, 'image') !== false) {
|
78 |
if ( ! function_exists( 'wp_handle_upload' ) ) {
|
79 |
-
require_once
|
80 |
}
|
81 |
|
82 |
$upload_overrides = array( 'test_form' => false );
|
@@ -86,79 +98,83 @@ class User {
|
|
86 |
$file_path = tutils()->array_get( 'file', $movefile );
|
87 |
$file_url = tutils()->array_get( 'url', $movefile );
|
88 |
|
89 |
-
$media_id = wp_insert_attachment(
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
98 |
// wp_generate_attachment_metadata() won't work if you do not include this file
|
99 |
-
require_once
|
100 |
|
101 |
// Generate and save the attachment metas into the database
|
102 |
wp_update_attachment_metadata( $media_id, wp_generate_attachment_metadata( $media_id, $file_path ) );
|
103 |
|
104 |
-
//Update it to user profile
|
105 |
-
$this->delete_existing_user_photo($user_id, $_POST['photo_type']);
|
106 |
-
update_user_meta($user_id, $meta_key, $media_id );
|
107 |
|
108 |
-
exit(json_encode(array('status'=>'success')));
|
109 |
}
|
110 |
}
|
111 |
}
|
112 |
}
|
113 |
|
114 |
-
public function profile_update($user_id){
|
115 |
-
if (tutils()->array_get('tutor_action', $_POST) !== 'tutor_profile_update_by_wp' ){
|
116 |
return;
|
117 |
}
|
118 |
|
119 |
-
$_tutor_profile_job_title = sanitize_text_field(tutor_utils()->avalue_dot('_tutor_profile_job_title', $_POST));
|
120 |
-
$_tutor_profile_bio
|
121 |
-
$_tutor_profile_image
|
122 |
|
123 |
-
update_user_meta($user_id, '_tutor_profile_job_title', $_tutor_profile_job_title);
|
124 |
-
update_user_meta($user_id, '_tutor_profile_bio', $_tutor_profile_bio);
|
125 |
-
update_user_meta($user_id, '_tutor_profile_photo', $_tutor_profile_image);
|
126 |
}
|
127 |
|
128 |
-
public function set_user_role($user_id, $role, $old_roles ){
|
129 |
$instructor_role = tutor()->instructor_role;
|
130 |
|
131 |
-
if (in_array($instructor_role, $old_roles)){
|
132 |
// tutor_utils()->remove_instructor_role($user_id);
|
133 |
}
|
134 |
|
135 |
// if ($role === $instructor_role){
|
136 |
-
if ($role === $instructor_role || in_array($instructor_role, $old_roles)){
|
137 |
-
tutor_utils()->add_instructor_role($user_id);
|
138 |
}
|
139 |
}
|
140 |
|
141 |
public function hide_notices() {
|
142 |
-
if(is_admin() && isset( $_GET['tutor-hide-notice'] ) && $_GET['tutor-hide-notice']=='registration') {
|
143 |
-
tutils()->checking_nonce('get');
|
144 |
|
145 |
-
if(isset($_GET['tutor-registration']) && $_GET['tutor-registration']==='enable') {
|
146 |
update_option( 'users_can_register', 1 );
|
147 |
} else {
|
148 |
self::$hide_registration_notice = true;
|
149 |
-
setcookie('tutor_notice_hide_registration', 1, time() + (86400 * 30), tutor()->basepath);
|
150 |
}
|
151 |
}
|
152 |
}
|
153 |
|
154 |
public function show_registration_disabled() {
|
155 |
|
156 |
-
if(
|
157 |
self::$hide_registration_notice ||
|
158 |
-
!tutils()->is_tutor_dashboard() ||
|
159 |
-
get_option( 'users_can_register' ) ||
|
160 |
isset( $_COOKIE['tutor_notice_hide_registration'] ) ||
|
161 |
-
!current_user_can( 'manage_options' )
|
162 |
) {
|
163 |
return;
|
164 |
}
|
@@ -168,18 +184,18 @@ class User {
|
|
168 |
<div class="wrap tutor-user-registration-notice-wrapper">
|
169 |
<div class="tutor-user-registration-notice">
|
170 |
<div>
|
171 |
-
<img src="<?php echo tutor()->url
|
172 |
</div>
|
173 |
<div>
|
174 |
-
<?php _e('As membership is turned off, students and instructors will not be able to sign up. <strong>Press Enable</strong> or go to <strong>Settings > General > Membership</strong> and enable "Anyone can register".'); ?>
|
175 |
</div>
|
176 |
<div>
|
177 |
-
<a href="<?php echo esc_url( add_query_arg( 'tutor-registration', 'enable', $hide_url ) ); ?>"><?php _e('Enable', 'tutor'); ?></a>
|
178 |
<hr/>
|
179 |
-
<a href="<?php echo esc_url( $hide_url ); ?>"><?php _e('Dismiss', 'tutor'); ?></a>
|
180 |
</div>
|
181 |
</div>
|
182 |
</div>
|
183 |
<?php
|
184 |
}
|
185 |
-
}
|
2 |
|
3 |
namespace TUTOR;
|
4 |
|
5 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
6 |
exit;
|
7 |
+
}
|
8 |
|
9 |
|
10 |
class User {
|
12 |
private static $hide_registration_notice = false;
|
13 |
|
14 |
public function __construct() {
|
15 |
+
add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
|
16 |
+
add_action( 'show_user_profile', array( $this, 'edit_user_profile' ), 10, 1 );
|
17 |
|
18 |
+
add_action( 'profile_update', array( $this, 'profile_update' ) );
|
19 |
+
add_action( 'set_user_role', array( $this, 'set_user_role' ), 10, 3 );
|
20 |
|
21 |
+
add_action( 'wp_ajax_tutor_user_photo_remove', array( $this, 'tutor_user_photo_remove' ) );
|
22 |
+
add_action( 'wp_ajax_tutor_user_photo_upload', array( $this, 'update_user_photo' ) );
|
23 |
+
|
24 |
+
add_action( 'tutor_options_after_instructors', array( $this, 'tutor_instructor_profile_layout' ) );
|
25 |
// add_action('tutor_options_after_students', array($this, 'tutor_student_profile_layout'));
|
26 |
|
27 |
add_action( 'admin_notices', array( $this, 'show_registration_disabled' ) );
|
31 |
private $profile_layout = array(
|
32 |
'pp-circle',
|
33 |
'pp-rectangle',
|
34 |
+
'no-cp',
|
35 |
);
|
36 |
|
37 |
/**
|
38 |
* Show layout selection dashboard in instructor and student setting
|
39 |
*/
|
40 |
+
public function tutor_instructor_profile_layout() {
|
41 |
+
tutor_load_template(
|
42 |
+
'public-profile-setting',
|
43 |
+
array(
|
44 |
+
'profile_templates' => $this->profile_layout,
|
45 |
+
'layout_option_name' => 'instructor',
|
46 |
+
)
|
47 |
+
);
|
48 |
}
|
49 |
+
public function tutor_student_profile_layout() {
|
50 |
+
tutor_load_template(
|
51 |
+
'public-profile-setting',
|
52 |
+
array(
|
53 |
+
'profile_templates' => $this->profile_layout,
|
54 |
+
'layout_option_name' => 'student',
|
55 |
+
)
|
56 |
+
);
|
57 |
}
|
58 |
|
59 |
+
public function edit_user_profile( $user ) {
|
60 |
+
include tutor()->path . 'views/metabox/user-profile-fields.php';
|
61 |
}
|
62 |
|
63 |
+
private function delete_existing_user_photo( $user_id, $type ) {
|
64 |
+
$meta_key = $type == 'cover_photo' ? '_tutor_cover_photo' : '_tutor_profile_photo';
|
65 |
+
$photo_id = get_user_meta( $user_id, $meta_key, true );
|
66 |
+
is_numeric( $photo_id ) ? wp_delete_attachment( $photo_id, true ) : 0;
|
67 |
+
delete_user_meta( $user_id, $meta_key );
|
68 |
}
|
69 |
|
70 |
+
public function tutor_user_photo_remove() {
|
71 |
tutils()->checking_nonce();
|
72 |
+
|
73 |
+
$this->delete_existing_user_photo( get_current_user_id(), tutor_sanitize_data( $_POST['photo_type'] ) );
|
74 |
}
|
75 |
|
76 |
+
public function update_user_photo() {
|
77 |
tutils()->checking_nonce();
|
78 |
|
79 |
+
$user_id = get_current_user_id();
|
80 |
+
$meta_key = sanitize_text_field( $_POST['photo_type'] ) == 'cover_photo' ? '_tutor_cover_photo' : '_tutor_profile_photo';
|
81 |
+
|
82 |
/**
|
83 |
* Photo Update from profile
|
|
|
84 |
*/
|
85 |
+
$photo = tutils()->array_get( 'photo_file', $_FILES );
|
86 |
+
$photo_size = tutils()->array_get( 'size', $photo );
|
87 |
+
$photo_type = tutils()->array_get( 'type', $photo );
|
88 |
|
89 |
+
if ( $photo_size && strpos( $photo_type, 'image' ) !== false ) {
|
90 |
if ( ! function_exists( 'wp_handle_upload' ) ) {
|
91 |
+
require_once ABSPATH . 'wp-admin/includes/file.php';
|
92 |
}
|
93 |
|
94 |
$upload_overrides = array( 'test_form' => false );
|
98 |
$file_path = tutils()->array_get( 'file', $movefile );
|
99 |
$file_url = tutils()->array_get( 'url', $movefile );
|
100 |
|
101 |
+
$media_id = wp_insert_attachment(
|
102 |
+
array(
|
103 |
+
'guid' => $file_path,
|
104 |
+
'post_mime_type' => mime_content_type( $file_path ),
|
105 |
+
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_url ) ),
|
106 |
+
'post_content' => '',
|
107 |
+
'post_status' => 'inherit',
|
108 |
+
),
|
109 |
+
$file_path,
|
110 |
+
0
|
111 |
+
);
|
112 |
+
|
113 |
+
if ( $media_id ) {
|
114 |
// wp_generate_attachment_metadata() won't work if you do not include this file
|
115 |
+
require_once ABSPATH . 'wp-admin/includes/image.php';
|
116 |
|
117 |
// Generate and save the attachment metas into the database
|
118 |
wp_update_attachment_metadata( $media_id, wp_generate_attachment_metadata( $media_id, $file_path ) );
|
119 |
|
120 |
+
// Update it to user profile
|
121 |
+
$this->delete_existing_user_photo( $user_id, tutor_sanitize_data($_POST['photo_type']) );
|
122 |
+
update_user_meta( $user_id, $meta_key, $media_id );
|
123 |
|
124 |
+
exit( json_encode( array( 'status' => 'success' ) ) );
|
125 |
}
|
126 |
}
|
127 |
}
|
128 |
}
|
129 |
|
130 |
+
public function profile_update( $user_id ) {
|
131 |
+
if ( tutils()->array_get( 'tutor_action', $_POST ) !== 'tutor_profile_update_by_wp' ) {
|
132 |
return;
|
133 |
}
|
134 |
|
135 |
+
$_tutor_profile_job_title = sanitize_text_field( tutor_utils()->avalue_dot( '_tutor_profile_job_title', $_POST ) );
|
136 |
+
$_tutor_profile_bio = wp_kses_post( tutor_utils()->avalue_dot( '_tutor_profile_bio', $_POST ) );
|
137 |
+
$_tutor_profile_image = wp_kses_post( tutor_utils()->avalue_dot( '_tutor_profile_photo', $_POST ) );
|
138 |
|
139 |
+
update_user_meta( $user_id, '_tutor_profile_job_title', $_tutor_profile_job_title );
|
140 |
+
update_user_meta( $user_id, '_tutor_profile_bio', $_tutor_profile_bio );
|
141 |
+
update_user_meta( $user_id, '_tutor_profile_photo', $_tutor_profile_image );
|
142 |
}
|
143 |
|
144 |
+
public function set_user_role( $user_id, $role, $old_roles ) {
|
145 |
$instructor_role = tutor()->instructor_role;
|
146 |
|
147 |
+
if ( in_array( $instructor_role, $old_roles ) ) {
|
148 |
// tutor_utils()->remove_instructor_role($user_id);
|
149 |
}
|
150 |
|
151 |
// if ($role === $instructor_role){
|
152 |
+
if ( $role === $instructor_role || in_array( $instructor_role, $old_roles ) ) {
|
153 |
+
tutor_utils()->add_instructor_role( $user_id );
|
154 |
}
|
155 |
}
|
156 |
|
157 |
public function hide_notices() {
|
158 |
+
if ( is_admin() && isset( $_GET['tutor-hide-notice'] ) && $_GET['tutor-hide-notice'] == 'registration' ) {
|
159 |
+
tutils()->checking_nonce( 'get' );
|
160 |
|
161 |
+
if ( isset( $_GET['tutor-registration'] ) && $_GET['tutor-registration'] === 'enable' ) {
|
162 |
update_option( 'users_can_register', 1 );
|
163 |
} else {
|
164 |
self::$hide_registration_notice = true;
|
165 |
+
setcookie( 'tutor_notice_hide_registration', 1, time() + ( 86400 * 30 ), tutor()->basepath );
|
166 |
}
|
167 |
}
|
168 |
}
|
169 |
|
170 |
public function show_registration_disabled() {
|
171 |
|
172 |
+
if (
|
173 |
self::$hide_registration_notice ||
|
174 |
+
! tutils()->is_tutor_dashboard() ||
|
175 |
+
get_option( 'users_can_register' ) ||
|
176 |
isset( $_COOKIE['tutor_notice_hide_registration'] ) ||
|
177 |
+
! current_user_can( 'manage_options' )
|
178 |
) {
|
179 |
return;
|
180 |
}
|
184 |
<div class="wrap tutor-user-registration-notice-wrapper">
|
185 |
<div class="tutor-user-registration-notice">
|
186 |
<div>
|
187 |
+
<img src="<?php echo esc_url( tutor()->url . 'assets/images/icon-info-round.svg' ); ?>"/>
|
188 |
</div>
|
189 |
<div>
|
190 |
+
<?php _e( 'As membership is turned off, students and instructors will not be able to sign up. <strong>Press Enable</strong> or go to <strong>Settings > General > Membership</strong> and enable "Anyone can register".' ); ?>
|
191 |
</div>
|
192 |
<div>
|
193 |
+
<a href="<?php echo esc_url( add_query_arg( 'tutor-registration', 'enable', $hide_url ) ); ?>"><?php _e( 'Enable', 'tutor' ); ?></a>
|
194 |
<hr/>
|
195 |
+
<a href="<?php echo esc_url( $hide_url ); ?>"><?php _e( 'Dismiss', 'tutor' ); ?></a>
|
196 |
</div>
|
197 |
</div>
|
198 |
</div>
|
199 |
<?php
|
200 |
}
|
201 |
+
}
|
classes/Utils.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Tutor Utils Helper functions
|
|
|
4 |
* @package TUTOR
|
5 |
*
|
6 |
* @since v.1.0.0
|
@@ -8,8 +9,9 @@
|
|
8 |
|
9 |
namespace TUTOR;
|
10 |
|
11 |
-
if ( ! defined( 'ABSPATH' ) )
|
12 |
exit;
|
|
|
13 |
|
14 |
class Utils {
|
15 |
/**
|
@@ -23,7 +25,7 @@ class Utils {
|
|
23 |
* @since v.1.0.0
|
24 |
*/
|
25 |
public function get_option( $key = null, $default = false ) {
|
26 |
-
$option = (array) maybe_unserialize(get_option('tutor_option'));
|
27 |
|
28 |
if ( empty( $option ) || ! is_array( $option ) ) {
|
29 |
return $default;
|
@@ -32,17 +34,17 @@ class Utils {
|
|
32 |
return $option;
|
33 |
}
|
34 |
if ( array_key_exists( $key, $option ) ) {
|
35 |
-
return apply_filters( $key, $option[$key] );
|
36 |
}
|
37 |
-
//Access array value via dot notation, such as option->get('value.subvalue')
|
38 |
-
if ( strpos($key, '.') ) {
|
39 |
$option_key_array = explode( '.', $key );
|
40 |
|
41 |
$new_option = $option;
|
42 |
foreach ( $option_key_array as $dotKey ) {
|
43 |
-
if ( isset( $new_option[$dotKey] ) ) {
|
44 |
-
$new_option = $new_option[$dotKey];
|
45 |
-
}else{
|
46 |
return $default;
|
47 |
}
|
48 |
}
|
@@ -61,13 +63,13 @@ class Utils {
|
|
61 |
* @since v.1.0.0
|
62 |
*/
|
63 |
public function update_option( $key = null, $value = false ) {
|
64 |
-
$option
|
65 |
-
$option[$key] = $value;
|
66 |
update_option( 'tutor_option', $option );
|
67 |
}
|
68 |
|
69 |
/**
|
70 |
-
* @param null
|
71 |
* @param array $array
|
72 |
*
|
73 |
* @return array|bool|mixed
|
@@ -80,7 +82,7 @@ class Utils {
|
|
80 |
*/
|
81 |
public function avalue_dot( $key = null, $array = array(), $default = false ) {
|
82 |
$array = (array) $array;
|
83 |
-
if ( ! $key || ! count($array) ) {
|
84 |
return $default;
|
85 |
}
|
86 |
$option_key_array = explode( '.', $key );
|
@@ -88,8 +90,8 @@ class Utils {
|
|
88 |
$value = $array;
|
89 |
|
90 |
foreach ( $option_key_array as $dotKey ) {
|
91 |
-
if ( isset( $value[$dotKey] ) ) {
|
92 |
-
$value = $value[$dotKey];
|
93 |
} else {
|
94 |
return $default;
|
95 |
}
|
@@ -98,7 +100,7 @@ class Utils {
|
|
98 |
}
|
99 |
|
100 |
/**
|
101 |
-
* @param null
|
102 |
* @param array $array
|
103 |
*
|
104 |
* @return array|bool|mixed
|
@@ -126,15 +128,15 @@ class Utils {
|
|
126 |
|
127 |
do_action( 'tutor_utils/get_pages/before' );
|
128 |
|
129 |
-
$pages
|
130 |
$wp_pages = get_pages();
|
131 |
|
132 |
-
if (is_array($wp_pages) && count($wp_pages)) {
|
133 |
-
foreach ($wp_pages as $page) {
|
134 |
-
$pages[$page->ID] = $page->post_title;
|
135 |
}
|
136 |
}
|
137 |
-
|
138 |
do_action( 'tutor_utils/get_pages/after' );
|
139 |
|
140 |
return $pages;
|
@@ -151,7 +153,7 @@ class Utils {
|
|
151 |
$course_post_type = tutor()->course_post_type;
|
152 |
$course_page_url = trailingslashit( home_url() ) . $course_post_type;
|
153 |
|
154 |
-
$course_archive_page = $this->get_option('course_archive_page');
|
155 |
if ( $course_archive_page && $course_archive_page !== '-1' ) {
|
156 |
$course_page_url = get_permalink( $course_archive_page );
|
157 |
}
|
@@ -173,23 +175,24 @@ class Utils {
|
|
173 |
$user_name = '';
|
174 |
if ( $student_id ) {
|
175 |
global $wpdb;
|
176 |
-
$user = $wpdb->get_row(
|
177 |
-
|
178 |
-
|
|
|
179 |
WHERE ID = %d;
|
180 |
-
",
|
181 |
-
|
182 |
-
|
|
|
183 |
|
184 |
-
if ($user) {
|
185 |
$user_name = $user->user_nicename;
|
186 |
}
|
187 |
-
|
188 |
} else {
|
189 |
$user_name = 'user_name';
|
190 |
}
|
191 |
|
192 |
-
return $site_url
|
193 |
}
|
194 |
|
195 |
/**
|
@@ -203,14 +206,16 @@ class Utils {
|
|
203 |
*/
|
204 |
public function get_user_by_login( $user_nicename = '' ) {
|
205 |
global $wpdb;
|
206 |
-
$user_nicename
|
207 |
-
$user
|
208 |
-
|
|
|
209 |
FROM {$wpdb->users}
|
210 |
WHERE user_nicename = %s;
|
211 |
",
|
212 |
-
|
213 |
-
|
|
|
214 |
return $user;
|
215 |
}
|
216 |
|
@@ -220,7 +225,7 @@ class Utils {
|
|
220 |
* Check if WooCommerce Activated
|
221 |
*
|
222 |
* @since v.1.0.0
|
223 |
-
|
224 |
*/
|
225 |
public function has_wc() {
|
226 |
return class_exists( 'WooCommerce' );
|
@@ -247,29 +252,29 @@ class Utils {
|
|
247 |
*
|
248 |
* @since v.1.3.6
|
249 |
*/
|
250 |
-
public function has_pmpro($check_monetization=false) {
|
251 |
-
$has_pmpro = $this->is_plugin_active('paid-memberships-pro/paid-memberships-pro.php');
|
252 |
-
return $has_pmpro && (
|
253 |
}
|
254 |
|
255 |
-
public function is_plugin_active($plugin_path) {
|
256 |
$activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) );
|
257 |
-
$depends = is_array($plugin_path) ? $plugin_path : array( $plugin_path );
|
258 |
$has_plugin = count( array_intersect( $depends, $activated_plugins ) ) == count( $depends );
|
259 |
-
|
260 |
return $has_plugin;
|
261 |
}
|
262 |
|
263 |
-
public function has_wcs(){
|
264 |
-
$has_wcs = $this->is_plugin_active('woocommerce-subscriptions/woocommerce-subscriptions.php');
|
265 |
return $has_wcs;
|
266 |
}
|
267 |
|
268 |
-
public function is_addon_enabled($basename) {
|
269 |
-
if($this->is_plugin_active('tutor-pro/tutor-pro.php')) {
|
270 |
-
$addonConfig = $this->get_addon_config($basename);
|
271 |
-
|
272 |
-
return (bool) $this->avalue_dot('is_enable', $addonConfig);
|
273 |
}
|
274 |
}
|
275 |
|
@@ -280,7 +285,7 @@ class Utils {
|
|
280 |
*
|
281 |
* @since v.1.4.8
|
282 |
*/
|
283 |
-
public function has_bp(){
|
284 |
$activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) );
|
285 |
$depends = array( 'buddypress/bp-loader.php' );
|
286 |
$has_bp = count( array_intersect( $depends, $activated_plugins ) ) == count( $depends );
|
@@ -294,141 +299,141 @@ class Utils {
|
|
294 |
*/
|
295 |
public function languages() {
|
296 |
$language_codes = array(
|
297 |
-
'en' => 'English'
|
298 |
-
'aa' => 'Afar'
|
299 |
-
'ab' => 'Abkhazian'
|
300 |
-
'af' => 'Afrikaans'
|
301 |
-
'am' => 'Amharic'
|
302 |
-
'ar' => 'Arabic'
|
303 |
-
'as' => 'Assamese'
|
304 |
-
'ay' => 'Aymara'
|
305 |
-
'az' => 'Azerbaijani'
|
306 |
-
'ba' => 'Bashkir'
|
307 |
-
'be' => 'Byelorussian'
|
308 |
-
'bg' => 'Bulgarian'
|
309 |
-
'bh' => 'Bihari'
|
310 |
-
'bi' => 'Bislama'
|
311 |
-
'bn' => 'Bengali/Bangla'
|
312 |
-
'bo' => 'Tibetan'
|
313 |
-
'br' => 'Breton'
|
314 |
-
'ca' => 'Catalan'
|
315 |
-
'co' => 'Corsican'
|
316 |
-
'cs' => 'Czech'
|
317 |
-
'cy' => 'Welsh'
|
318 |
-
'da' => 'Danish'
|
319 |
-
'de' => 'German'
|
320 |
-
'dz' => 'Bhutani'
|
321 |
-
'el' => 'Greek'
|
322 |
-
'eo' => 'Esperanto'
|
323 |
-
'es' => 'Spanish'
|
324 |
-
'et' => 'Estonian'
|
325 |
-
'eu' => 'Basque'
|
326 |
-
'fa' => 'Persian'
|
327 |
-
'fi' => 'Finnish'
|
328 |
-
'fj' => 'Fiji'
|
329 |
-
'fo' => 'Faeroese'
|
330 |
-
'fr' => 'French'
|
331 |
-
'fy' => 'Frisian'
|
332 |
-
'ga' => 'Irish'
|
333 |
-
'gd' => 'Scots/Gaelic'
|
334 |
-
'gl' => 'Galician'
|
335 |
-
'gn' => 'Guarani'
|
336 |
-
'gu' => 'Gujarati'
|
337 |
-
'ha' => 'Hausa'
|
338 |
-
'hi' => 'Hindi'
|
339 |
-
'hr' => 'Croatian'
|
340 |
-
'hu' => 'Hungarian'
|
341 |
-
'hy' => 'Armenian'
|
342 |
-
'ia' => 'Interlingua'
|
343 |
-
'ie' => 'Interlingue'
|
344 |
-
'ik' => 'Inupiak'
|
345 |
-
'in' => 'Indonesian'
|
346 |
-
'is' => 'Icelandic'
|
347 |
-
'it' => 'Italian'
|
348 |
-
'iw' => 'Hebrew'
|
349 |
-
'ja' => 'Japanese'
|
350 |
-
'ji' => 'Yiddish'
|
351 |
-
'jw' => 'Javanese'
|
352 |
-
'ka' => 'Georgian'
|
353 |
-
'kk' => 'Kazakh'
|
354 |
-
'kl' => 'Greenlandic'
|
355 |
-
'km' => 'Cambodian'
|
356 |
-
'kn' => 'Kannada'
|
357 |
-
'ko' => 'Korean'
|
358 |
-
'ks' => 'Kashmiri'
|
359 |
-
'ku' => 'Kurdish'
|
360 |
-
'ky' => 'Kirghiz'
|
361 |
-
'la' => 'Latin'
|
362 |
-
'ln' => 'Lingala'
|
363 |
-
'lo' => 'Laothian'
|
364 |
-
'lt' => 'Lithuanian'
|
365 |
-
'lv' => 'Latvian/Lettish'
|
366 |
-
'mg' => 'Malagasy'
|
367 |
-
'mi' => 'Maori'
|
368 |
-
'mk' => 'Macedonian'
|
369 |
-
'ml' => 'Malayalam'
|
370 |
-
'mn' => 'Mongolian'
|
371 |
-
'mo' => 'Moldavian'
|
372 |
-
'mr' => 'Marathi'
|
373 |
-
'ms' => 'Malay'
|
374 |
-
'mt' => 'Maltese'
|
375 |
-
'my' => 'Burmese'
|
376 |
-
'na' => 'Nauru'
|
377 |
-
'ne' => 'Nepali'
|
378 |
-
'nl' => 'Dutch'
|
379 |
-
'no' => 'Norwegian'
|
380 |
-
'oc' => 'Occitan'
|
381 |
-
'om' => '(Afan)/Oromoor/Oriya'
|
382 |
-
'pa' => 'Punjabi'
|
383 |
-
'pl' => 'Polish'
|
384 |
-
'ps' => 'Pashto/Pushto'
|
385 |
-
'pt' => 'Portuguese'
|
386 |
-
'qu' => 'Quechua'
|
387 |
-
'rm' => 'Rhaeto-Romance'
|
388 |
-
'rn' => 'Kirundi'
|
389 |
-
'ro' => 'Romanian'
|
390 |
-
'ru' => 'Russian'
|
391 |
-
'rw' => 'Kinyarwanda'
|
392 |
-
'sa' => 'Sanskrit'
|
393 |
-
'sd' => 'Sindhi'
|
394 |
-
'sg' => 'Sangro'
|
395 |
-
'sh' => 'Serbo-Croatian'
|
396 |
-
'si' => 'Singhalese'
|
397 |
-
'sk' => 'Slovak'
|
398 |
-
'sl' => 'Slovenian'
|
399 |
-
'sm' => 'Samoan'
|
400 |
-
'sn' => 'Shona'
|
401 |
-
'so' => 'Somali'
|
402 |
-
'sq' => 'Albanian'
|
403 |
-
'sr' => 'Serbian'
|
404 |
-
'ss' => 'Siswati'
|
405 |
-
'st' => 'Sesotho'
|
406 |
-
'su' => 'Sundanese'
|
407 |
-
'sv' => 'Swedish'
|
408 |
-
'sw' => 'Swahili'
|
409 |
-
'ta' => 'Tamil'
|
410 |
-
'te' => 'Tegulu'
|
411 |
-
'tg' => 'Tajik'
|
412 |
-
'th' => 'Thai'
|
413 |
-
'ti' => 'Tigrinya'
|
414 |
-
'tk' => 'Turkmen'
|
415 |
-
'tl' => 'Tagalog'
|
416 |
-
'tn' => 'Setswana'
|
417 |
-
'to' => 'Tonga'
|
418 |
-
'tr' => 'Turkish'
|
419 |
-
'ts' => 'Tsonga'
|
420 |
-
'tt' => 'Tatar'
|
421 |
-
'tw' => 'Twi'
|
422 |
-
'uk' => 'Ukrainian'
|
423 |
-
'ur' => 'Urdu'
|
424 |
-
'uz' => 'Uzbek'
|
425 |
-
'vi' => 'Vietnamese'
|
426 |
-
'vo' => 'Volapuk'
|
427 |
-
'wo' => 'Wolof'
|
428 |
-
'xh' => 'Xhosa'
|
429 |
-
'yo' => 'Yoruba'
|
430 |
-
'zh' => 'Chinese'
|
431 |
-
'zu' => 'Zulu'
|
432 |
);
|
433 |
|
434 |
return apply_filters( 'tutor/utils/languages', $language_codes );
|
@@ -443,7 +448,7 @@ class Utils {
|
|
443 |
*/
|
444 |
public function print_view( $value = '' ) {
|
445 |
echo '<pre>';
|
446 |
-
|
447 |
echo '</pre>';
|
448 |
}
|
449 |
|
@@ -466,27 +471,32 @@ class Utils {
|
|
466 |
$exclude_query = implode( "','", $excludes );
|
467 |
}
|
468 |
|
469 |
-
$post_status = array_map(
|
470 |
-
|
471 |
-
|
|
|
|
|
|
|
472 |
|
473 |
$post_status = implode( ',', $post_status );
|
474 |
$course_post_type = tutor()->course_post_type;
|
475 |
|
476 |
-
$query = $wpdb->get_results(
|
477 |
-
|
|
|
478 |
post_author,
|
479 |
post_title,
|
480 |
post_name,
|
481 |
post_status,
|
482 |
-
menu_order
|
483 |
-
FROM {$wpdb->posts}
|
484 |
WHERE post_status IN ({$post_status})
|
485 |
AND ID NOT IN('$exclude_query')
|
486 |
AND post_type = %s;
|
487 |
",
|
488 |
-
|
489 |
-
|
|
|
490 |
|
491 |
return $query;
|
492 |
}
|
@@ -507,13 +517,15 @@ class Utils {
|
|
507 |
$course_post_type = tutor()->course_post_type;
|
508 |
|
509 |
global $current_user;
|
510 |
-
$courses = get_posts(
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
|
|
|
|
517 |
return $courses;
|
518 |
}
|
519 |
|
@@ -531,21 +543,23 @@ class Utils {
|
|
531 |
|
532 |
$course_post_type = tutor()->course_post_type;
|
533 |
|
534 |
-
$count = $wpdb->get_var(
|
535 |
-
|
|
|
536 |
FROM {$wpdb->posts}
|
537 |
INNER JOIN {$wpdb->usermeta}
|
538 |
ON user_id = %d
|
539 |
AND meta_key = %s
|
540 |
AND meta_value = ID
|
541 |
-
WHERE post_status = %s
|
542 |
AND post_type = %s;
|
543 |
",
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
|
|
549 |
|
550 |
return $count;
|
551 |
}
|
@@ -562,32 +576,35 @@ class Utils {
|
|
562 |
public function get_courses_by_instructor( $instructor_id = 0, $post_status = array( 'publish' ) ) {
|
563 |
global $wpdb;
|
564 |
|
565 |
-
$instructor_id = $this->get_user_id($instructor_id);
|
566 |
$course_post_type = tutor()->course_post_type;
|
567 |
|
568 |
if ( $post_status === 'any' ) {
|
569 |
-
$where_post_status =
|
570 |
} else {
|
571 |
$post_status = (array) $post_status;
|
572 |
$statuses = "'" . implode( "','", $post_status ) . "'";
|
573 |
$where_post_status = "AND $wpdb->posts.post_status IN({$statuses}) ";
|
574 |
}
|
575 |
|
576 |
-
$pageposts = $wpdb->get_results(
|
577 |
-
|
|
|
578 |
FROM $wpdb->posts
|
579 |
INNER JOIN {$wpdb->usermeta}
|
580 |
ON $wpdb->usermeta.user_id = %d
|
581 |
AND $wpdb->usermeta.meta_key = %s
|
582 |
-
AND $wpdb->usermeta.meta_value = $wpdb->posts.ID
|
583 |
WHERE 1 = 1 {$where_post_status}
|
584 |
AND $wpdb->posts.post_type = %s
|
585 |
ORDER BY $wpdb->posts.post_date DESC;
|
586 |
",
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
|
|
|
|
591 |
|
592 |
return $pageposts;
|
593 |
}
|
@@ -616,16 +633,18 @@ class Utils {
|
|
616 |
|
617 |
$course_post_type = tutor()->course_post_type;
|
618 |
|
619 |
-
$count = $wpdb->get_var(
|
620 |
-
|
|
|
621 |
FROM {$wpdb->posts}
|
622 |
WHERE post_status = %s
|
623 |
AND post_type = %s;
|
624 |
",
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
|
|
629 |
return $count;
|
630 |
}
|
631 |
|
@@ -641,16 +660,18 @@ class Utils {
|
|
641 |
|
642 |
$lesson_post_type = tutor()->lesson_post_type;
|
643 |
|
644 |
-
$count = $wpdb->get_var(
|
645 |
-
|
|
|
646 |
FROM {$wpdb->posts}
|
647 |
WHERE post_status = %s
|
648 |
AND post_type = %s;
|
649 |
",
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
|
|
654 |
return $count;
|
655 |
}
|
656 |
|
@@ -715,23 +736,25 @@ class Utils {
|
|
715 |
$user_id = $this->get_user_id( $user_id );
|
716 |
|
717 |
$lesson_ids = $this->get_course_content_ids_by( tutor()->lesson_post_type, tutor()->course_post_type, $course_id );
|
718 |
-
|
719 |
$count = 0;
|
720 |
-
if ( count( $lesson_ids) ) {
|
721 |
$completed_lesson_meta_ids = array();
|
722 |
foreach ( $lesson_ids as $lesson_id ) {
|
723 |
$completed_lesson_meta_ids[] = '_tutor_completed_lesson_id_' . $lesson_id;
|
724 |
}
|
725 |
$in_ids = implode( "','", $completed_lesson_meta_ids );
|
726 |
|
727 |
-
$count = (int) $wpdb->get_var(
|
728 |
-
|
|
|
729 |
FROM {$wpdb->usermeta}
|
730 |
WHERE user_id = %d
|
731 |
AND meta_key IN ('{$in_ids}')
|
732 |
",
|
733 |
-
|
734 |
-
|
|
|
735 |
}
|
736 |
|
737 |
return $count;
|
@@ -744,32 +767,32 @@ class Utils {
|
|
744 |
* @return float|int
|
745 |
*
|
746 |
* @since v.1.0.0
|
747 |
-
|
748 |
*/
|
749 |
public function get_course_completed_percent( $course_id = 0, $user_id = 0 ) {
|
750 |
-
$course_id
|
751 |
-
$user_id = $this->get_user_id($user_id);
|
752 |
-
$completed_lesson = $this->get_completed_lesson_count_by_course($course_id, $user_id);
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
|
774 |
if ( $totalContents > 0 && $completedCount > 0 ) {
|
775 |
return number_format( ( $completedCount * 100 ) / $totalContents );
|
@@ -815,16 +838,18 @@ class Utils {
|
|
815 |
public function get_next_topic_order_id( $course_ID ) {
|
816 |
global $wpdb;
|
817 |
|
818 |
-
$last_order = (int) $wpdb->get_var(
|
819 |
-
|
|
|
820 |
FROM {$wpdb->posts}
|
821 |
WHERE post_parent = %d
|
822 |
AND post_type = %s;
|
823 |
",
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
|
|
828 |
return $last_order + 1;
|
829 |
}
|
830 |
|
@@ -840,15 +865,17 @@ class Utils {
|
|
840 |
public function get_next_course_content_order_id( $topic_ID ) {
|
841 |
global $wpdb;
|
842 |
|
843 |
-
$last_order = (int) $wpdb->get_var(
|
844 |
-
|
|
|
845 |
FROM {$wpdb->posts}
|
846 |
WHERE post_parent = %d;
|
847 |
",
|
848 |
-
|
849 |
-
|
|
|
850 |
|
851 |
-
return is_numeric( $last_order ) ? $last_order+1 : 0;
|
852 |
}
|
853 |
|
854 |
/**
|
@@ -864,7 +891,7 @@ class Utils {
|
|
864 |
public function get_lessons_by_topic( $topics_id = 0, $limit = 10 ) {
|
865 |
$topics_id = $this->get_post_id( $topics_id );
|
866 |
$lesson_post_type = tutor()->lesson_post_type;
|
867 |
-
|
868 |
$args = array(
|
869 |
'post_type' => $lesson_post_type,
|
870 |
'post_parent' => $topics_id,
|
@@ -889,7 +916,7 @@ class Utils {
|
|
889 |
* @since v.1.0.0
|
890 |
*/
|
891 |
public function get_course_contents_by_topic( $topics_id = 0, $limit = 10 ) {
|
892 |
-
$topics_id = $this->get_post_id($topics_id);
|
893 |
$lesson_post_type = tutor()->lesson_post_type;
|
894 |
$post_type = apply_filters( 'tutor_course_contents_post_types', array( $lesson_post_type, 'tutor_quiz' ) );
|
895 |
|
@@ -915,11 +942,11 @@ class Utils {
|
|
915 |
*/
|
916 |
public function checking_nonce( $request_method = 'post' ) {
|
917 |
|
918 |
-
$data
|
919 |
-
$nonce_value = sanitize_text_field(tutils()->array_get(tutor()->nonce, $data, null));
|
920 |
-
$matched
|
921 |
|
922 |
-
! $matched ? exit( __('Nonce not matched', 'tutor') ) : 0;
|
923 |
}
|
924 |
|
925 |
/**
|
@@ -957,7 +984,7 @@ class Utils {
|
|
957 |
$course_id = $this->get_post_id( $course_id );
|
958 |
|
959 |
if ( $this->is_course_purchasable() ) {
|
960 |
-
$monetize_by = $this->get_option('monetize_by');
|
961 |
|
962 |
if ( $this->has_wc() && $monetize_by === 'wc' ) {
|
963 |
$product_id = tutor_utils()->get_course_product_id( $course_id );
|
@@ -993,7 +1020,7 @@ class Utils {
|
|
993 |
'sale_price' => 0,
|
994 |
);
|
995 |
|
996 |
-
$monetize_by = $this->get_option('monetize_by');
|
997 |
|
998 |
$product_id = $this->get_course_product_id( $course_id );
|
999 |
if ( $product_id ) {
|
@@ -1042,8 +1069,9 @@ class Utils {
|
|
1042 |
|
1043 |
do_action( 'tutor_is_enrolled_before', $course_id, $user_id );
|
1044 |
|
1045 |
-
$getEnrolledInfo = $wpdb->get_row(
|
1046 |
-
|
|
|
1047 |
post_author,
|
1048 |
post_date,
|
1049 |
post_date_gmt,
|
@@ -1054,11 +1082,12 @@ class Utils {
|
|
1054 |
AND post_author = %d
|
1055 |
AND post_status = %s;
|
1056 |
",
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
|
|
1062 |
|
1063 |
if ( $getEnrolledInfo ) {
|
1064 |
return apply_filters( 'tutor_is_enrolled', $getEnrolledInfo, $course_id, $user_id );
|
@@ -1083,29 +1112,32 @@ class Utils {
|
|
1083 |
$user_id = $this->get_user_id( $user_id );
|
1084 |
|
1085 |
// Delete Quiz submissions
|
1086 |
-
$attempts = $this->get_quiz_attempts_by_course_ids(
|
1087 |
-
|
1088 |
-
if( is_array($attempts) ) {
|
1089 |
-
$attempt_ids = array_map(
|
1090 |
-
|
1091 |
-
|
|
|
|
|
|
|
1092 |
|
1093 |
-
$this->delete_quiz_attempt($attempt_ids);
|
1094 |
}
|
1095 |
|
1096 |
// Delete Course completion row
|
1097 |
$del_where = array(
|
1098 |
-
'user_id'
|
1099 |
'comment_post_ID' => $course_id,
|
1100 |
-
'comment_type'
|
1101 |
-
'comment_agent'
|
1102 |
);
|
1103 |
-
$wpdb->delete($wpdb->comments, $del_where);
|
1104 |
|
1105 |
// Delete Completed lesson count
|
1106 |
-
$lesson_ids = $this->get_course_content_ids_by(tutor()->lesson_post_type, tutor()->course_post_type, $course_id);
|
1107 |
-
foreach($lesson_ids as $id) {
|
1108 |
-
delete_user_meta( $user_id, '_tutor_completed_lesson_id_'
|
1109 |
}
|
1110 |
|
1111 |
// Delete other addon-wise stuffs by hook, specially assignment.
|
@@ -1129,21 +1161,23 @@ class Utils {
|
|
1129 |
if ( is_user_logged_in() ) {
|
1130 |
global $wpdb;
|
1131 |
|
1132 |
-
$getEnrolledInfo = $wpdb->get_row(
|
1133 |
-
|
|
|
1134 |
post_author,
|
1135 |
post_date,
|
1136 |
post_date_gmt,
|
1137 |
post_title
|
1138 |
FROM {$wpdb->posts}
|
1139 |
-
WHERE post_type = %s
|
1140 |
AND post_parent = %d
|
1141 |
AND post_author = %d;
|
1142 |
",
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
|
|
1147 |
|
1148 |
if ( $getEnrolledInfo ) {
|
1149 |
return $getEnrolledInfo;
|
@@ -1154,37 +1188,39 @@ class Utils {
|
|
1154 |
}
|
1155 |
|
1156 |
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
public function get_course_by_enrol_id( $enrol_id = 0 ) {
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
|
1170 |
-
|
1171 |
|
1172 |
-
|
1173 |
-
|
|
|
1174 |
FROM {$wpdb->posts}
|
1175 |
WHERE post_type = %s
|
1176 |
AND ID = %d
|
1177 |
",
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
|
|
1181 |
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
|
1186 |
-
|
1187 |
-
|
1188 |
|
1189 |
/**
|
1190 |
* @param int $lesson_id
|
@@ -1218,7 +1254,7 @@ class Utils {
|
|
1218 |
*/
|
1219 |
public function get_course_id_by_lesson( $lesson_id = 0 ) {
|
1220 |
$lesson_id = $this->get_post_id( $lesson_id );
|
1221 |
-
$course_id = tutor_utils()->get_course_id_by('lesson', $lesson_id);
|
1222 |
|
1223 |
if ( ! $course_id ) {
|
1224 |
$course_id = $this->get_course_id_by_content( $lesson_id );
|
@@ -1239,33 +1275,35 @@ class Utils {
|
|
1239 |
*
|
1240 |
* @since v.1.0.0
|
1241 |
*/
|
1242 |
-
public function get_course_first_lesson( $course_id = 0, $post_type=null ) {
|
1243 |
global $wpdb;
|
1244 |
|
1245 |
$course_id = $this->get_post_id( $course_id );
|
1246 |
$user_id = get_current_user_id();
|
1247 |
|
1248 |
-
$lessons = $wpdb->get_results(
|
1249 |
-
|
|
|
1250 |
FROM {$wpdb->posts} topic
|
1251 |
INNER JOIN {$wpdb->posts} items
|
1252 |
ON topic.ID = items.post_parent
|
1253 |
WHERE topic.post_parent = %d
|
1254 |
AND items.post_status = %s
|
1255 |
-
".( $post_type ? " AND items.post_type='{$post_type}' " :
|
1256 |
ORDER BY topic.menu_order ASC,
|
1257 |
items.menu_order ASC;
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
|
|
1262 |
|
1263 |
$first_lesson = false;
|
1264 |
|
1265 |
if ( tutils()->count( $lessons ) ) {
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
|
1270 |
foreach ( $lessons as $lesson ) {
|
1271 |
$is_complete = get_user_meta( $user_id, "_tutor_completed_lesson_id_{$lesson->ID}", true );
|
@@ -1275,7 +1313,7 @@ class Utils {
|
|
1275 |
}
|
1276 |
}
|
1277 |
|
1278 |
-
if ( ! empty($first_lesson->ID) ) {
|
1279 |
return get_permalink( $first_lesson->ID );
|
1280 |
}
|
1281 |
}
|
@@ -1291,8 +1329,8 @@ class Utils {
|
|
1291 |
*/
|
1292 |
public function course_sub_pages() {
|
1293 |
$nav_items = array(
|
1294 |
-
'questions' => __('Q&A', 'tutor'),
|
1295 |
-
'announcements' => __('Announcements', 'tutor'),
|
1296 |
);
|
1297 |
|
1298 |
return apply_filters( 'tutor_course/single/enrolled/nav_items', $nav_items );
|
@@ -1315,7 +1353,7 @@ class Utils {
|
|
1315 |
}
|
1316 |
|
1317 |
/**
|
1318 |
-
* @param int
|
1319 |
* @param array $video_data
|
1320 |
*
|
1321 |
* @return bool
|
@@ -1342,28 +1380,31 @@ class Utils {
|
|
1342 |
$attachments = maybe_unserialize( get_post_meta( $post_id, '_tutor_attachments', true ) );
|
1343 |
$attachments_arr = array();
|
1344 |
|
1345 |
-
$font_icons = apply_filters(
|
1346 |
-
'
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
|
|
|
|
|
|
1357 |
|
1358 |
if ( is_array( $attachments ) && count( $attachments ) ) {
|
1359 |
foreach ( $attachments as $attachment ) {
|
1360 |
$url = wp_get_attachment_url( $attachment );
|
1361 |
$file_type = wp_check_filetype( $url );
|
1362 |
$ext = $file_type['ext'];
|
1363 |
-
$title = get_the_title($attachment);
|
1364 |
|
1365 |
$file_path = get_attached_file( $attachment );
|
1366 |
-
$size_bytes = file_exists($file_path) ? filesize( $file_path ) : 0;
|
1367 |
$size = size_format( $size_bytes, 2 );
|
1368 |
$type = wp_ext2type( $ext );
|
1369 |
|
@@ -1402,12 +1443,12 @@ class Utils {
|
|
1402 |
* @since v.1.0.0
|
1403 |
*/
|
1404 |
public function playtime_string( $seconds ) {
|
1405 |
-
$sign
|
1406 |
$seconds = round( abs( $seconds ) );
|
1407 |
-
$H
|
1408 |
-
$M
|
1409 |
-
$S
|
1410 |
-
return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
|
1411 |
}
|
1412 |
|
1413 |
/**
|
@@ -1426,21 +1467,21 @@ class Utils {
|
|
1426 |
'seconds' => '00',
|
1427 |
);
|
1428 |
|
1429 |
-
if ($seconds <= 0 ) {
|
1430 |
return $run_time_format;
|
1431 |
}
|
1432 |
|
1433 |
$playTimeString = $this->playtime_string( $seconds );
|
1434 |
$timeInArray = explode( ':', $playTimeString );
|
1435 |
|
1436 |
-
$run_time_size = count($timeInArray);
|
1437 |
if ( $run_time_size === 3 ) {
|
1438 |
-
$run_time_format[
|
1439 |
-
$run_time_format[
|
1440 |
-
$run_time_format[
|
1441 |
} elseif ( $run_time_size === 2 ) {
|
1442 |
-
$run_time_format[
|
1443 |
-
$run_time_format[
|
1444 |
}
|
1445 |
|
1446 |
return $run_time_format;
|
@@ -1456,13 +1497,13 @@ class Utils {
|
|
1456 |
* @since v.1.0.0
|
1457 |
*/
|
1458 |
public function seconds_to_time_context( $seconds ) {
|
1459 |
-
$sign
|
1460 |
$seconds = round( abs( $seconds ) );
|
1461 |
-
$H
|
1462 |
-
$M
|
1463 |
-
$S
|
1464 |
|
1465 |
-
return $sign.($H ? $H.'h ' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).'m '.str_pad($S, 2, 0, STR_PAD_LEFT).'s';
|
1466 |
}
|
1467 |
|
1468 |
/**
|
@@ -1484,15 +1525,22 @@ class Utils {
|
|
1484 |
'playtime' => '00:00',
|
1485 |
);
|
1486 |
|
1487 |
-
$types = apply_filters(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1488 |
|
1489 |
-
$videoSource = $this->avalue_dot('source', $video);
|
1490 |
|
1491 |
if ( $videoSource === 'html5' ) {
|
1492 |
$sourceVideoID = $this->avalue_dot( 'source_video_id', $video );
|
1493 |
$video_info = get_post_meta( $sourceVideoID, '_wp_attachment_metadata', true );
|
1494 |
|
1495 |
-
if ( $video_info && in_array( $this->array_get('mime_type', $video_info), $types ) ) {
|
1496 |
$path = get_attached_file( $sourceVideoID );
|
1497 |
$info['playtime'] = $video_info['length_formatted'];
|
1498 |
$info['path'] = $path;
|
@@ -1521,7 +1569,8 @@ class Utils {
|
|
1521 |
}
|
1522 |
|
1523 |
public function get_optimized_duration( $duration ) {
|
1524 |
-
/*
|
|
|
1525 |
strpos($duration, '00:')===0 ? $duration=substr($duration, 3) : 0; // Remove Empty hour
|
1526 |
strpos($duration, '00:')===0 ? $duration=substr($duration, 3) : 0; // Remove empty minute
|
1527 |
} */
|
@@ -1555,7 +1604,7 @@ class Utils {
|
|
1555 |
*
|
1556 |
* return lesson type icon
|
1557 |
*
|
1558 |
-
* @param int
|
1559 |
* @param bool $html
|
1560 |
* @param bool $echo
|
1561 |
*
|
@@ -1579,7 +1628,7 @@ class Utils {
|
|
1579 |
}
|
1580 |
|
1581 |
if ( $echo ) {
|
1582 |
-
echo $tutor_lesson_type_icon;
|
1583 |
}
|
1584 |
|
1585 |
return $tutor_lesson_type_icon;
|
@@ -1596,7 +1645,7 @@ class Utils {
|
|
1596 |
public function is_completed_lesson( $lesson_id = 0, $user_id = 0 ) {
|
1597 |
$lesson_id = $this->get_post_id( $lesson_id );
|
1598 |
$user_id = $this->get_user_id( $user_id );
|
1599 |
-
$is_completed = get_user_meta( $user_id, '_tutor_completed_lesson_id_'
|
1600 |
|
1601 |
if ( $is_completed ) {
|
1602 |
return $is_completed;
|
@@ -1618,28 +1667,30 @@ class Utils {
|
|
1618 |
* @updated v.1.4.9
|
1619 |
*/
|
1620 |
public function is_completed_course( $course_id = 0, $user_id = 0 ) {
|
1621 |
-
|
1622 |
global $wpdb;
|
1623 |
-
$course_id = $this->get_post_id($course_id);
|
1624 |
-
$user_id = $this->get_user_id($user_id);
|
1625 |
-
|
1626 |
-
$is_completed = $wpdb->get_row(
|
1627 |
-
|
1628 |
-
|
1629 |
-
|
1630 |
-
|
1631 |
-
|
1632 |
-
|
1633 |
-
|
1634 |
-
|
1635 |
-
AND
|
|
|
1636 |
AND user_id = %d;
|
1637 |
",
|
1638 |
-
|
1639 |
-
|
1640 |
-
|
1641 |
-
|
1642 |
-
|
|
|
1643 |
|
1644 |
if ( $is_completed ) {
|
1645 |
return apply_filters( 'is_completed_course', $is_completed, $course_id, $user_id );
|
@@ -1662,12 +1713,12 @@ class Utils {
|
|
1662 |
|
1663 |
if ( is_array( $input ) && count( $input ) ) {
|
1664 |
foreach ( $input as $key => $value ) {
|
1665 |
-
if ( is_array( $value )) {
|
1666 |
-
$array[$key] = $this->sanitize_array( $value );
|
1667 |
} else {
|
1668 |
-
$key
|
1669 |
-
$value
|
1670 |
-
$array[$key] = $value;
|
1671 |
}
|
1672 |
}
|
1673 |
}
|
@@ -1687,16 +1738,16 @@ class Utils {
|
|
1687 |
public function has_video_in_single( $post_id = 0 ) {
|
1688 |
if ( is_single() ) {
|
1689 |
$post_id = $this->get_post_id( $post_id );
|
1690 |
-
|
1691 |
$video = $this->get_video( $post_id );
|
1692 |
if ( $video && $this->array_get( 'source', $video ) !== '-1' ) {
|
1693 |
-
|
1694 |
-
$not_empty
|
1695 |
-
!empty( $video[
|
1696 |
-
!empty( $video[
|
1697 |
-
!empty( $video[
|
1698 |
-
!empty( $video[
|
1699 |
-
|
1700 |
return $not_empty ? $video : false;
|
1701 |
}
|
1702 |
}
|
@@ -1704,10 +1755,10 @@ class Utils {
|
|
1704 |
}
|
1705 |
|
1706 |
/**
|
1707 |
-
* @param int
|
1708 |
-
* @param int
|
1709 |
* @param string $search_term
|
1710 |
-
* @param int
|
1711 |
*
|
1712 |
* @return array|null|object
|
1713 |
*
|
@@ -1723,8 +1774,9 @@ class Utils {
|
|
1723 |
|
1724 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
1725 |
|
1726 |
-
$students = $wpdb->get_results(
|
1727 |
-
|
|
|
1728 |
FROM {$wpdb->users}
|
1729 |
INNER JOIN {$wpdb->usermeta}
|
1730 |
ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
|
@@ -1733,10 +1785,11 @@ class Utils {
|
|
1733 |
ORDER BY {$wpdb->usermeta}.meta_value DESC
|
1734 |
LIMIT {$start}, {$limit};
|
1735 |
",
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
|
|
1740 |
|
1741 |
return $students;
|
1742 |
}
|
@@ -1756,18 +1809,20 @@ class Utils {
|
|
1756 |
|
1757 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
1758 |
|
1759 |
-
$count = $wpdb->get_var(
|
1760 |
-
|
|
|
1761 |
FROM {$wpdb->users}
|
1762 |
INNER JOIN {$wpdb->usermeta}
|
1763 |
ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
|
1764 |
WHERE {$wpdb->usermeta}.meta_key = %s
|
1765 |
AND ( {$wpdb->users}.display_name LIKE %s OR {$wpdb->users}.user_email LIKE %s );
|
1766 |
",
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
1770 |
-
|
|
|
1771 |
|
1772 |
return (int) $count;
|
1773 |
}
|
@@ -1786,17 +1841,19 @@ class Utils {
|
|
1786 |
|
1787 |
$user_id = $this->get_user_id( $user_id );
|
1788 |
|
1789 |
-
$course_ids = (array) $wpdb->get_col(
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
|
|
1793 |
AND comment_type = %s
|
1794 |
AND user_id = %d
|
1795 |
",
|
1796 |
-
|
1797 |
-
|
1798 |
-
|
1799 |
-
|
|
|
1800 |
|
1801 |
return $course_ids;
|
1802 |
}
|
@@ -1814,13 +1871,13 @@ class Utils {
|
|
1814 |
$user_id = $this->get_user_id( $user_id );
|
1815 |
$course_ids = $this->get_completed_courses_ids_by_user( $user_id );
|
1816 |
|
1817 |
-
if ( count($course_ids) ) {
|
1818 |
$course_post_type = tutor()->course_post_type;
|
1819 |
-
$course_args
|
1820 |
'post_type' => $course_post_type,
|
1821 |
'post_status' => 'publish',
|
1822 |
'post__in' => $course_ids,
|
1823 |
-
|
1824 |
);
|
1825 |
|
1826 |
return new \WP_Query( $course_args );
|
@@ -1846,11 +1903,11 @@ class Utils {
|
|
1846 |
|
1847 |
if ( count( $active_courses ) ) {
|
1848 |
$course_post_type = tutor()->course_post_type;
|
1849 |
-
$course_args
|
1850 |
'post_type' => $course_post_type,
|
1851 |
'post_status' => 'publish',
|
1852 |
'post__in' => $active_courses,
|
1853 |
-
|
1854 |
);
|
1855 |
|
1856 |
return new \WP_Query( $course_args );
|
@@ -1870,61 +1927,65 @@ class Utils {
|
|
1870 |
*/
|
1871 |
public function get_enrolled_courses_ids_by_user( $user_id = 0 ) {
|
1872 |
global $wpdb;
|
1873 |
-
$user_id
|
1874 |
-
$course_ids = $wpdb->get_col(
|
1875 |
-
|
|
|
1876 |
FROM {$wpdb->posts}
|
1877 |
WHERE post_type = %s
|
1878 |
AND post_status = %s
|
1879 |
AND post_author = %d;
|
1880 |
",
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
|
|
1885 |
|
1886 |
return $course_ids;
|
1887 |
}
|
1888 |
|
1889 |
/**
|
1890 |
* Get total enrolled students by course id
|
1891 |
-
*
|
1892 |
-
* @param int
|
1893 |
*
|
1894 |
* @param $period string | optional added since 1.9.9
|
1895 |
-
*
|
1896 |
* @return int
|
1897 |
-
*
|
1898 |
* @since 1.9.9
|
1899 |
*/
|
1900 |
-
public function count_enrolled_users_by_course( $course_id = 0
|
1901 |
global $wpdb;
|
1902 |
|
1903 |
$course_id = $this->get_post_id( $course_id );
|
1904 |
-
//set period wise query
|
1905 |
$period_filter = '';
|
1906 |
if ( 'today' === $period ) {
|
1907 |
-
$period_filter =
|
1908 |
-
}
|
1909 |
if ( 'monthly' === $period ) {
|
1910 |
-
$period_filter =
|
1911 |
}
|
1912 |
if ( 'yearly' === $period ) {
|
1913 |
-
$period_filter =
|
1914 |
}
|
1915 |
|
1916 |
-
$course_ids = $wpdb->get_var(
|
1917 |
-
|
1918 |
-
|
|
|
1919 |
WHERE post_type = %s
|
1920 |
AND post_status = %s
|
1921 |
AND post_parent = %d;
|
1922 |
{$period_filter}
|
1923 |
",
|
1924 |
-
|
1925 |
-
|
1926 |
-
|
1927 |
-
|
|
|
1928 |
|
1929 |
return (int) $course_ids;
|
1930 |
}
|
@@ -1936,19 +1997,19 @@ class Utils {
|
|
1936 |
*
|
1937 |
* Get the enrolled courses by user
|
1938 |
*/
|
1939 |
-
public function get_enrolled_courses_by_user( $user_id = 0, $post_status='publish' ) {
|
1940 |
global $wpdb;
|
1941 |
|
1942 |
-
$user_id
|
1943 |
$course_ids = $this->get_enrolled_courses_ids_by_user( $user_id );
|
1944 |
|
1945 |
if ( count( $course_ids ) ) {
|
1946 |
$course_post_type = tutor()->course_post_type;
|
1947 |
-
$course_args
|
1948 |
'post_type' => $course_post_type,
|
1949 |
'post_status' => $post_status,
|
1950 |
'post__in' => $course_ids,
|
1951 |
-
|
1952 |
);
|
1953 |
return new \WP_Query( $course_args );
|
1954 |
}
|
@@ -1971,7 +2032,7 @@ class Utils {
|
|
1971 |
$video_url = trailingslashit( home_url() ) . 'video-url/' . $post->post_name;
|
1972 |
} else {
|
1973 |
$video_info = tutor_utils()->get_video_info( $post_id );
|
1974 |
-
$video_url
|
1975 |
}
|
1976 |
|
1977 |
return $video_url;
|
@@ -1989,7 +2050,7 @@ class Utils {
|
|
1989 |
*/
|
1990 |
public function get_lesson_reading_info_full( $lesson_id = 0, $user_id = 0 ) {
|
1991 |
$lesson_id = $this->get_post_id( $lesson_id );
|
1992 |
-
$user_id
|
1993 |
|
1994 |
$lesson_info = (array) maybe_unserialize( get_user_meta( $user_id, '_lesson_reading_info', true ) );
|
1995 |
return $this->avalue_dot( $lesson_id, $lesson_info );
|
@@ -2004,7 +2065,7 @@ class Utils {
|
|
2004 |
*
|
2005 |
* @since v.1.0.0
|
2006 |
*/
|
2007 |
-
public function get_post_id( $post_id = 0) {
|
2008 |
if ( ! $post_id ) {
|
2009 |
$post_id = get_the_ID();
|
2010 |
if ( ! $post_id ) {
|
@@ -2025,7 +2086,7 @@ class Utils {
|
|
2025 |
* @since v.1.0.0
|
2026 |
*/
|
2027 |
public function get_user_id( $user_id = 0 ) {
|
2028 |
-
if ( ! $user_id) {
|
2029 |
$user_id = get_current_user_id();
|
2030 |
if ( ! $user_id ) {
|
2031 |
return false;
|
@@ -2036,8 +2097,8 @@ class Utils {
|
|
2036 |
}
|
2037 |
|
2038 |
/**
|
2039 |
-
* @param int
|
2040 |
-
* @param int
|
2041 |
* @param string $key
|
2042 |
*
|
2043 |
* @return array|bool|mixed
|
@@ -2051,12 +2112,12 @@ class Utils {
|
|
2051 |
$user_id = $this->get_user_id( $user_id );
|
2052 |
$lesson_info = $this->get_lesson_reading_info_full( $lesson_id, $user_id );
|
2053 |
|
2054 |
-
return $this->avalue_dot($key, $lesson_info);
|
2055 |
}
|
2056 |
|
2057 |
/**
|
2058 |
-
* @param int
|
2059 |
-
* @param int
|
2060 |
* @param array $data
|
2061 |
*
|
2062 |
* @return bool
|
@@ -2066,11 +2127,11 @@ class Utils {
|
|
2066 |
* @since v.1.0.0
|
2067 |
*/
|
2068 |
public function update_lesson_reading_info( $lesson_id = 0, $user_id = 0, $key = '', $value = '' ) {
|
2069 |
-
$lesson_id = $this->get_post_id($lesson_id);
|
2070 |
-
$user_id = $this->get_user_id($user_id);
|
2071 |
|
2072 |
if ( $key && $value ) {
|
2073 |
-
$lesson_info
|
2074 |
$lesson_info[ $lesson_id ][ $key ] = $value;
|
2075 |
update_user_meta( $user_id, '_lesson_reading_info', $lesson_info );
|
2076 |
}
|
@@ -2085,7 +2146,7 @@ class Utils {
|
|
2085 |
*
|
2086 |
* @since v.1.0.0
|
2087 |
*/
|
2088 |
-
public function get_youtube_video_id( $url = '') {
|
2089 |
if ( ! $url ) {
|
2090 |
return false;
|
2091 |
}
|
@@ -2110,7 +2171,7 @@ class Utils {
|
|
2110 |
* @since v.1.0.0
|
2111 |
*/
|
2112 |
public function get_vimeo_video_id( $url = '' ) {
|
2113 |
-
if ( preg_match('%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im', $url, $match ) ) {
|
2114 |
if ( isset( $match[3] ) ) {
|
2115 |
return $match[3];
|
2116 |
}
|
@@ -2130,7 +2191,7 @@ class Utils {
|
|
2130 |
$user_id = $this->get_user_id( $user_id );
|
2131 |
|
2132 |
do_action( 'tutor_mark_lesson_complete_before', $post_id, $user_id );
|
2133 |
-
update_user_meta( $user_id, '_tutor_completed_lesson_id_'
|
2134 |
do_action( 'tutor_mark_lesson_complete_after', $post_id, $user_id );
|
2135 |
}
|
2136 |
|
@@ -2159,11 +2220,11 @@ class Utils {
|
|
2159 |
|
2160 |
do_action( 'tutor_before_enroll', $course_id );
|
2161 |
$user_id = $this->get_user_id( $user_id );
|
2162 |
-
$title
|
2163 |
|
2164 |
if ( $course_id && $user_id ) {
|
2165 |
if ( $this->is_enrolled( $course_id, $user_id ) ) {
|
2166 |
-
return
|
2167 |
}
|
2168 |
}
|
2169 |
|
@@ -2176,13 +2237,14 @@ class Utils {
|
|
2176 |
$enrolment_status = 'pending';
|
2177 |
}
|
2178 |
|
2179 |
-
$enroll_data = apply_filters(
|
|
|
2180 |
array(
|
2181 |
-
'post_type'
|
2182 |
-
'post_title'
|
2183 |
-
'post_status'
|
2184 |
-
'post_author'
|
2185 |
-
'post_parent'
|
2186 |
)
|
2187 |
);
|
2188 |
|
@@ -2194,20 +2256,20 @@ class Utils {
|
|
2194 |
do_action( 'tutor_after_enroll', $course_id, $isEnrolled );
|
2195 |
|
2196 |
// Run this hook for completed enrollment regardless of payment provider and free/paid mode
|
2197 |
-
if( $enroll_data['post_status'] == 'completed' ) {
|
2198 |
-
do_action('tutor_after_enrolled', $course_id, $user_id, $isEnrolled);
|
2199 |
}
|
2200 |
|
2201 |
-
//Mark Current User as Students with user meta data
|
2202 |
update_user_meta( $user_id, '_is_tutor_student', tutor_time() );
|
2203 |
|
2204 |
if ( $order_id ) {
|
2205 |
-
//Mark order for course and user
|
2206 |
$product_id = $this->get_course_product_id( $course_id );
|
2207 |
update_post_meta( $isEnrolled, '_tutor_enrolled_by_order_id', $order_id );
|
2208 |
update_post_meta( $isEnrolled, '_tutor_enrolled_by_product_id', $product_id );
|
2209 |
update_post_meta( $order_id, '_is_tutor_order_for_course', tutor_time() );
|
2210 |
-
update_post_meta( $order_id, '_tutor_order_for_course_id_'
|
2211 |
}
|
2212 |
return true;
|
2213 |
}
|
@@ -2215,61 +2277,76 @@ class Utils {
|
|
2215 |
return false;
|
2216 |
}
|
2217 |
|
2218 |
-
|
2219 |
-
|
2220 |
-
|
2221 |
-
|
2222 |
-
|
2223 |
-
|
2224 |
-
|
2225 |
-
|
2226 |
public function course_enrol_status_change( $enrol_id = false, $new_status = '' ) {
|
2227 |
-
|
2228 |
-
|
2229 |
-
|
2230 |
-
|
2231 |
-
|
2232 |
-
|
2233 |
-
|
2234 |
-
|
2235 |
-
|
2236 |
-
|
2237 |
-
|
2238 |
-
|
2239 |
-
|
2240 |
-
|
2241 |
-
|
2242 |
-
|
2243 |
public function cancel_course_enrol( $course_id = 0, $user_id = 0, $cancel_status = 'canceled' ) {
|
2244 |
-
|
2245 |
-
|
2246 |
-
|
2247 |
-
|
2248 |
-
|
2249 |
-
|
2250 |
-
|
2251 |
-
|
2252 |
-
|
2253 |
-
|
2254 |
-
|
2255 |
-
|
2256 |
-
|
2257 |
-
|
2258 |
-
|
2259 |
-
|
2260 |
-
|
2261 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2262 |
do_action( 'tutor_enrollment/after/delete', $enrolled->ID );
|
2263 |
-
|
2264 |
-
|
2265 |
-
|
2266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2267 |
if ( $cancel_status === 'cancel' ) {
|
2268 |
do_action( 'tutor_enrollment/after/cancel', $enrolled->ID );
|
2269 |
}
|
2270 |
}
|
2271 |
-
|
2272 |
-
|
2273 |
|
2274 |
/**
|
2275 |
* @param $order_id
|
@@ -2307,24 +2384,26 @@ class Utils {
|
|
2307 |
public function get_course_enrolled_ids_by_order_id( $order_id ) {
|
2308 |
global $wpdb;
|
2309 |
|
2310 |
-
//Getting all of courses ids within this order
|
2311 |
-
$courses_ids = $wpdb->get_results(
|
2312 |
-
|
|
|
2313 |
FROM {$wpdb->postmeta}
|
2314 |
-
WHERE post_id = %d
|
2315 |
AND meta_key LIKE '_tutor_order_for_course_id_%'
|
2316 |
-
",
|
2317 |
-
|
2318 |
-
|
|
|
2319 |
|
2320 |
if ( is_array( $courses_ids ) && count( $courses_ids ) ) {
|
2321 |
$course_enrolled_by_order = array();
|
2322 |
foreach ( $courses_ids as $courses_id ) {
|
2323 |
-
$course_id
|
2324 |
$course_enrolled_by_order[] = array(
|
2325 |
'course_id' => $course_id,
|
2326 |
'enrolled_id' => $courses_id->meta_value,
|
2327 |
-
'order_id' => $courses_id->post_id
|
2328 |
);
|
2329 |
}
|
2330 |
return $course_enrolled_by_order;
|
@@ -2345,16 +2424,18 @@ class Utils {
|
|
2345 |
*/
|
2346 |
public function get_wc_products_db() {
|
2347 |
global $wpdb;
|
2348 |
-
$query = $wpdb->get_results(
|
2349 |
-
|
|
|
2350 |
post_title
|
2351 |
FROM {$wpdb->posts}
|
2352 |
WHERE post_status = %s
|
2353 |
AND post_type = %s;
|
2354 |
",
|
2355 |
-
|
2356 |
-
|
2357 |
-
|
|
|
2358 |
|
2359 |
return $query;
|
2360 |
}
|
@@ -2366,16 +2447,18 @@ class Utils {
|
|
2366 |
*/
|
2367 |
public function get_edd_products() {
|
2368 |
global $wpdb;
|
2369 |
-
$query = $wpdb->get_results(
|
2370 |
-
|
|
|
2371 |
post_title
|
2372 |
FROM {$wpdb->posts}
|
2373 |
WHERE post_status = %s
|
2374 |
AND post_type = %s;
|
2375 |
",
|
2376 |
-
|
2377 |
-
|
2378 |
-
|
|
|
2379 |
|
2380 |
return $query;
|
2381 |
}
|
@@ -2408,17 +2491,19 @@ class Utils {
|
|
2408 |
public function product_belongs_with_course( $product_id = 0 ) {
|
2409 |
global $wpdb;
|
2410 |
|
2411 |
-
$query = $wpdb->get_row(
|
2412 |
-
|
|
|
2413 |
FROM {$wpdb->postmeta}
|
2414 |
-
WHERE meta_key = %s
|
2415 |
-
AND meta_value = %d
|
2416 |
limit 1
|
2417 |
",
|
2418 |
-
|
2419 |
-
|
2420 |
-
|
2421 |
-
|
|
|
2422 |
return $query;
|
2423 |
}
|
2424 |
|
@@ -2430,7 +2515,7 @@ class Utils {
|
|
2430 |
public function get_enrolled_statuses() {
|
2431 |
return apply_filters(
|
2432 |
'tutor_get_enrolled_statuses',
|
2433 |
-
array
|
2434 |
'pending',
|
2435 |
'processing',
|
2436 |
'on-hold',
|
@@ -2463,25 +2548,54 @@ class Utils {
|
|
2463 |
* @since v.1.0.0
|
2464 |
*/
|
2465 |
public function tutor_dashboard_pages() {
|
2466 |
-
$nav_items = apply_filters(
|
2467 |
-
'
|
2468 |
-
|
2469 |
-
|
2470 |
-
|
2471 |
-
|
2472 |
-
|
2473 |
-
|
2474 |
-
|
2475 |
-
|
2476 |
-
|
2477 |
-
|
2478 |
-
|
2479 |
-
|
2480 |
-
'
|
2481 |
-
|
2482 |
-
|
2483 |
-
|
2484 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2485 |
|
2486 |
$disable = get_tutor_option( 'disable_course_review' );
|
2487 |
if ( $disable && isset( $nav_items['reviews'] ) ) {
|
@@ -2490,11 +2604,17 @@ class Utils {
|
|
2490 |
|
2491 |
$nav_items = array_merge( $nav_items, $instructor_nav_items );
|
2492 |
|
2493 |
-
$new_navs
|
2494 |
-
'
|
2495 |
-
|
2496 |
-
|
2497 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2498 |
$all_nav_items = array_merge( $nav_items, $new_navs );
|
2499 |
|
2500 |
return apply_filters( 'tutor_dashboard/nav_items_all', $all_nav_items );
|
@@ -2503,9 +2623,15 @@ class Utils {
|
|
2503 |
public function tutor_dashboard_permalinks() {
|
2504 |
$dashboard_pages = $this->tutor_dashboard_pages();
|
2505 |
|
2506 |
-
$dashboard_permalinks = apply_filters(
|
2507 |
-
'
|
2508 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2509 |
|
2510 |
$dashboard_pages = array_merge( $dashboard_pages, $dashboard_permalinks );
|
2511 |
|
@@ -2524,23 +2650,23 @@ class Utils {
|
|
2524 |
$nav_items = $this->tutor_dashboard_pages();
|
2525 |
|
2526 |
foreach ( $nav_items as $key => $nav_item ) {
|
2527 |
-
if ( is_array($nav_item) ) {
|
2528 |
|
2529 |
if ( isset( $nav_item['show_ui'] ) && ! tutor_utils()->array_get( 'show_ui', $nav_item ) ) {
|
2530 |
unset( $nav_items[ $key ] );
|
2531 |
}
|
2532 |
-
if ( isset($nav_item['auth_cap'] ) && ! current_user_can( $nav_item['auth_cap'] ) ) {
|
2533 |
unset( $nav_items[ $key ] );
|
2534 |
}
|
2535 |
}
|
2536 |
}
|
2537 |
|
2538 |
-
return apply_filters('tutor_dashboard/nav_ui_items', $nav_items);
|
2539 |
}
|
2540 |
|
2541 |
/**
|
2542 |
* @param string $page_key
|
2543 |
-
* @param int
|
2544 |
*
|
2545 |
* @return string
|
2546 |
*
|
@@ -2553,8 +2679,8 @@ class Utils {
|
|
2553 |
$page_key = '';
|
2554 |
}
|
2555 |
if ( ! $page_id ) {
|
2556 |
-
|
2557 |
-
|
2558 |
return trailingslashit( get_permalink( $page_id ) ) . $page_key;
|
2559 |
}
|
2560 |
|
@@ -2570,7 +2696,7 @@ class Utils {
|
|
2570 |
*/
|
2571 |
public function input_old( $input = '', $old_data = null ) {
|
2572 |
if ( ! $old_data ) {
|
2573 |
-
$old_data = $_REQUEST;
|
2574 |
}
|
2575 |
$value = $this->avalue_dot( $input, $old_data );
|
2576 |
if ( $value ) {
|
@@ -2595,7 +2721,7 @@ class Utils {
|
|
2595 |
}
|
2596 |
|
2597 |
/**
|
2598 |
-
* @param int
|
2599 |
* @param bool $status_name
|
2600 |
*
|
2601 |
* @return bool|mixed
|
@@ -2607,19 +2733,22 @@ class Utils {
|
|
2607 |
public function instructor_status( $user_id = 0, $status_name = true ) {
|
2608 |
$user_id = $this->get_user_id( $user_id );
|
2609 |
|
2610 |
-
$instructor_status = apply_filters(
|
2611 |
-
'
|
2612 |
-
|
2613 |
-
|
2614 |
-
|
|
|
|
|
|
|
2615 |
|
2616 |
$status = get_user_meta( $user_id, '_tutor_instructor_status', true );
|
2617 |
|
2618 |
-
if ( isset( $instructor_status[$status] ) ) {
|
2619 |
if ( ! $status_name ) {
|
2620 |
return $status;
|
2621 |
}
|
2622 |
-
return $instructor_status[$status];
|
2623 |
}
|
2624 |
return false;
|
2625 |
}
|
@@ -2633,32 +2762,34 @@ class Utils {
|
|
2633 |
*
|
2634 |
* @since v.1.0.0
|
2635 |
*/
|
2636 |
-
public function get_total_instructors( $search_filter = '') {
|
2637 |
global $wpdb;
|
2638 |
|
2639 |
-
sanitize_text_field($search_filter);
|
2640 |
-
|
2641 |
-
$search_filter = '%' . $wpdb->esc_like( $search_filter ) . '%';
|
2642 |
|
2643 |
-
$
|
2644 |
-
|
|
|
|
|
|
|
2645 |
FROM {$wpdb->users} as user
|
2646 |
INNER JOIN {$wpdb->usermeta} as user_meta
|
2647 |
ON ( user_meta.user_id = user.ID )
|
2648 |
-
|
2649 |
WHERE user_meta.meta_key = %s
|
2650 |
AND ( user.display_name LIKE %s OR user.user_email LIKE %s );
|
2651 |
",
|
2652 |
-
|
2653 |
-
|
2654 |
-
|
2655 |
-
|
|
|
2656 |
return $count;
|
2657 |
}
|
2658 |
|
2659 |
/**
|
2660 |
-
* @param int
|
2661 |
-
* @param int
|
2662 |
* @param string $search_term
|
2663 |
*
|
2664 |
* @return array|null|object
|
@@ -2670,38 +2801,44 @@ class Utils {
|
|
2670 |
public function get_instructors( $start = 0, $limit = 10, $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '', $status = null, $cat_ids = array() ) {
|
2671 |
global $wpdb;
|
2672 |
|
2673 |
-
sanitize_text_field($search_filter);
|
2674 |
-
sanitize_text_field($course_filter);
|
2675 |
-
sanitize_text_field($date_filter);
|
2676 |
-
sanitize_text_field($order_filter);
|
2677 |
|
2678 |
-
$search_filter
|
2679 |
-
$course_filter
|
2680 |
|
2681 |
if ( '' != $date_filter ) {
|
2682 |
$date_filter = tutor_get_formated_date( 'Y-m-d', $date_filter );
|
2683 |
}
|
2684 |
-
|
2685 |
-
$date_filter = $date_filter != '' ? " AND DATE(user.user_registered) = '$date_filter' " : '' ;
|
2686 |
|
2687 |
-
$
|
|
|
|
|
2688 |
$category_where = '';
|
2689 |
|
2690 |
if ( $status ) {
|
2691 |
-
!is_array( $status ) ? $status = array( $status ) : 0;
|
2692 |
|
2693 |
-
$status = array_map(
|
2694 |
-
|
2695 |
-
|
|
|
|
|
|
|
2696 |
|
2697 |
-
$status =
|
2698 |
}
|
2699 |
|
2700 |
-
$cat_ids = array_filter(
|
2701 |
-
|
2702 |
-
|
|
|
|
|
|
|
2703 |
|
2704 |
-
if(count( $cat_ids )) {
|
2705 |
|
2706 |
$category_join =
|
2707 |
"INNER JOIN {$wpdb->posts} course
|
@@ -2713,17 +2850,18 @@ class Utils {
|
|
2713 |
INNER JOIN {$wpdb->prefix}terms term
|
2714 |
ON term.term_id=taxonomy.term_id";
|
2715 |
|
2716 |
-
$cat_ids
|
2717 |
$category_where = " AND term.term_id IN ({$cat_ids})";
|
2718 |
}
|
2719 |
|
2720 |
-
$instructors = $wpdb->get_results(
|
2721 |
-
|
|
|
2722 |
FROM {$wpdb->users} user
|
2723 |
INNER JOIN {$wpdb->usermeta} user_meta
|
2724 |
-
ON ( user.ID = user_meta.user_id )
|
2725 |
-
INNER JOIN {$wpdb->usermeta} inst_status
|
2726 |
-
ON ( user.ID = inst_status.user_id )
|
2727 |
{$category_join}
|
2728 |
WHERE user_meta.meta_key = %s
|
2729 |
AND ( user.display_name LIKE %s OR user.user_email LIKE %s )
|
@@ -2734,13 +2872,13 @@ class Utils {
|
|
2734 |
ORDER BY user_meta.meta_value {$order_filter}
|
2735 |
LIMIT %d, %d;
|
2736 |
",
|
2737 |
-
|
2738 |
-
|
2739 |
-
|
2740 |
-
|
2741 |
-
|
2742 |
-
|
2743 |
-
)
|
2744 |
|
2745 |
return $instructors;
|
2746 |
}
|
@@ -2758,34 +2896,36 @@ class Utils {
|
|
2758 |
global $wpdb;
|
2759 |
$course_id = $this->get_post_id( $course_id );
|
2760 |
|
2761 |
-
$instructors = $wpdb->get_results(
|
2762 |
-
|
|
|
2763 |
display_name,
|
2764 |
get_course.meta_value AS taught_course_id,
|
2765 |
tutor_job_title.meta_value AS tutor_profile_job_title,
|
2766 |
tutor_bio.meta_value AS tutor_profile_bio,
|
2767 |
-
tutor_photo.meta_value AS tutor_profile_photo
|
2768 |
-
FROM {$wpdb->users}
|
2769 |
-
INNER JOIN {$wpdb->usermeta} get_course
|
2770 |
-
ON ID = get_course.user_id
|
2771 |
-
AND get_course.meta_key = %s
|
2772 |
-
AND get_course.meta_value = %d
|
2773 |
-
LEFT JOIN {$wpdb->usermeta} tutor_job_title
|
2774 |
-
ON ID = tutor_job_title.user_id
|
2775 |
-
AND tutor_job_title.meta_key = %s
|
2776 |
-
LEFT JOIN {$wpdb->usermeta} tutor_bio
|
2777 |
-
ON ID = tutor_bio.user_id
|
2778 |
-
AND tutor_bio.meta_key = %s
|
2779 |
-
LEFT JOIN {$wpdb->usermeta} tutor_photo
|
2780 |
-
ON ID = tutor_photo.user_id
|
2781 |
AND tutor_photo.meta_key = %s
|
2782 |
",
|
2783 |
-
|
2784 |
-
|
2785 |
-
|
2786 |
-
|
2787 |
-
|
2788 |
-
|
|
|
2789 |
|
2790 |
if ( is_array( $instructors ) && count( $instructors ) ) {
|
2791 |
return $instructors;
|
@@ -2809,9 +2949,10 @@ class Utils {
|
|
2809 |
|
2810 |
$course_post_type = tutor()->course_post_type;
|
2811 |
|
2812 |
-
$count = $wpdb->get_var(
|
2813 |
-
|
2814 |
-
|
|
|
2815 |
INNER JOIN {$wpdb->posts} course
|
2816 |
ON enrollment.post_parent=course.ID
|
2817 |
WHERE course.post_author = %d
|
@@ -2820,55 +2961,55 @@ class Utils {
|
|
2820 |
AND enrollment.post_type = %s
|
2821 |
AND enrollment.post_status = %s;
|
2822 |
",
|
2823 |
-
|
2824 |
-
|
2825 |
-
|
2826 |
-
|
2827 |
-
|
2828 |
-
|
2829 |
-
)
|
2830 |
|
2831 |
return (int) $count;
|
2832 |
}
|
2833 |
|
2834 |
/**
|
2835 |
* Get all students by instructor_id
|
2836 |
-
*
|
2837 |
* @param $instructor_id int | required
|
2838 |
-
*
|
2839 |
* @param $offset int | required
|
2840 |
-
*
|
2841 |
* @param $limit int | required
|
2842 |
-
*
|
2843 |
* @param $search string | optional
|
2844 |
-
*
|
2845 |
* @param $course_id int | optional
|
2846 |
-
*
|
2847 |
* @param $date string | optional
|
2848 |
-
*
|
2849 |
* @return array
|
2850 |
-
*
|
2851 |
* @since 1.9.9
|
2852 |
*/
|
2853 |
public function get_students_by_instructor( int $instructor_id, int $offset, int $limit, $search_filter = '', $course_id = '', $date_filter = '', $order_by = '', $order = '' ): array {
|
2854 |
global $wpdb;
|
2855 |
-
$instructor_id
|
2856 |
-
$limit
|
2857 |
-
$offset
|
2858 |
-
$course_id
|
2859 |
-
$date_filter
|
2860 |
-
$search_filter
|
2861 |
-
|
2862 |
-
$order_by
|
2863 |
if ( 'registration_date' === $order_by ) {
|
2864 |
$order_by = 'enrollment.post_date';
|
2865 |
-
}
|
2866 |
$order_by = 'course_taken';
|
2867 |
} else {
|
2868 |
$order_by = 'user.ID';
|
2869 |
}
|
2870 |
|
2871 |
-
$order
|
2872 |
|
2873 |
if ( '' !== $date_filter ) {
|
2874 |
$date_filter = \tutor_get_formated_date( 'Y-m-d', $date_filter );
|
@@ -2887,9 +3028,10 @@ class Utils {
|
|
2887 |
$date_query = " AND DATE(user.user_registered) = CAST( '$date_filter' AS DATE ) ";
|
2888 |
}
|
2889 |
|
2890 |
-
$students
|
2891 |
-
|
2892 |
-
FROM
|
|
|
2893 |
INNER JOIN {$wpdb->posts} AS course
|
2894 |
ON enrollment.post_parent=course.ID
|
2895 |
INNER JOIN {$wpdb->users} AS user
|
@@ -2907,23 +3049,25 @@ class Utils {
|
|
2907 |
ORDER BY {$order_by} {$order}
|
2908 |
LIMIT %d, %d
|
2909 |
",
|
2910 |
-
|
2911 |
-
|
2912 |
-
|
2913 |
-
|
2914 |
-
|
2915 |
-
|
2916 |
-
|
2917 |
-
|
2918 |
-
|
2919 |
-
|
2920 |
-
|
2921 |
-
|
2922 |
-
|
2923 |
-
|
2924 |
-
|
2925 |
-
|
2926 |
-
|
|
|
|
|
2927 |
INNER JOIN {$wpdb->users} AS user
|
2928 |
ON user.ID = enrollment.post_author
|
2929 |
WHERE course.post_author = %d
|
@@ -2936,42 +3080,44 @@ class Utils {
|
|
2936 |
{$date_query}
|
2937 |
GROUP BY enrollment.post_author
|
2938 |
ORDER BY {$order_by} {$order}
|
2939 |
-
|
2940 |
",
|
2941 |
-
|
2942 |
-
|
2943 |
-
|
2944 |
-
|
2945 |
-
|
2946 |
-
|
2947 |
-
|
2948 |
-
|
2949 |
-
|
2950 |
-
|
|
|
2951 |
|
2952 |
return array(
|
2953 |
-
'students'
|
2954 |
-
'total_students' => count($total_students)
|
2955 |
);
|
2956 |
}
|
2957 |
|
2958 |
/**
|
2959 |
* Get all course for a give student & instructor id
|
2960 |
-
*
|
2961 |
* @param $student_id int | required
|
2962 |
-
*
|
2963 |
* @param $instructor_id int | required
|
2964 |
-
*
|
2965 |
* @return array
|
2966 |
-
*
|
2967 |
* @since 1.9.9
|
2968 |
*/
|
2969 |
-
public function get_courses_by_student_instructor_id
|
2970 |
global $wpdb;
|
2971 |
$course_post_type = tutor()->course_post_type;
|
2972 |
-
$students
|
2973 |
-
|
2974 |
-
|
|
|
2975 |
INNER JOIN {$wpdb->posts} AS course
|
2976 |
ON enrollment.post_parent=course.ID
|
2977 |
WHERE course.post_author = %d
|
@@ -2982,70 +3128,75 @@ class Utils {
|
|
2982 |
AND enrollment.post_author = %d
|
2983 |
ORDER BY course.post_date DESC
|
2984 |
",
|
2985 |
-
|
2986 |
-
|
2987 |
-
|
2988 |
-
|
2989 |
-
|
2990 |
-
|
2991 |
-
|
|
|
2992 |
return $students;
|
2993 |
}
|
2994 |
|
2995 |
/**
|
2996 |
* Get total number of completed assignment
|
2997 |
-
*
|
2998 |
* @param $course_id int | required
|
2999 |
-
*
|
3000 |
* @param $student | required
|
3001 |
-
*
|
3002 |
* @since 1.9.9
|
3003 |
*/
|
3004 |
-
public function get_completed_assignment(int $course_id, int $student_id): int {
|
3005 |
global $wpdb;
|
3006 |
-
$course_id
|
3007 |
$student_id = sanitize_text_field( $student_id );
|
3008 |
-
$count
|
3009 |
-
|
|
|
3010 |
INNER JOIN wp_comments c ON c.comment_post_ID = wp_posts.ID AND c.user_id = %d AND c.comment_approved = %s
|
3011 |
WHERE post_parent IN (SELECT ID FROM wp_posts WHERE post_type = %s AND post_parent = %d AND post_status = %s)
|
3012 |
-
AND post_type =%s
|
3013 |
AND post_status = %s
|
3014 |
-
|
3015 |
-
|
3016 |
-
|
3017 |
-
|
3018 |
-
|
3019 |
-
|
3020 |
-
|
3021 |
-
|
3022 |
-
|
|
|
3023 |
return (int) $count;
|
3024 |
}
|
3025 |
/**
|
3026 |
* Get total number of completed quiz
|
3027 |
-
*
|
3028 |
* @param $course_id int | required
|
3029 |
-
*
|
3030 |
* @param $student | required
|
3031 |
-
*
|
3032 |
* @since 1.9.9
|
3033 |
*/
|
3034 |
-
public function get_completed_quiz(int $course_id, int $student_id): int {
|
3035 |
global $wpdb;
|
3036 |
-
$course_id
|
3037 |
$student_id = sanitize_text_field( $student_id );
|
3038 |
-
$count
|
3039 |
-
|
3040 |
-
|
3041 |
-
|
|
|
3042 |
AND user_id = %d
|
3043 |
AND attempt_status = %s
|
3044 |
",
|
3045 |
-
|
3046 |
-
|
3047 |
-
|
3048 |
-
|
|
|
3049 |
return (int) $count;
|
3050 |
}
|
3051 |
|
@@ -3060,10 +3211,10 @@ class Utils {
|
|
3060 |
*/
|
3061 |
public function get_rating_value( $input = 0.00 ) {
|
3062 |
|
3063 |
-
if ( $input > 0) {
|
3064 |
-
$input
|
3065 |
$int_value = (int) $input;
|
3066 |
-
$fraction
|
3067 |
|
3068 |
if ( $fraction == 0 ) {
|
3069 |
$fraction = 0.00;
|
@@ -3081,7 +3232,7 @@ class Utils {
|
|
3081 |
|
3082 |
/**
|
3083 |
* @param float $current_rating
|
3084 |
-
* @param bool
|
3085 |
*
|
3086 |
* @return string
|
3087 |
*
|
@@ -3092,26 +3243,26 @@ class Utils {
|
|
3092 |
public function star_rating_generator( $current_rating = 0.00, $echo = true ) {
|
3093 |
$output = '<div class="tutor-star-rating-group">';
|
3094 |
|
3095 |
-
for ( $i = 1; $i <=5
|
3096 |
$intRating = (int) $current_rating;
|
3097 |
|
3098 |
if ( $intRating >= $i ) {
|
3099 |
-
$output.= '<i class="tutor-icon-star-full" data-rating-value="'
|
3100 |
} else {
|
3101 |
-
if ( ( $current_rating - $i) == -0.5 ) {
|
3102 |
-
$output.= '<i class="tutor-icon-star-half" data-rating-value="'
|
3103 |
} else {
|
3104 |
-
$output.= '<i class="tutor-icon-star-line" data-rating-value="'
|
3105 |
}
|
3106 |
}
|
3107 |
}
|
3108 |
|
3109 |
-
$output .=
|
3110 |
|
3111 |
-
$output .=
|
3112 |
|
3113 |
if ( $echo ) {
|
3114 |
-
echo $output;
|
3115 |
}
|
3116 |
|
3117 |
return $output;
|
@@ -3123,18 +3274,16 @@ class Utils {
|
|
3123 |
* @return string
|
3124 |
*
|
3125 |
* Split string regardless of ASCI, Unicode
|
3126 |
-
*
|
3127 |
-
*
|
3128 |
*/
|
3129 |
public function str_split( $string ) {
|
3130 |
$strlen = mb_strlen( $string );
|
3131 |
while ( $strlen ) {
|
3132 |
-
$array[] = mb_substr( $string,0,1,
|
3133 |
-
$string
|
3134 |
-
$strlen
|
3135 |
}
|
3136 |
return $array;
|
3137 |
-
}
|
3138 |
|
3139 |
/**
|
3140 |
* @param null $name
|
@@ -3154,18 +3303,18 @@ class Utils {
|
|
3154 |
|
3155 |
$user = $this->get_tutor_user( $user_id );
|
3156 |
if ( $user->tutor_profile_photo ) {
|
3157 |
-
return '<img src="'.wp_get_attachment_image_url( $user->tutor_profile_photo, $size ).'" class="tutor-image-avatar" alt="" /> ';
|
3158 |
}
|
3159 |
|
3160 |
$name = $user->display_name;
|
3161 |
-
$arr
|
3162 |
|
3163 |
-
$first_char
|
3164 |
-
$second_char
|
3165 |
-
$initial_avatar = strtoupper( $first_char
|
3166 |
|
3167 |
-
$bg_color
|
3168 |
-
$initial_avatar =
|
3169 |
|
3170 |
return $initial_avatar;
|
3171 |
}
|
@@ -3182,15 +3331,16 @@ class Utils {
|
|
3182 |
public function get_tutor_user( $user_id ) {
|
3183 |
global $wpdb;
|
3184 |
|
3185 |
-
$user = $wpdb->get_row(
|
3186 |
-
|
3187 |
-
|
3188 |
-
|
|
|
3189 |
tutor_bio.meta_value AS tutor_profile_bio,
|
3190 |
tutor_photo.meta_value AS tutor_profile_photo
|
3191 |
FROM {$wpdb->users}
|
3192 |
-
LEFT JOIN {$wpdb->usermeta} tutor_job_title
|
3193 |
-
ON ID = tutor_job_title.user_id
|
3194 |
AND tutor_job_title.meta_key = '_tutor_profile_job_title'
|
3195 |
LEFT JOIN {$wpdb->usermeta} tutor_bio
|
3196 |
ON ID = tutor_bio.user_id
|
@@ -3200,8 +3350,9 @@ class Utils {
|
|
3200 |
AND tutor_photo.meta_key = '_tutor_profile_photo'
|
3201 |
WHERE ID = %d
|
3202 |
",
|
3203 |
-
|
3204 |
-
|
|
|
3205 |
|
3206 |
return $user;
|
3207 |
}
|
@@ -3221,31 +3372,33 @@ class Utils {
|
|
3221 |
$course_id = $this->get_post_id( $course_id );
|
3222 |
global $wpdb;
|
3223 |
|
3224 |
-
$reviews = $wpdb->get_results(
|
3225 |
-
|
3226 |
-
|
3227 |
-
{$wpdb->comments}.
|
3228 |
-
{$wpdb->comments}.
|
3229 |
-
{$wpdb->comments}.
|
3230 |
-
{$wpdb->comments}.
|
3231 |
-
{$wpdb->comments}.
|
|
|
3232 |
{$wpdb->commentmeta}.meta_value AS rating,
|
3233 |
-
{$wpdb->users}.display_name
|
3234 |
-
|
3235 |
FROM {$wpdb->comments}
|
3236 |
-
INNER JOIN {$wpdb->commentmeta}
|
3237 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3238 |
LEFT JOIN {$wpdb->users}
|
3239 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3240 |
-
WHERE {$wpdb->comments}.comment_post_ID = %d
|
3241 |
AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating'
|
3242 |
ORDER BY comment_ID DESC
|
3243 |
LIMIT %d, %d;
|
3244 |
",
|
3245 |
-
|
3246 |
-
|
3247 |
-
|
3248 |
-
|
|
|
3249 |
|
3250 |
return $reviews;
|
3251 |
}
|
@@ -3267,11 +3420,18 @@ class Utils {
|
|
3267 |
'rating_count' => 0,
|
3268 |
'rating_sum' => 0,
|
3269 |
'rating_avg' => 0.00,
|
3270 |
-
'count_by_value' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
3271 |
);
|
3272 |
|
3273 |
-
$rating = $wpdb->get_row(
|
3274 |
-
|
|
|
3275 |
SUM(meta_value) AS rating_sum
|
3276 |
FROM {$wpdb->comments}
|
3277 |
INNER JOIN {$wpdb->commentmeta}
|
@@ -3279,42 +3439,51 @@ class Utils {
|
|
3279 |
WHERE {$wpdb->comments}.comment_post_ID = %d
|
3280 |
AND {$wpdb->comments}.comment_type = %s
|
3281 |
AND meta_key = %s;
|
3282 |
-
",
|
3283 |
-
|
3284 |
-
|
3285 |
-
|
3286 |
-
|
|
|
3287 |
|
3288 |
if ( $rating->rating_count ) {
|
3289 |
$avg_rating = number_format( ( $rating->rating_sum / $rating->rating_count ), 2 );
|
3290 |
|
3291 |
-
$stars = $wpdb->get_results(
|
3292 |
-
|
3293 |
-
|
|
|
3294 |
FROM {$wpdb->comments} comments
|
3295 |
INNER JOIN {$wpdb->commentmeta} commentmeta
|
3296 |
ON comments.comment_ID = commentmeta.comment_id
|
3297 |
-
WHERE comments.comment_post_ID = %d
|
3298 |
AND comments.comment_type = %s
|
3299 |
AND commentmeta.meta_key = %s
|
3300 |
GROUP BY commentmeta.meta_value;
|
3301 |
-
",
|
3302 |
-
|
3303 |
-
|
3304 |
-
|
3305 |
-
|
|
|
3306 |
|
3307 |
-
$ratings = array(
|
|
|
|
|
|
|
|
|
|
|
|
|
3308 |
foreach ( $stars as $star ) {
|
3309 |
$index = (int) $star->rating;
|
3310 |
-
array_key_exists($index, $ratings) ? $ratings[ $index ] = $star->rating_count : 0;
|
3311 |
}
|
3312 |
|
3313 |
$ratings = array(
|
3314 |
'rating_count' => $rating->rating_count,
|
3315 |
'rating_sum' => $rating->rating_sum,
|
3316 |
'rating_avg' => $avg_rating,
|
3317 |
-
'count_by_value' => $ratings
|
3318 |
);
|
3319 |
}
|
3320 |
|
@@ -3336,8 +3505,9 @@ class Utils {
|
|
3336 |
$user_id = $this->get_user_id( $user_id );
|
3337 |
global $wpdb;
|
3338 |
|
3339 |
-
$reviews = $wpdb->get_results(
|
3340 |
-
|
|
|
3341 |
{$wpdb->comments}.comment_post_ID,
|
3342 |
{$wpdb->comments}.comment_author,
|
3343 |
{$wpdb->comments}.comment_author_email,
|
@@ -3346,45 +3516,47 @@ class Utils {
|
|
3346 |
{$wpdb->comments}.user_id,
|
3347 |
{$wpdb->commentmeta}.meta_value as rating,
|
3348 |
{$wpdb->users}.display_name
|
3349 |
-
|
3350 |
FROM {$wpdb->comments}
|
3351 |
-
INNER JOIN {$wpdb->commentmeta}
|
3352 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3353 |
INNER JOIN {$wpdb->users}
|
3354 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3355 |
-
WHERE {$wpdb->comments}.user_id = %d
|
3356 |
AND comment_type = %s
|
3357 |
AND meta_key = %s
|
3358 |
ORDER BY comment_ID DESC
|
3359 |
LIMIT %d, %d;
|
3360 |
",
|
3361 |
-
|
3362 |
-
|
3363 |
-
|
3364 |
-
|
3365 |
-
|
3366 |
-
|
3367 |
-
|
3368 |
|
3369 |
-
if($get_object) {
|
3370 |
-
$count = (int)$wpdb->get_var(
|
3371 |
-
|
|
|
3372 |
FROM {$wpdb->comments}
|
3373 |
-
INNER JOIN {$wpdb->commentmeta}
|
3374 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3375 |
INNER JOIN {$wpdb->users}
|
3376 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3377 |
-
WHERE {$wpdb->comments}.user_id = %d
|
3378 |
AND comment_type = %s
|
3379 |
AND meta_key = %s",
|
3380 |
-
|
3381 |
-
|
3382 |
-
|
3383 |
-
|
|
|
3384 |
|
3385 |
-
return (object)array(
|
3386 |
-
'count'
|
3387 |
-
'results' => $reviews
|
3388 |
);
|
3389 |
}
|
3390 |
|
@@ -3392,47 +3564,47 @@ class Utils {
|
|
3392 |
}
|
3393 |
|
3394 |
/**
|
3395 |
-
* @param int
|
3396 |
-
* @param int
|
3397 |
-
* @param int
|
3398 |
*
|
3399 |
* @return array|null|object
|
3400 |
*
|
3401 |
* Get reviews by instructor (Received by the instructor)
|
3402 |
*
|
3403 |
* @since v.1.4.0
|
3404 |
-
*
|
3405 |
* @param $course_id optional
|
3406 |
-
*
|
3407 |
* @param $date_filter optional
|
3408 |
-
*
|
3409 |
* Course id & date filter is sorting with specific course and date
|
3410 |
-
*
|
3411 |
* @since 1.9.9
|
3412 |
*/
|
3413 |
public function get_reviews_by_instructor( $instructor_id = 0, $offset = 0, $limit = 150, $course_id = '', $date_filter = '' ) {
|
3414 |
global $wpdb;
|
3415 |
-
$instructor_id
|
3416 |
-
$offset
|
3417 |
-
$limit
|
3418 |
-
$course_id
|
3419 |
-
$date_filter
|
3420 |
-
$instructor_id
|
3421 |
|
3422 |
-
$course_query
|
3423 |
-
$date_query
|
3424 |
|
3425 |
if ( '' !== $course_id ) {
|
3426 |
$course_query = " AND {$wpdb->comments}.comment_post_ID = {$course_id} ";
|
3427 |
-
}
|
3428 |
if ( '' !== $date_filter ) {
|
3429 |
-
$date_filter
|
3430 |
-
$date_query
|
3431 |
-
}
|
3432 |
|
3433 |
$results = array(
|
3434 |
-
'count'
|
3435 |
-
'results'
|
3436 |
);
|
3437 |
|
3438 |
$cours_ids = (array) $this->get_assigned_courses_ids_by_instructors( $instructor_id );
|
@@ -3440,45 +3612,48 @@ class Utils {
|
|
3440 |
if ( $this->count( $cours_ids ) ) {
|
3441 |
$implode_ids = implode( ',', $cours_ids );
|
3442 |
|
3443 |
-
//Count
|
3444 |
-
$results['count'] = $wpdb->get_var(
|
3445 |
-
|
|
|
3446 |
FROM {$wpdb->comments}
|
3447 |
INNER JOIN {$wpdb->commentmeta}
|
3448 |
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3449 |
INNER JOIN {$wpdb->users}
|
3450 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3451 |
-
WHERE {$wpdb->comments}.comment_post_ID IN({$implode_ids})
|
3452 |
AND comment_type = %s
|
3453 |
AND meta_key = %s
|
3454 |
{$course_query}
|
3455 |
{$date_query}
|
3456 |
",
|
3457 |
-
|
3458 |
-
|
3459 |
-
|
3460 |
-
|
3461 |
-
|
3462 |
-
|
3463 |
-
|
3464 |
-
|
3465 |
-
|
3466 |
-
{$wpdb->comments}.
|
3467 |
-
{$wpdb->comments}.
|
3468 |
-
{$wpdb->comments}.
|
3469 |
-
{$wpdb->comments}.
|
|
|
|
|
3470 |
{$wpdb->commentmeta}.meta_value AS rating,
|
3471 |
{$wpdb->users}.display_name,
|
3472 |
{$wpdb->posts}.post_title as course_title
|
3473 |
-
|
3474 |
FROM {$wpdb->comments}
|
3475 |
-
INNER JOIN {$wpdb->commentmeta}
|
3476 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3477 |
INNER JOIN {$wpdb->users}
|
3478 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3479 |
INNER JOIN {$wpdb->posts}
|
3480 |
ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID
|
3481 |
-
WHERE {$wpdb->comments}.comment_post_ID IN({$implode_ids})
|
3482 |
AND comment_type = %s
|
3483 |
AND meta_key = %s
|
3484 |
{$course_query}
|
@@ -3486,11 +3661,12 @@ class Utils {
|
|
3486 |
ORDER BY comment_ID DESC
|
3487 |
LIMIT %d, %d;
|
3488 |
",
|
3489 |
-
|
3490 |
-
|
3491 |
-
|
3492 |
-
|
3493 |
-
|
|
|
3494 |
}
|
3495 |
|
3496 |
return (object) $results;
|
@@ -3509,13 +3685,14 @@ class Utils {
|
|
3509 |
global $wpdb;
|
3510 |
|
3511 |
$ratings = array(
|
3512 |
-
'rating_count'
|
3513 |
-
'rating_sum'
|
3514 |
-
'rating_avg'
|
3515 |
);
|
3516 |
|
3517 |
-
$rating = $wpdb->get_row(
|
3518 |
-
|
|
|
3519 |
FROM {$wpdb->usermeta} courses
|
3520 |
INNER JOIN {$wpdb->comments} reviews
|
3521 |
ON courses.meta_value = reviews.comment_post_ID
|
@@ -3526,17 +3703,18 @@ class Utils {
|
|
3526 |
WHERE courses.user_id = %d
|
3527 |
AND courses.meta_key = %s
|
3528 |
",
|
3529 |
-
|
3530 |
-
|
3531 |
-
|
|
|
3532 |
|
3533 |
if ( $rating->rating_count ) {
|
3534 |
$avg_rating = number_format( ( $rating->rating_sum / $rating->rating_count ), 2 );
|
3535 |
|
3536 |
$ratings = array(
|
3537 |
-
'rating_count'
|
3538 |
-
'rating_sum'
|
3539 |
-
'rating_avg'
|
3540 |
);
|
3541 |
}
|
3542 |
|
@@ -3557,27 +3735,29 @@ class Utils {
|
|
3557 |
global $wpdb;
|
3558 |
|
3559 |
$course_id = $this->get_post_id( $course_id );
|
3560 |
-
$user_id
|
3561 |
|
3562 |
$ratings = array(
|
3563 |
'rating' => 0,
|
3564 |
'review' => '',
|
3565 |
);
|
3566 |
|
3567 |
-
$rating = $wpdb->get_row(
|
3568 |
-
|
|
|
3569 |
comment_content AS review
|
3570 |
FROM {$wpdb->comments}
|
3571 |
-
INNER JOIN {$wpdb->commentmeta}
|
3572 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3573 |
WHERE {$wpdb->comments}.comment_post_ID = %d
|
3574 |
AND user_id = %d
|
3575 |
AND meta_key = %s;
|
3576 |
",
|
3577 |
-
|
3578 |
-
|
3579 |
-
|
3580 |
-
|
|
|
3581 |
|
3582 |
if ( $rating ) {
|
3583 |
$rating_format = number_format( $rating->rating, 2 );
|
@@ -3601,17 +3781,19 @@ class Utils {
|
|
3601 |
public function count_reviews_wrote_by_user( $user_id = 0 ) {
|
3602 |
global $wpdb;
|
3603 |
|
3604 |
-
$user_id = $this->get_user_id($user_id);
|
3605 |
|
3606 |
-
$count_reviews = $wpdb->get_var(
|
3607 |
-
|
|
|
3608 |
FROM {$wpdb->comments}
|
3609 |
WHERE user_id = %d
|
3610 |
AND comment_type = %s
|
3611 |
",
|
3612 |
-
|
3613 |
-
|
3614 |
-
|
|
|
3615 |
|
3616 |
return $count_reviews;
|
3617 |
}
|
@@ -3633,19 +3815,19 @@ class Utils {
|
|
3633 |
switch ( strtoupper( $l ) ) {
|
3634 |
case 'P':
|
3635 |
$ret *= 1024;
|
3636 |
-
|
3637 |
case 'T':
|
3638 |
$ret *= 1024;
|
3639 |
-
|
3640 |
case 'G':
|
3641 |
$ret *= 1024;
|
3642 |
-
|
3643 |
case 'M':
|
3644 |
$ret *= 1024;
|
3645 |
-
|
3646 |
case 'K':
|
3647 |
$ret *= 1024;
|
3648 |
-
|
3649 |
}
|
3650 |
return $ret;
|
3651 |
}
|
@@ -3698,37 +3880,39 @@ class Utils {
|
|
3698 |
public function get_top_question( $course_id = 0, $user_id = 0, $offset = 0, $limit = 20, $is_author = false ) {
|
3699 |
global $wpdb;
|
3700 |
|
3701 |
-
$course_id
|
3702 |
-
$user_id
|
3703 |
|
3704 |
-
$author_sql = $is_author ?
|
3705 |
-
|
3706 |
-
$questions = $wpdb->get_results(
|
3707 |
-
|
3708 |
-
|
3709 |
-
{$wpdb->comments}.
|
3710 |
-
{$wpdb->comments}.
|
3711 |
-
{$wpdb->comments}.
|
3712 |
-
{$wpdb->comments}.
|
3713 |
-
{$wpdb->comments}.
|
3714 |
-
{$wpdb->
|
3715 |
-
{$wpdb->
|
3716 |
-
|
|
|
3717 |
INNER JOIN {$wpdb->commentmeta}
|
3718 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3719 |
INNER JOIN {$wpdb->users}
|
3720 |
-
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3721 |
-
WHERE {$wpdb->comments}.comment_post_ID = {$course_id} {$author_sql}
|
3722 |
-
AND {$wpdb->comments}.comment_type = %s
|
3723 |
-
AND meta_key = %s
|
3724 |
-
ORDER BY comment_ID DESC
|
3725 |
LIMIT %d, %d;
|
3726 |
",
|
3727 |
-
|
3728 |
-
|
3729 |
-
|
3730 |
-
|
3731 |
-
|
|
|
3732 |
|
3733 |
return $questions;
|
3734 |
}
|
@@ -3745,7 +3929,7 @@ class Utils {
|
|
3745 |
public function get_total_qa_question( $search_term = '' ) {
|
3746 |
global $wpdb;
|
3747 |
|
3748 |
-
$user_id
|
3749 |
$course_type = tutor()->course_post_type;
|
3750 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
3751 |
|
@@ -3755,32 +3939,36 @@ class Utils {
|
|
3755 |
*/
|
3756 |
if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
|
3757 |
|
3758 |
-
$get_course_ids = $wpdb->get_col(
|
3759 |
-
|
|
|
3760 |
FROM {$wpdb->posts}
|
3761 |
WHERE post_author = %d
|
3762 |
AND post_type = %s
|
3763 |
AND post_status = %s
|
3764 |
",
|
3765 |
-
|
3766 |
-
|
3767 |
-
|
3768 |
-
|
|
|
3769 |
|
3770 |
-
$get_assigned_courses_ids = $wpdb->get_col(
|
3771 |
-
|
|
|
3772 |
FROM {$wpdb->usermeta}
|
3773 |
WHERE meta_key = %s
|
3774 |
AND user_id = %d
|
3775 |
",
|
3776 |
-
|
3777 |
-
|
3778 |
-
|
|
|
3779 |
|
3780 |
$my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
|
3781 |
|
3782 |
if ( $this->count( $my_course_ids ) ) {
|
3783 |
-
$implode_ids
|
3784 |
$in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
|
3785 |
}
|
3786 |
}
|
@@ -3790,31 +3978,34 @@ class Utils {
|
|
3790 |
* could be retained thus total number counted and q & a showing
|
3791 |
* list is not similar
|
3792 |
* now only the q & a will be appeared that is belongs to a user
|
|
|
3793 |
* @since version 1.9.0
|
3794 |
*/
|
3795 |
-
$count = $wpdb->get_var(
|
3796 |
-
|
|
|
3797 |
FROM {$wpdb->comments}
|
3798 |
INNER JOIN {$wpdb->commentmeta}
|
3799 |
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3800 |
|
3801 |
-
INNER JOIN {$wpdb->users}
|
3802 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3803 |
|
3804 |
-
WHERE comment_type = %s
|
3805 |
AND comment_parent = 0 {$in_question_id_query}
|
3806 |
AND {$wpdb->commentmeta}.meta_value LIKE %s;
|
3807 |
",
|
3808 |
-
|
3809 |
-
|
3810 |
-
|
|
|
3811 |
|
3812 |
return (int) $count;
|
3813 |
}
|
3814 |
|
3815 |
/**
|
3816 |
-
* @param int
|
3817 |
-
* @param int
|
3818 |
* @param string $search_term
|
3819 |
*
|
3820 |
* @return array|null|object
|
@@ -3836,49 +4027,54 @@ class Utils {
|
|
3836 |
* Get only assinged courses questions if current user is a
|
3837 |
*/
|
3838 |
if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
|
3839 |
-
|
3840 |
-
$get_course_ids = $wpdb->get_col(
|
3841 |
-
|
|
|
3842 |
FROM {$wpdb->posts}
|
3843 |
WHERE post_author = %d
|
3844 |
AND post_type = %s
|
3845 |
AND post_status = %s
|
3846 |
",
|
3847 |
-
|
3848 |
-
|
3849 |
-
|
3850 |
-
|
|
|
3851 |
|
3852 |
-
$get_assigned_courses_ids = $wpdb->get_col(
|
3853 |
-
|
|
|
3854 |
FROM {$wpdb->usermeta}
|
3855 |
WHERE meta_key = %s
|
3856 |
AND user_id = %d
|
3857 |
",
|
3858 |
-
|
3859 |
-
|
3860 |
-
|
|
|
3861 |
|
3862 |
$my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
|
3863 |
|
3864 |
if ( $this->count( $my_course_ids ) ) {
|
3865 |
-
$implode_ids
|
3866 |
$in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
|
3867 |
}
|
3868 |
}
|
3869 |
|
3870 |
-
$query = $wpdb->get_results(
|
3871 |
-
|
3872 |
-
|
3873 |
-
{$wpdb->comments}.
|
3874 |
-
{$wpdb->comments}.
|
3875 |
-
{$wpdb->comments}.
|
3876 |
-
{$wpdb->comments}.
|
3877 |
-
{$wpdb->
|
3878 |
-
{$wpdb->
|
3879 |
-
{$wpdb->
|
3880 |
-
|
3881 |
-
|
|
|
3882 |
WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID
|
3883 |
) AS answer_count
|
3884 |
FROM {$wpdb->comments}
|
@@ -3892,14 +4088,15 @@ class Utils {
|
|
3892 |
AND {$wpdb->comments}.comment_parent = 0
|
3893 |
AND {$wpdb->commentmeta}.meta_value LIKE %s
|
3894 |
{$in_question_id_query}
|
3895 |
-
ORDER BY {$wpdb->comments}.comment_ID DESC
|
3896 |
LIMIT %d, %d;
|
3897 |
",
|
3898 |
-
|
3899 |
-
|
3900 |
-
|
3901 |
-
|
3902 |
-
|
|
|
3903 |
|
3904 |
return $query;
|
3905 |
}
|
@@ -3915,30 +4112,32 @@ class Utils {
|
|
3915 |
*/
|
3916 |
public function get_qa_question( $question_id ) {
|
3917 |
global $wpdb;
|
3918 |
-
$query = $wpdb->get_row(
|
3919 |
-
|
3920 |
-
|
3921 |
-
{$wpdb->comments}.
|
3922 |
-
{$wpdb->comments}.
|
3923 |
-
{$wpdb->comments}.
|
3924 |
-
{$wpdb->comments}.
|
3925 |
-
{$wpdb->comments}.
|
3926 |
-
{$wpdb->
|
3927 |
-
{$wpdb->
|
3928 |
-
{$wpdb->
|
3929 |
-
|
3930 |
-
|
3931 |
-
|
3932 |
-
|
3933 |
-
|
|
|
3934 |
INNER JOIN {$wpdb->users}
|
3935 |
-
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3936 |
-
WHERE comment_type = %s
|
3937 |
AND {$wpdb->comments}.comment_ID = %d;
|
3938 |
",
|
3939 |
-
|
3940 |
-
|
3941 |
-
|
|
|
3942 |
|
3943 |
return $query;
|
3944 |
}
|
@@ -3952,8 +4151,9 @@ class Utils {
|
|
3952 |
*/
|
3953 |
public function get_qa_answer_by_question( $question_id ) {
|
3954 |
global $wpdb;
|
3955 |
-
$query = $wpdb->get_results(
|
3956 |
-
|
|
|
3957 |
{$wpdb->comments}.comment_post_ID,
|
3958 |
{$wpdb->comments}.comment_author,
|
3959 |
{$wpdb->comments}.comment_date,
|
@@ -3969,9 +4169,10 @@ class Utils {
|
|
3969 |
AND {$wpdb->comments}.comment_parent = %d
|
3970 |
ORDER BY {$wpdb->comments}.comment_ID ASC;
|
3971 |
",
|
3972 |
-
|
3973 |
-
|
3974 |
-
|
|
|
3975 |
|
3976 |
return $query;
|
3977 |
}
|
@@ -3980,34 +4181,36 @@ class Utils {
|
|
3980 |
* @param $answer_id
|
3981 |
*
|
3982 |
* @return array|null|object
|
3983 |
-
*
|
3984 |
* @since v1.6.9
|
3985 |
*
|
3986 |
* Get question and asnwer by answer_id
|
3987 |
*/
|
3988 |
public function get_qa_answer_by_answer_id( $answer_id ) {
|
3989 |
global $wpdb;
|
3990 |
-
$answer = $wpdb->get_row(
|
3991 |
-
|
3992 |
-
|
|
|
3993 |
users.display_name,
|
3994 |
question.user_id AS question_by,
|
3995 |
question.comment_content AS question,
|
3996 |
question_meta.meta_value AS question_title
|
3997 |
FROM {$wpdb->comments} answer
|
3998 |
INNER JOIN {$wpdb->users} users
|
3999 |
-
ON answer.user_id = users.id
|
4000 |
-
INNER JOIN {$wpdb->comments} question
|
4001 |
-
ON answer.comment_parent = question.comment_ID
|
4002 |
-
INNER JOIN {$wpdb->commentmeta} question_meta
|
4003 |
ON answer.comment_parent = question_meta.comment_id
|
4004 |
AND question_meta.meta_key = 'tutor_question_title'
|
4005 |
-
WHERE answer.comment_ID = %d
|
4006 |
AND answer.comment_type = %s;
|
4007 |
-
",
|
4008 |
-
|
4009 |
-
|
4010 |
-
|
|
|
4011 |
|
4012 |
if ( $answer ) {
|
4013 |
return $answer;
|
@@ -4023,9 +4226,10 @@ class Utils {
|
|
4023 |
* instructor as it was count unanswered question from all courses
|
4024 |
* from now on it will check if tutor instructor and count
|
4025 |
* from instructor's course
|
|
|
4026 |
* @since version 1.9.0
|
4027 |
*/
|
4028 |
-
$user_id
|
4029 |
$course_type = tutor()->course_post_type;
|
4030 |
|
4031 |
$in_question_id_query = '';
|
@@ -4034,38 +4238,43 @@ class Utils {
|
|
4034 |
*/
|
4035 |
if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
|
4036 |
|
4037 |
-
$get_course_ids = $wpdb->get_col(
|
4038 |
-
|
|
|
4039 |
FROM {$wpdb->posts}
|
4040 |
WHERE post_author = %d
|
4041 |
AND post_type = %s
|
4042 |
AND post_status = %s
|
4043 |
",
|
4044 |
-
|
4045 |
-
|
4046 |
-
|
4047 |
-
|
|
|
4048 |
|
4049 |
-
$get_assigned_courses_ids = $wpdb->get_col(
|
4050 |
-
|
|
|
4051 |
FROM {$wpdb->usermeta}
|
4052 |
WHERE meta_key = %s
|
4053 |
AND user_id = %d
|
4054 |
",
|
4055 |
-
|
4056 |
-
|
4057 |
-
|
|
|
4058 |
|
4059 |
$my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
|
4060 |
|
4061 |
if ( $this->count( $my_course_ids ) ) {
|
4062 |
-
$implode_ids
|
4063 |
$in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
|
4064 |
}
|
4065 |
}
|
4066 |
|
4067 |
-
$count = $wpdb->get_var(
|
4068 |
-
|
|
|
4069 |
FROM {$wpdb->comments}
|
4070 |
INNER JOIN {$wpdb->posts}
|
4071 |
ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
|
@@ -4075,9 +4284,10 @@ class Utils {
|
|
4075 |
AND {$wpdb->comments}.comment_approved = %s
|
4076 |
AND {$wpdb->comments}.comment_parent = 0 {$in_question_id_query};
|
4077 |
",
|
4078 |
-
|
4079 |
-
|
4080 |
-
|
|
|
4081 |
return (int) $count;
|
4082 |
}
|
4083 |
|
@@ -4093,23 +4303,25 @@ class Utils {
|
|
4093 |
public function get_announcements( $course_id = 0 ) {
|
4094 |
$course_id = $this->get_post_id( $course_id );
|
4095 |
global $wpdb;
|
4096 |
-
$query = $wpdb->get_results(
|
4097 |
-
|
4098 |
-
|
4099 |
-
|
4100 |
-
|
4101 |
-
|
4102 |
-
|
4103 |
-
|
4104 |
-
|
4105 |
-
|
4106 |
-
|
|
|
4107 |
AND post_parent = %d
|
4108 |
ORDER BY {$wpdb->posts}.ID DESC;
|
4109 |
",
|
4110 |
-
|
4111 |
-
|
4112 |
-
|
|
|
4113 |
return $query;
|
4114 |
}
|
4115 |
|
@@ -4127,7 +4339,7 @@ class Utils {
|
|
4127 |
|
4128 |
$user_display_name = 'User';
|
4129 |
if ( is_user_logged_in() ) {
|
4130 |
-
$user
|
4131 |
$user_display_name = $user->display_name;
|
4132 |
}
|
4133 |
|
@@ -4137,17 +4349,17 @@ class Utils {
|
|
4137 |
}
|
4138 |
|
4139 |
/**
|
4140 |
-
* @param int
|
4141 |
* @param string $option_key
|
4142 |
-
* @param bool
|
4143 |
*
|
4144 |
* @return array|bool|mixed
|
4145 |
*
|
4146 |
* Get the quiz option from meta
|
4147 |
*/
|
4148 |
public function get_quiz_option( $post_id = 0, $option_key = '', $default = false ) {
|
4149 |
-
$post_id
|
4150 |
-
$get_option_meta = maybe_unserialize(get_post_meta( $post_id, 'tutor_quiz_option', true ) );
|
4151 |
|
4152 |
if ( ! $option_key && ! empty( $get_option_meta ) ) {
|
4153 |
return $get_option_meta;
|
@@ -4172,14 +4384,16 @@ class Utils {
|
|
4172 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4173 |
global $wpdb;
|
4174 |
|
4175 |
-
$questions = $wpdb->get_results(
|
4176 |
-
|
|
|
4177 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4178 |
WHERE quiz_id = %d
|
4179 |
ORDER BY question_order ASC
|
4180 |
",
|
4181 |
-
|
4182 |
-
|
|
|
4183 |
|
4184 |
if ( is_array( $questions ) && count( $questions ) ) {
|
4185 |
return $questions;
|
@@ -4199,14 +4413,16 @@ class Utils {
|
|
4199 |
global $wpdb;
|
4200 |
|
4201 |
if ( $question_id ) {
|
4202 |
-
$question = $wpdb->get_row(
|
4203 |
-
|
|
|
4204 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4205 |
WHERE question_id = %d
|
4206 |
LIMIT 0, 1;
|
4207 |
",
|
4208 |
-
|
4209 |
-
|
|
|
4210 |
|
4211 |
return $question;
|
4212 |
}
|
@@ -4225,40 +4441,82 @@ class Utils {
|
|
4225 |
*/
|
4226 |
public function get_question_types( $type = null ) {
|
4227 |
$types = array(
|
4228 |
-
'true_false'
|
4229 |
-
|
4230 |
-
|
4231 |
-
|
4232 |
-
|
4233 |
-
'
|
4234 |
-
|
4235 |
-
|
4236 |
-
|
4237 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4238 |
);
|
4239 |
|
4240 |
if ( isset( $types[ $type ] ) ) {
|
4241 |
return $types[ $type ];
|
4242 |
}
|
4243 |
-
|
4244 |
return $types;
|
4245 |
}
|
4246 |
|
4247 |
public function get_quiz_answer_options_by_question( $question_id ) {
|
4248 |
global $wpdb;
|
4249 |
|
4250 |
-
$answer_options = $wpdb->get_results(
|
4251 |
-
|
4252 |
-
|
|
|
4253 |
{$wpdb->comments}.comment_content
|
4254 |
FROM {$wpdb->comments}
|
4255 |
-
WHERE {$wpdb->comments}.comment_post_ID = %d
|
4256 |
AND {$wpdb->comments}.comment_type = %s
|
4257 |
ORDER BY {$wpdb->comments}.comment_karma ASC;
|
4258 |
",
|
4259 |
-
|
4260 |
-
|
4261 |
-
|
|
|
4262 |
|
4263 |
if ( is_array( $answer_options ) && count( $answer_options ) ) {
|
4264 |
return $answer_options;
|
@@ -4278,13 +4536,15 @@ class Utils {
|
|
4278 |
public function quiz_next_question_order_id( $quiz_id ) {
|
4279 |
global $wpdb;
|
4280 |
|
4281 |
-
$last_order = (int) $wpdb->get_var(
|
4282 |
-
|
4283 |
-
|
|
|
4284 |
WHERE quiz_id = %d ;
|
4285 |
",
|
4286 |
-
|
4287 |
-
|
|
|
4288 |
|
4289 |
return $last_order + 1;
|
4290 |
}
|
@@ -4306,13 +4566,15 @@ class Utils {
|
|
4306 |
|
4307 |
public function get_quiz_id_by_question( $question_id ) {
|
4308 |
global $wpdb;
|
4309 |
-
$quiz_id = $wpdb->get_var(
|
4310 |
-
|
4311 |
-
|
|
|
4312 |
WHERE question_id = %d;
|
4313 |
",
|
4314 |
-
|
4315 |
-
|
|
|
4316 |
return $quiz_id;
|
4317 |
}
|
4318 |
|
@@ -4328,8 +4590,9 @@ class Utils {
|
|
4328 |
|
4329 |
$post_id = $this->get_post_id( $post_id );
|
4330 |
|
4331 |
-
$questions = $wpdb->get_results(
|
4332 |
-
|
|
|
4333 |
post_content,
|
4334 |
post_title,
|
4335 |
post_parent
|
@@ -4338,10 +4601,11 @@ class Utils {
|
|
4338 |
AND post_status = %s
|
4339 |
AND post_parent = %d;
|
4340 |
",
|
4341 |
-
|
4342 |
-
|
4343 |
-
|
4344 |
-
|
|
|
4345 |
|
4346 |
if ( is_array( $questions ) && count( $questions ) ) {
|
4347 |
return $questions;
|
@@ -4363,13 +4627,13 @@ class Utils {
|
|
4363 |
global $wpdb;
|
4364 |
|
4365 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4366 |
-
$post
|
4367 |
|
4368 |
if ( $post ) {
|
4369 |
$course_post_type = tutor()->course_post_type;
|
4370 |
-
$query_string
|
4371 |
-
$course
|
4372 |
-
|
4373 |
if ( $course ) {
|
4374 |
if ( $course->post_type !== $course_post_type ) {
|
4375 |
$course = $wpdb->get_row( $wpdb->prepare( $query_string, $course->post_parent ) );
|
@@ -4393,15 +4657,17 @@ class Utils {
|
|
4393 |
global $wpdb;
|
4394 |
|
4395 |
$max_questions_count = (int) tutor_utils()->get_quiz_option( get_the_ID(), 'max_questions_for_answer' );
|
4396 |
-
$total_question
|
4397 |
-
|
|
|
4398 |
FROM {$wpdb->tutor_quiz_questions}
|
4399 |
WHERE quiz_id = %d;
|
4400 |
",
|
4401 |
-
|
4402 |
-
|
|
|
4403 |
|
4404 |
-
return min($max_questions_count, $total_question);
|
4405 |
}
|
4406 |
|
4407 |
/**
|
@@ -4419,17 +4685,19 @@ class Utils {
|
|
4419 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4420 |
$user_id = get_current_user_id();
|
4421 |
|
4422 |
-
$is_started = $wpdb->get_row(
|
4423 |
-
|
|
|
4424 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4425 |
WHERE user_id = %d
|
4426 |
AND quiz_id = %d
|
4427 |
AND attempt_status = %s;
|
4428 |
",
|
4429 |
-
|
4430 |
-
|
4431 |
-
|
4432 |
-
|
|
|
4433 |
|
4434 |
return $is_started;
|
4435 |
}
|
@@ -4449,13 +4717,15 @@ class Utils {
|
|
4449 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4450 |
global $wpdb;
|
4451 |
|
4452 |
-
$max_questions = (int) $wpdb->get_var(
|
4453 |
-
|
|
|
4454 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4455 |
WHERE quiz_id = %d;
|
4456 |
",
|
4457 |
-
|
4458 |
-
|
|
|
4459 |
|
4460 |
$max_mentioned = (int) $this->get_quiz_option( $quiz_id, 'max_questions_for_answer', 10 );
|
4461 |
|
@@ -4481,13 +4751,15 @@ class Utils {
|
|
4481 |
return false;
|
4482 |
}
|
4483 |
|
4484 |
-
$attempt = $wpdb->get_row(
|
4485 |
-
|
|
|
4486 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4487 |
WHERE attempt_id = %d;
|
4488 |
",
|
4489 |
-
|
4490 |
-
|
|
|
4491 |
|
4492 |
return $attempt;
|
4493 |
}
|
@@ -4507,7 +4779,7 @@ class Utils {
|
|
4507 |
|
4508 |
/**
|
4509 |
* @param $quiz_attempt_id
|
4510 |
-
* @param array
|
4511 |
*
|
4512 |
* @return bool|int
|
4513 |
*
|
@@ -4516,13 +4788,13 @@ class Utils {
|
|
4516 |
* @since v.1.0.0
|
4517 |
*/
|
4518 |
public function quiz_update_attempt_info( $quiz_attempt_id, $attempt_info = array() ) {
|
4519 |
-
$answers
|
4520 |
-
$total_marks
|
4521 |
-
$earned_marks
|
4522 |
-
$earned_mark_percent = $earned_marks > 0 ? ( number_format( ($earned_marks * 100) / $total_marks) ) : 0;
|
4523 |
update_comment_meta( $quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent );
|
4524 |
|
4525 |
-
return update_comment_meta( $quiz_attempt_id,'quiz_attempt_info', $attempt_info );
|
4526 |
}
|
4527 |
|
4528 |
/**
|
@@ -4537,20 +4809,22 @@ class Utils {
|
|
4537 |
public function get_random_question_by_quiz( $quiz_id = 0 ) {
|
4538 |
global $wpdb;
|
4539 |
|
4540 |
-
$quiz_id
|
4541 |
$is_attempt = $this->is_started_quiz( $quiz_id );
|
4542 |
|
4543 |
-
$tempSql
|
4544 |
-
$questions = $wpdb->get_results(
|
4545 |
-
|
|
|
4546 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4547 |
WHERE quiz_id = %d
|
4548 |
{$tempSql}
|
4549 |
ORDER BY RAND()
|
4550 |
LIMIT 0, 1
|
4551 |
",
|
4552 |
-
|
4553 |
-
|
|
|
4554 |
|
4555 |
return $questions;
|
4556 |
}
|
@@ -4565,8 +4839,8 @@ class Utils {
|
|
4565 |
public function get_random_questions_by_quiz( $quiz_id = 0 ) {
|
4566 |
global $wpdb;
|
4567 |
|
4568 |
-
$quiz_id
|
4569 |
-
$attempt
|
4570 |
$total_questions = (int) $attempt->total_questions;
|
4571 |
if ( ! $attempt ) {
|
4572 |
return false;
|
@@ -4574,15 +4848,15 @@ class Utils {
|
|
4574 |
|
4575 |
$questions_order = tutor_utils()->get_quiz_option( get_the_ID(), 'questions_order', 'rand' );
|
4576 |
|
4577 |
-
$order_by =
|
4578 |
if ( $questions_order === 'rand' ) {
|
4579 |
-
$order_by =
|
4580 |
} elseif ( $questions_order === 'asc' ) {
|
4581 |
-
$order_by =
|
4582 |
} elseif ( $questions_order === 'desc' ) {
|
4583 |
-
$order_by =
|
4584 |
} elseif ( $questions_order === 'sorting' ) {
|
4585 |
-
$order_by =
|
4586 |
}
|
4587 |
|
4588 |
$limit = '';
|
@@ -4590,22 +4864,24 @@ class Utils {
|
|
4590 |
$limit = "LIMIT {$total_questions} ";
|
4591 |
}
|
4592 |
|
4593 |
-
$questions = $wpdb->get_results(
|
4594 |
-
|
|
|
4595 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4596 |
WHERE quiz_id = %d
|
4597 |
{$order_by}
|
4598 |
{$limit}
|
4599 |
",
|
4600 |
-
|
4601 |
-
|
|
|
4602 |
|
4603 |
return $questions;
|
4604 |
}
|
4605 |
|
4606 |
/**
|
4607 |
* @param $question_id
|
4608 |
-
* @param bool
|
4609 |
*
|
4610 |
* @return array|bool|null|object
|
4611 |
*
|
@@ -4616,38 +4892,42 @@ class Utils {
|
|
4616 |
public function get_answers_by_quiz_question( $question_id, $rand = false ) {
|
4617 |
global $wpdb;
|
4618 |
|
4619 |
-
$question = $wpdb->get_row(
|
4620 |
-
|
|
|
4621 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4622 |
WHERE question_id = %d;
|
4623 |
",
|
4624 |
-
|
4625 |
-
|
|
|
4626 |
|
4627 |
if ( ! $question ) {
|
4628 |
return false;
|
4629 |
}
|
4630 |
|
4631 |
-
$order =
|
4632 |
if ( $question->question_type === 'ordering' ) {
|
4633 |
-
$order =
|
4634 |
}
|
4635 |
|
4636 |
-
if ($rand){
|
4637 |
-
$order =
|
4638 |
}
|
4639 |
|
4640 |
-
$answers = $wpdb->get_results(
|
4641 |
-
|
4642 |
-
|
|
|
4643 |
WHERE belongs_question_id = %d
|
4644 |
AND belongs_question_type = %s
|
4645 |
ORDER BY {$order}
|
4646 |
",
|
4647 |
-
|
4648 |
-
|
4649 |
-
|
4650 |
-
|
|
|
4651 |
return $answers;
|
4652 |
}
|
4653 |
|
@@ -4668,16 +4948,18 @@ class Utils {
|
|
4668 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4669 |
$user_id = $this->get_user_id( $user_id );
|
4670 |
|
4671 |
-
$attempts = $wpdb->get_results(
|
4672 |
-
|
|
|
4673 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4674 |
WHERE quiz_id = %d
|
4675 |
AND user_id = %d
|
4676 |
-
ORDER BY attempt_id DESC
|
4677 |
",
|
4678 |
-
|
4679 |
-
|
4680 |
-
|
|
|
4681 |
|
4682 |
if ( is_array( $attempts ) && count( $attempts ) ) {
|
4683 |
return $attempts;
|
@@ -4702,17 +4984,19 @@ class Utils {
|
|
4702 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4703 |
$user_id = $this->get_user_id( $user_id );
|
4704 |
|
4705 |
-
$attempts = $wpdb->get_results(
|
4706 |
-
|
|
|
4707 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4708 |
WHERE quiz_id = %d
|
4709 |
AND user_id = %d
|
4710 |
AND attempt_status != %s
|
4711 |
",
|
4712 |
-
|
4713 |
-
|
4714 |
-
|
4715 |
-
|
|
|
4716 |
|
4717 |
if ( is_array( $attempts ) && count( $attempts ) ) {
|
4718 |
return $attempts;
|
@@ -4735,14 +5019,16 @@ class Utils {
|
|
4735 |
global $wpdb;
|
4736 |
|
4737 |
$user_id = $this->get_user_id( $user_id );
|
4738 |
-
$attempts = $wpdb->get_results(
|
4739 |
-
|
|
|
4740 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4741 |
WHERE user_id = %d
|
4742 |
ORDER BY attempt_id DESC
|
4743 |
",
|
4744 |
-
|
4745 |
-
|
|
|
4746 |
|
4747 |
if ( is_array( $attempts ) && count( $attempts ) ) {
|
4748 |
return $attempts;
|
@@ -4759,21 +5045,21 @@ class Utils {
|
|
4759 |
* Total number of quiz attempts
|
4760 |
*
|
4761 |
* @since v.1.0.0
|
4762 |
-
*
|
4763 |
* This method is not being in used
|
4764 |
-
*
|
4765 |
-
* to get total number of attempt get_quiz_attempts method is enough
|
4766 |
-
*
|
4767 |
-
* @since 1.9.5
|
4768 |
*
|
|
|
|
|
|
|
4769 |
*/
|
4770 |
public function get_total_quiz_attempts( $search_term = '' ) {
|
4771 |
global $wpdb;
|
4772 |
|
4773 |
-
$search_term
|
4774 |
|
4775 |
-
$count = $wpdb->get_var(
|
4776 |
-
|
|
|
4777 |
FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
|
4778 |
INNER JOIN {$wpdb->posts} quiz
|
4779 |
ON quiz_attempts.quiz_id = quiz.ID
|
@@ -4782,18 +5068,19 @@ class Utils {
|
|
4782 |
WHERE attempt_status != %s
|
4783 |
AND ( user_email LIKE %s OR display_name LIKE %s OR post_title LIKE %s )
|
4784 |
",
|
4785 |
-
|
4786 |
-
|
4787 |
-
|
4788 |
-
|
4789 |
-
|
|
|
4790 |
|
4791 |
return (int) $count;
|
4792 |
}
|
4793 |
|
4794 |
/**
|
4795 |
-
* @param int
|
4796 |
-
* @param int
|
4797 |
* @param string $search_term
|
4798 |
*
|
4799 |
* @return array|null|object
|
@@ -4802,21 +5089,22 @@ class Utils {
|
|
4802 |
* Get the all quiz attempts
|
4803 |
*
|
4804 |
* @since 1.0.0
|
4805 |
-
*
|
4806 |
-
* Sorting paramas added
|
4807 |
-
*
|
4808 |
* @since 1.9.5
|
4809 |
*/
|
4810 |
-
public function get_quiz_attempts( $start = 0, $limit = 10, $search_filter='', $course_filter='', $date_filter='', $order_filter='' ) {
|
4811 |
global $wpdb;
|
4812 |
|
4813 |
-
$search_filter
|
4814 |
-
$course_filter
|
4815 |
-
$date_filter
|
4816 |
-
$date_filter
|
4817 |
|
4818 |
-
$query = $wpdb->get_results(
|
4819 |
-
|
|
|
4820 |
FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
|
4821 |
INNER JOIN {$wpdb->posts} quiz
|
4822 |
ON quiz_attempts.quiz_id = quiz.ID
|
@@ -4828,124 +5116,135 @@ class Utils {
|
|
4828 |
AND ( users.user_email LIKE %s OR users.display_name LIKE %s OR quiz.post_title LIKE %s OR course.post_title LIKE %s )
|
4829 |
{$course_filter}
|
4830 |
{$date_filter}
|
4831 |
-
ORDER BY quiz_attempts.attempt_ended_at $order_filter
|
4832 |
LIMIT %d, %d;
|
4833 |
",
|
4834 |
-
|
4835 |
-
|
4836 |
-
|
4837 |
-
|
4838 |
-
|
4839 |
-
|
4840 |
-
|
4841 |
-
|
|
|
4842 |
|
4843 |
return $query;
|
4844 |
}
|
4845 |
|
4846 |
/**
|
4847 |
* Delete quizattempt for user
|
4848 |
-
*
|
4849 |
* @since v1.9.5
|
4850 |
*/
|
4851 |
-
public function delete_quiz_attempt($attempt_ids) {
|
4852 |
global $wpdb;
|
4853 |
|
4854 |
// Singlular to array
|
4855 |
-
!is_array($attempt_ids) ? $attempt_ids = array($attempt_ids) : 0;
|
4856 |
|
4857 |
-
if(count($attempt_ids)) {
|
4858 |
-
$attempt_ids = implode( ',',
|
4859 |
|
4860 |
-
//Deleting attempt (comment), child attempt and attempt meta (comment meta)
|
4861 |
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id IN($attempt_ids)" );
|
4862 |
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_quiz_attempt_answers WHERE quiz_attempt_id IN($attempt_ids)" );
|
4863 |
}
|
4864 |
}
|
4865 |
|
4866 |
/**
|
4867 |
-
* Sorting params added on quiz attempt
|
4868 |
-
*
|
4869 |
* SQL query updated
|
4870 |
-
*
|
4871 |
* @since 1.9.5
|
4872 |
*/
|
4873 |
public function get_quiz_attempts_by_course_ids( $start = 0, $limit = 10, $course_ids = array(), $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '', $user_id = null ) {
|
4874 |
global $wpdb;
|
4875 |
|
4876 |
-
$course_ids = array_map(
|
4877 |
-
|
4878 |
-
|
|
|
|
|
|
|
4879 |
|
4880 |
$course_ids_in = implode( ', ', $course_ids );
|
4881 |
|
4882 |
-
$search_filter
|
4883 |
$search_filter = $search_filter ? "AND ( users.user_email LIKE {$search_filter} OR users.display_name LIKE {$search_filter} OR quiz.post_title LIKE {$search_filter} OR course.post_title LIKE {$search_filter} )" : '';
|
4884 |
|
4885 |
-
$course_filter
|
4886 |
-
$date_filter
|
4887 |
-
$date_filter
|
4888 |
|
4889 |
-
$query = $wpdb->get_results(
|
4890 |
-
|
4891 |
-
|
|
|
4892 |
INNER JOIN {$wpdb->posts} AS quiz
|
4893 |
-
ON quiz_attempts.quiz_id = quiz.ID
|
4894 |
INNER JOIN {$wpdb->users} AS users
|
4895 |
-
ON quiz_attempts.user_id = users.ID
|
4896 |
INNER JOIN {$wpdb->posts} AS course
|
4897 |
-
ON course.ID = quiz_attempts.course_id
|
4898 |
WHERE quiz_attempts.course_id IN (" . $course_ids_in . ")
|
4899 |
AND quiz_attempts.attempt_status != %s
|
4900 |
{$search_filter}
|
4901 |
{$course_filter}
|
4902 |
{$date_filter}
|
4903 |
-
" . ($user_id ? ' AND user_id=\''.esc_sql( $user_id ).'\''
|
4904 |
ORDER BY quiz_attempts.attempt_id $order_filter
|
4905 |
LIMIT %d, %d;
|
4906 |
",
|
4907 |
-
|
4908 |
-
|
4909 |
-
|
4910 |
-
|
|
|
4911 |
|
4912 |
return $query;
|
4913 |
}
|
4914 |
|
4915 |
/**
|
4916 |
* This method is not being in used
|
4917 |
-
*
|
4918 |
-
* to get total number of attempt above method is enough
|
4919 |
-
*
|
4920 |
* @since 1.9.5
|
4921 |
*/
|
4922 |
public function get_total_quiz_attempts_by_course_ids( $course_ids = array(), $search_term = '' ) {
|
4923 |
global $wpdb;
|
4924 |
-
|
4925 |
-
$course_ids = array_map(
|
4926 |
-
|
4927 |
-
|
|
|
|
|
|
|
4928 |
|
4929 |
$course_ids_in = implode( ', ', $course_ids );
|
4930 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
4931 |
|
4932 |
-
$count = $wpdb->get_var(
|
4933 |
-
|
4934 |
-
|
|
|
4935 |
INNER JOIN {$wpdb->posts} quiz
|
4936 |
-
ON quiz_attempts.quiz_id = quiz.ID
|
4937 |
INNER JOIN {$wpdb->users}
|
4938 |
-
ON quiz_attempts.user_id = {$wpdb->users}.ID
|
4939 |
-
WHERE quiz_attempts.course_id IN (" . $course_ids_in .
|
4940 |
-
AND attempt_status != %s
|
4941 |
AND ( user_email LIKE %s OR display_name LIKE %s OR post_title LIKE %s )
|
4942 |
-
|
4943 |
-
|
4944 |
-
|
4945 |
-
|
4946 |
-
|
4947 |
-
|
4948 |
-
|
|
|
4949 |
return (int) $count;
|
4950 |
}
|
4951 |
|
@@ -4961,18 +5260,20 @@ class Utils {
|
|
4961 |
public function get_quiz_answers_by_attempt_id( $attempt_id ) {
|
4962 |
global $wpdb;
|
4963 |
|
4964 |
-
$results = $wpdb->get_results(
|
4965 |
-
|
4966 |
-
|
4967 |
-
question.
|
4968 |
-
|
|
|
4969 |
LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question
|
4970 |
-
ON answers.question_id = question.question_id
|
4971 |
-
WHERE answers.quiz_attempt_id = %d
|
4972 |
ORDER BY attempt_answer_id ASC;
|
4973 |
",
|
4974 |
-
|
4975 |
-
|
|
|
4976 |
|
4977 |
return $results;
|
4978 |
}
|
@@ -4990,25 +5291,30 @@ class Utils {
|
|
4990 |
global $wpdb;
|
4991 |
|
4992 |
! is_array( $answer_id ) ? $answer_id = array( $answer_id ) : 0;
|
4993 |
-
|
4994 |
-
$answer_id = array_map(
|
4995 |
-
|
4996 |
-
|
|
|
|
|
|
|
4997 |
|
4998 |
$in_ids_string = implode( ', ', $answer_id );
|
4999 |
-
|
5000 |
-
$answer = $wpdb->get_results(
|
5001 |
-
|
|
|
5002 |
question.question_title,
|
5003 |
question.question_type
|
5004 |
FROM {$wpdb->prefix}tutor_quiz_question_answers answer
|
5005 |
LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question
|
5006 |
ON answer.belongs_question_id = question.question_id
|
5007 |
-
WHERE answer.answer_id IN (" . $in_ids_string .
|
5008 |
AND 1 = %d;
|
5009 |
-
|
5010 |
-
|
5011 |
-
|
|
|
5012 |
|
5013 |
return $answer;
|
5014 |
}
|
@@ -5029,19 +5335,21 @@ class Utils {
|
|
5029 |
return false;
|
5030 |
}
|
5031 |
|
5032 |
-
$in_ids = implode(
|
5033 |
|
5034 |
global $wpdb;
|
5035 |
|
5036 |
-
$query = $wpdb->get_results(
|
5037 |
-
|
|
|
5038 |
comment_content
|
5039 |
FROM {$wpdb->comments}
|
5040 |
WHERE comment_type = %s
|
5041 |
AND comment_ID IN({$in_ids})
|
5042 |
",
|
5043 |
-
|
5044 |
-
|
|
|
5045 |
|
5046 |
if ( is_array( $query ) && count( $query ) ) {
|
5047 |
return $query;
|
@@ -5060,12 +5368,15 @@ class Utils {
|
|
5060 |
* @since v.1.0.0
|
5061 |
*/
|
5062 |
public function course_levels( $level = null ) {
|
5063 |
-
$levels = apply_filters(
|
5064 |
-
'
|
5065 |
-
|
5066 |
-
|
5067 |
-
|
5068 |
-
|
|
|
|
|
|
|
5069 |
|
5070 |
if ( $level ) {
|
5071 |
if ( isset( $levels[ $level ] ) ) {
|
@@ -5087,7 +5398,7 @@ class Utils {
|
|
5087 |
*/
|
5088 |
public function user_profile_permalinks() {
|
5089 |
$permalinks = array(
|
5090 |
-
'courses_taken'
|
5091 |
);
|
5092 |
|
5093 |
$show_enrolled_course = tutor_utils()->get_option( 'show_courses_completed_by_student' );
|
@@ -5143,7 +5454,7 @@ class Utils {
|
|
5143 |
*
|
5144 |
* Get frontend dashboard URL
|
5145 |
*/
|
5146 |
-
public function tutor_dashboard_url($sub_url = '') {
|
5147 |
$page_id = (int) tutor_utils()->get_option( 'tutor_dashboard_page_id' );
|
5148 |
$page_id = apply_filters( 'tutor_dashboard_page_id', $page_id );
|
5149 |
return trailingslashit( get_the_permalink( $page_id ) ) . $sub_url;
|
@@ -5153,7 +5464,6 @@ class Utils {
|
|
5153 |
* Get the tutor dashboard page ID
|
5154 |
*
|
5155 |
* @return int
|
5156 |
-
*
|
5157 |
*/
|
5158 |
public function dashboard_page_id() {
|
5159 |
$page_id = (int) tutor_utils()->get_option( 'tutor_dashboard_page_id' );
|
@@ -5173,22 +5483,24 @@ class Utils {
|
|
5173 |
*/
|
5174 |
public function is_wishlisted( $course_id = 0, $user_id = 0 ) {
|
5175 |
$course_id = $this->get_post_id( $course_id );
|
5176 |
-
$user_id
|
5177 |
if ( ! $user_id ) {
|
5178 |
return false;
|
5179 |
}
|
5180 |
|
5181 |
global $wpdb;
|
5182 |
-
$if_added_to_list = (bool) $wpdb->get_row(
|
5183 |
-
|
5184 |
-
|
|
|
5185 |
WHERE user_id = %d
|
5186 |
AND meta_key = '_tutor_course_wishlist'
|
5187 |
AND meta_value = %d;
|
5188 |
",
|
5189 |
-
|
5190 |
-
|
5191 |
-
|
|
|
5192 |
|
5193 |
return $if_added_to_list;
|
5194 |
}
|
@@ -5208,8 +5520,9 @@ class Utils {
|
|
5208 |
$user_id = $this->get_user_id( $user_id );
|
5209 |
$course_post_type = tutor()->course_post_type;
|
5210 |
|
5211 |
-
$pageposts = $wpdb->get_results(
|
5212 |
-
|
|
|
5213 |
FROM $wpdb->posts
|
5214 |
LEFT JOIN $wpdb->usermeta
|
5215 |
ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
|
@@ -5219,11 +5532,13 @@ class Utils {
|
|
5219 |
AND $wpdb->usermeta.user_id = %d
|
5220 |
ORDER BY $wpdb->usermeta.umeta_id DESC;
|
5221 |
",
|
5222 |
-
|
5223 |
-
|
5224 |
-
|
5225 |
-
|
5226 |
-
|
|
|
|
|
5227 |
|
5228 |
return $pageposts;
|
5229 |
}
|
@@ -5239,21 +5554,22 @@ class Utils {
|
|
5239 |
*/
|
5240 |
public function most_popular_courses( $limit = 10, $user_id = '' ) {
|
5241 |
global $wpdb;
|
5242 |
-
$limit
|
5243 |
-
$user_id
|
5244 |
|
5245 |
$author_query = '';
|
5246 |
if ( '' !== $user_id ) {
|
5247 |
$author_query = "AND course.post_author = $user_id";
|
5248 |
}
|
5249 |
|
5250 |
-
$courses = $wpdb->get_results(
|
5251 |
-
|
|
|
5252 |
enrolled.post_parent as course_id,
|
5253 |
course.*
|
5254 |
FROM {$wpdb->posts} enrolled
|
5255 |
INNER JOIN {$wpdb->posts} course
|
5256 |
-
ON enrolled.post_parent = course.ID
|
5257 |
WHERE enrolled.post_type = %s
|
5258 |
AND enrolled.post_status = %s
|
5259 |
{$author_query}
|
@@ -5261,10 +5577,11 @@ class Utils {
|
|
5261 |
ORDER BY total_enrolled DESC
|
5262 |
LIMIT 0, %d;
|
5263 |
",
|
5264 |
-
|
5265 |
-
|
5266 |
-
|
5267 |
-
|
|
|
5268 |
|
5269 |
return $courses;
|
5270 |
}
|
@@ -5281,8 +5598,9 @@ class Utils {
|
|
5281 |
public function most_rated_courses( $limit = 10 ) {
|
5282 |
global $wpdb;
|
5283 |
|
5284 |
-
$result = $wpdb->get_results(
|
5285 |
-
|
|
|
5286 |
comment_ID,
|
5287 |
comment_post_ID,
|
5288 |
course.*
|
@@ -5295,10 +5613,11 @@ class Utils {
|
|
5295 |
ORDER BY total_rating DESC
|
5296 |
LIMIT 0, %d
|
5297 |
;",
|
5298 |
-
|
5299 |
-
|
5300 |
-
|
5301 |
-
|
|
|
5302 |
|
5303 |
if ( is_array( $result ) && count( $result ) ) {
|
5304 |
return $result;
|
@@ -5339,20 +5658,21 @@ class Utils {
|
|
5339 |
*/
|
5340 |
function get_ip() {
|
5341 |
$ipaddress = '';
|
5342 |
-
if ( getenv( 'HTTP_CLIENT_IP') )
|
5343 |
$ipaddress = getenv( 'HTTP_CLIENT_IP' );
|
5344 |
-
|
5345 |
$ipaddress = getenv( 'HTTP_X_FORWARDED_FOR' );
|
5346 |
-
|
5347 |
$ipaddress = getenv( 'HTTP_X_FORWARDED' );
|
5348 |
-
|
5349 |
$ipaddress = getenv( 'HTTP_FORWARDED_FOR' );
|
5350 |
-
|
5351 |
$ipaddress = getenv( 'HTTP_FORWARDED' );
|
5352 |
-
|
5353 |
$ipaddress = getenv( 'REMOTE_ADDR' );
|
5354 |
-
else
|
5355 |
$ipaddress = 'UNKNOWN';
|
|
|
5356 |
return $ipaddress;
|
5357 |
}
|
5358 |
|
@@ -5365,10 +5685,22 @@ class Utils {
|
|
5365 |
*/
|
5366 |
public function tutor_social_share_icons() {
|
5367 |
$icons = array(
|
5368 |
-
'facebook' => array(
|
5369 |
-
|
5370 |
-
|
5371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5372 |
);
|
5373 |
|
5374 |
return apply_filters( 'tutor_social_share_icons', $icons );
|
@@ -5384,29 +5716,29 @@ class Utils {
|
|
5384 |
public function tutor_user_social_icons() {
|
5385 |
$icons = array(
|
5386 |
'_tutor_profile_website' => array(
|
5387 |
-
'label' => __('Website URL', 'tutor'),
|
5388 |
'placeholder' => 'https://example.com/',
|
5389 |
-
'icon_classes' => 'tutor-icon-earth'
|
5390 |
),
|
5391 |
-
'_tutor_profile_github'
|
5392 |
-
'label' => __('Github URL', 'tutor'),
|
5393 |
'placeholder' => 'https://github.com/username',
|
5394 |
-
'icon_classes' => 'tutor-icon-github-logo'
|
5395 |
),
|
5396 |
-
'_tutor_profile_facebook'
|
5397 |
-
'label' => __('Facebook URL', 'tutor'),
|
5398 |
'placeholder' => 'https://facebook.com/username',
|
5399 |
-
'icon_classes' => 'tutor-icon-facebook'
|
5400 |
),
|
5401 |
'_tutor_profile_twitter' => array(
|
5402 |
-
'label' => __('Twitter URL', 'tutor'),
|
5403 |
'placeholder' => 'https://twitter.com/username',
|
5404 |
-
'icon_classes' => 'tutor-icon-twitter'
|
5405 |
),
|
5406 |
-
'_tutor_profile_linkedin'
|
5407 |
-
'label' => __('Linkedin URL', 'tutor'),
|
5408 |
'placeholder' => 'https://linkedin.com/username',
|
5409 |
-
'icon_classes' => 'tutor-icon-linkedin'
|
5410 |
),
|
5411 |
);
|
5412 |
|
@@ -5439,19 +5771,19 @@ class Utils {
|
|
5439 |
*/
|
5440 |
public function tutor_get_screen_ids() {
|
5441 |
$screen_ids = array(
|
5442 |
-
|
5443 |
-
|
5444 |
-
|
5445 |
-
|
5446 |
-
|
5447 |
-
|
5448 |
-
|
5449 |
-
|
5450 |
-
|
5451 |
-
|
5452 |
-
|
5453 |
-
|
5454 |
-
|
5455 |
);
|
5456 |
|
5457 |
return apply_filters( 'tutor_get_screen_ids', $screen_ids );
|
@@ -5467,7 +5799,7 @@ class Utils {
|
|
5467 |
public function get_earnings_completed_statuses() {
|
5468 |
return apply_filters(
|
5469 |
'tutor_get_earnings_completed_statuses',
|
5470 |
-
array
|
5471 |
'wc-completed',
|
5472 |
'completed',
|
5473 |
'complete',
|
@@ -5476,7 +5808,7 @@ class Utils {
|
|
5476 |
}
|
5477 |
|
5478 |
/**
|
5479 |
-
* @param int
|
5480 |
* @param array $date_filter
|
5481 |
*
|
5482 |
* @return array|null|object
|
@@ -5488,7 +5820,7 @@ class Utils {
|
|
5488 |
public function get_earning_sum( $user_id = 0, $date_filter = array() ) {
|
5489 |
global $wpdb;
|
5490 |
|
5491 |
-
$user_id
|
5492 |
$date_query = '';
|
5493 |
|
5494 |
if ( $this->count( $date_filter ) ) {
|
@@ -5509,39 +5841,41 @@ class Utils {
|
|
5509 |
$complete_status = tutor_utils()->get_earnings_completed_statuses();
|
5510 |
$complete_status = "'" . implode( "','", $complete_status ) . "'";
|
5511 |
|
5512 |
-
$earning_sum = $wpdb->get_row(
|
5513 |
-
|
5514 |
-
|
5515 |
-
SUM(
|
|
|
5516 |
(SELECT SUM(amount)
|
5517 |
FROM {$wpdb->prefix}tutor_withdraws
|
5518 |
WHERE user_id = {$user_id}
|
5519 |
AND status != 'rejected'
|
5520 |
) AS withdraws_amount,
|
5521 |
-
SUM(admin_amount) AS admin_amount,
|
5522 |
SUM(deduct_fees_amount) AS deduct_fees_amount
|
5523 |
-
FROM {$wpdb->prefix}tutor_earnings
|
5524 |
WHERE user_id = %d
|
5525 |
AND order_status IN({$complete_status})
|
5526 |
{$date_query}
|
5527 |
",
|
5528 |
-
|
5529 |
-
|
|
|
5530 |
|
5531 |
-
//TODO: need to check
|
5532 |
// (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
|
5533 |
|
5534 |
if ( $earning_sum->course_price_total ) {
|
5535 |
$earning_sum->balance = $earning_sum->instructor_amount - $earning_sum->withdraws_amount;
|
5536 |
} else {
|
5537 |
$earning_sum = (object) array(
|
5538 |
-
'course_price_total'
|
5539 |
-
'course_price_grand_total'
|
5540 |
-
'instructor_amount'
|
5541 |
-
'withdraws_amount'
|
5542 |
-
'balance'
|
5543 |
-
'admin_amount'
|
5544 |
-
'deduct_fees_amount'
|
5545 |
);
|
5546 |
}
|
5547 |
|
@@ -5549,7 +5883,7 @@ class Utils {
|
|
5549 |
}
|
5550 |
|
5551 |
/**
|
5552 |
-
* @param int
|
5553 |
* @param array $date_filter
|
5554 |
*
|
5555 |
* @return array|null|object
|
@@ -5561,13 +5895,13 @@ class Utils {
|
|
5561 |
public function get_earning_statements( $user_id = 0, $filter_data = array() ) {
|
5562 |
global $wpdb;
|
5563 |
|
5564 |
-
$user_sql =
|
5565 |
-
if ($user_id){
|
5566 |
$user_sql = " AND user_id='{$user_id}' ";
|
5567 |
}
|
5568 |
|
5569 |
-
$date_query
|
5570 |
-
$query_by_status
|
5571 |
$pagination_query = '';
|
5572 |
|
5573 |
/**
|
@@ -5604,40 +5938,40 @@ class Utils {
|
|
5604 |
}
|
5605 |
|
5606 |
if ( ! empty( $per_page ) ) {
|
5607 |
-
$offset = (int) ! empty($offset) ? $offset : 0;
|
5608 |
$pagination_query = " LIMIT {$offset}, {$per_page} ";
|
5609 |
}
|
5610 |
}
|
5611 |
|
5612 |
-
|
5613 |
/**
|
5614 |
* Delete duplicated earning rows that were created due to not checking if already added while creating new.
|
5615 |
* New entries will check before insert.
|
5616 |
-
*
|
5617 |
* @since v1.9.7
|
5618 |
*/
|
5619 |
-
if(!get_option( 'tutor_duplicated_earning_deleted', false )) {
|
5620 |
|
5621 |
// Get the duplicated order IDs
|
5622 |
-
$del_rows
|
5623 |
$order_ids = $wpdb->get_col(
|
5624 |
-
"SELECT order_id
|
5625 |
-
FROM (SELECT order_id, COUNT(order_id) AS cnt
|
5626 |
-
FROM {$wpdb->prefix}tutor_earnings
|
5627 |
-
GROUP BY order_id) t
|
5628 |
WHERE cnt>1"
|
5629 |
);
|
5630 |
|
5631 |
-
if(is_array($order_ids) && count($order_ids)) {
|
5632 |
-
$order_ids_string = implode(',', $order_ids);
|
5633 |
-
$earnings
|
5634 |
"SELECT earning_id, course_id FROM {$wpdb->prefix}tutor_earnings
|
5635 |
-
WHERE order_id IN ({$order_ids_string})
|
5636 |
-
ORDER BY earning_id ASC"
|
|
|
5637 |
|
5638 |
$excluded_first = array();
|
5639 |
-
foreach($earnings as $earning) {
|
5640 |
-
if(!in_array($earning->course_id, $excluded_first)) {
|
5641 |
// Exclude first course ID from deletion
|
5642 |
$excluded_first[] = $earning->course_id;
|
5643 |
continue;
|
@@ -5647,16 +5981,17 @@ class Utils {
|
|
5647 |
}
|
5648 |
}
|
5649 |
|
5650 |
-
if(count($del_rows)) {
|
5651 |
-
$ids = implode(',', $del_rows);
|
5652 |
-
$wpdb->query("DELETE FROM {$wpdb->prefix}tutor_earnings WHERE earning_id IN ({$ids})");
|
5653 |
}
|
5654 |
-
|
5655 |
update_option( 'tutor_duplicated_earning_deleted', true );
|
5656 |
}
|
5657 |
|
5658 |
-
$query = $wpdb->get_results(
|
5659 |
-
|
|
|
5660 |
course.post_title AS course_title
|
5661 |
FROM {$wpdb->prefix}tutor_earnings earning_tbl
|
5662 |
LEFT JOIN {$wpdb->posts} course
|
@@ -5664,17 +5999,20 @@ class Utils {
|
|
5664 |
WHERE 1 = %d {$user_sql} {$date_query} {$query_by_status}
|
5665 |
ORDER BY created_at DESC {$pagination_query}
|
5666 |
",
|
5667 |
-
|
5668 |
-
|
|
|
5669 |
|
5670 |
-
$query_count = (int) $wpdb->get_var(
|
5671 |
-
|
|
|
5672 |
FROM {$wpdb->prefix}tutor_earnings earning_tbl
|
5673 |
WHERE 1 = %d {$user_sql} {$date_query} {$query_by_status}
|
5674 |
ORDER BY created_at DESC
|
5675 |
",
|
5676 |
-
|
5677 |
-
|
|
|
5678 |
|
5679 |
return (object) array(
|
5680 |
'count' => $query_count,
|
@@ -5692,11 +6030,11 @@ class Utils {
|
|
5692 |
* @since v.1.1.2
|
5693 |
*/
|
5694 |
public function tutor_price( $price = 0 ) {
|
5695 |
-
if ( function_exists( 'wc_price') ) {
|
5696 |
return wc_price( $price );
|
5697 |
} elseif ( function_exists( 'edd_currency_filter' ) ) {
|
5698 |
return edd_currency_filter( edd_format_amount( $price ) );
|
5699 |
-
}else{
|
5700 |
return number_format_i18n( $price );
|
5701 |
}
|
5702 |
}
|
@@ -5710,7 +6048,7 @@ class Utils {
|
|
5710 |
*/
|
5711 |
public function currency_symbol() {
|
5712 |
$enable_tutor_edd = tutor_utils()->get_option( 'enable_tutor_edd' );
|
5713 |
-
$monetize_by = $this->get_option('monetize_by');
|
5714 |
|
5715 |
$symbol = '$';
|
5716 |
if ( $enable_tutor_edd && function_exists( 'edd_currency_symbol' ) ) {
|
@@ -5743,7 +6081,7 @@ class Utils {
|
|
5743 |
}
|
5744 |
|
5745 |
/**
|
5746 |
-
* @param int
|
5747 |
* @param array $filter
|
5748 |
*
|
5749 |
* get withdrawal history
|
@@ -5754,11 +6092,11 @@ class Utils {
|
|
5754 |
global $wpdb;
|
5755 |
|
5756 |
$filter = (array) $filter;
|
5757 |
-
extract($filter);
|
5758 |
|
5759 |
-
$query_by_status_sql =
|
5760 |
-
$query_by_user_sql =
|
5761 |
-
$query_by_pagination =
|
5762 |
|
5763 |
if ( ! empty( $status ) ) {
|
5764 |
$status = (array) $status;
|
@@ -5768,8 +6106,9 @@ class Utils {
|
|
5768 |
}
|
5769 |
|
5770 |
if ( ! empty( $per_page ) ) {
|
5771 |
-
if ( empty( $start ) )
|
5772 |
$start = 0;
|
|
|
5773 |
|
5774 |
$query_by_pagination = " LIMIT {$start}, {$per_page} ";
|
5775 |
}
|
@@ -5778,31 +6117,35 @@ class Utils {
|
|
5778 |
$query_by_user_sql = " AND user_id = {$user_id} ";
|
5779 |
}
|
5780 |
|
5781 |
-
$count = (int) $wpdb->get_var(
|
5782 |
-
|
|
|
5783 |
FROM {$wpdb->prefix}tutor_withdraws
|
5784 |
WHERE 1 = %d
|
5785 |
{$query_by_user_sql}
|
5786 |
{$query_by_status_sql}
|
5787 |
",
|
5788 |
-
|
5789 |
-
|
5790 |
-
|
5791 |
-
|
5792 |
-
|
5793 |
-
|
5794 |
-
|
5795 |
-
|
|
|
|
|
5796 |
INNER JOIN {$wpdb->users} user_tbl
|
5797 |
ON withdraw_tbl.user_id = user_tbl.ID
|
5798 |
WHERE 1 = %d
|
5799 |
-
{$query_by_user_sql}
|
5800 |
{$query_by_status_sql}
|
5801 |
ORDER BY created_at DESC
|
5802 |
{$query_by_pagination}
|
5803 |
",
|
5804 |
-
|
5805 |
-
|
|
|
5806 |
|
5807 |
$withdraw_history = array(
|
5808 |
'count' => 0,
|
@@ -5870,12 +6213,12 @@ class Utils {
|
|
5870 |
public function set_flash_msg( $msg = '', $name = 'success' ) {
|
5871 |
global $wp_filesystem;
|
5872 |
if ( ! $wp_filesystem ) {
|
5873 |
-
require_once
|
5874 |
}
|
5875 |
|
5876 |
-
$filename
|
5877 |
$upload_dir = wp_upload_dir();
|
5878 |
-
$dir
|
5879 |
|
5880 |
WP_Filesystem( false, $upload_dir['basedir'], true );
|
5881 |
|
@@ -5900,10 +6243,10 @@ class Utils {
|
|
5900 |
|
5901 |
$upload_dir = wp_get_upload_dir();
|
5902 |
$upload_dir = trailingslashit( $upload_dir['basedir'] );
|
5903 |
-
$msg_name = 'tutor_flash_msg_'
|
5904 |
|
5905 |
-
$msg
|
5906 |
-
$flash_msg_file_name = $upload_dir."tutor/{$msg_name}.txt";
|
5907 |
if ( file_exists( $flash_msg_file_name ) ) {
|
5908 |
$msg = file_get_contents( $flash_msg_file_name );
|
5909 |
unlink( $flash_msg_file_name );
|
@@ -5925,19 +6268,20 @@ class Utils {
|
|
5925 |
$user_id = $this->get_user_id();
|
5926 |
$monetize_by = tutils()->get_option( 'monetize_by' );
|
5927 |
|
5928 |
-
$post_type =
|
5929 |
-
$user_meta =
|
5930 |
|
5931 |
if ( $monetize_by === 'wc' ) {
|
5932 |
-
$post_type =
|
5933 |
-
$user_meta =
|
5934 |
-
}
|
5935 |
-
$post_type =
|
5936 |
-
$user_meta =
|
5937 |
}
|
5938 |
|
5939 |
-
$orders = $wpdb->get_results(
|
5940 |
-
|
|
|
5941 |
FROM {$wpdb->posts}
|
5942 |
INNER JOIN {$wpdb->postmeta} customer
|
5943 |
ON id = customer.post_id
|
@@ -5946,12 +6290,13 @@ class Utils {
|
|
5946 |
ON id = tutor_order.post_id
|
5947 |
AND tutor_order.meta_key = '_is_tutor_order_for_course'
|
5948 |
WHERE post_type = %s
|
5949 |
-
AND customer.meta_value = %d
|
5950 |
ORDER BY {$wpdb->posts}.id DESC
|
5951 |
",
|
5952 |
-
|
5953 |
-
|
5954 |
-
|
|
|
5955 |
|
5956 |
return $orders;
|
5957 |
}
|
@@ -5969,22 +6314,22 @@ class Utils {
|
|
5969 |
$status = str_replace( 'wc-', '', $status );
|
5970 |
$status_name = ucwords( str_replace( '-', ' ', $status ) );
|
5971 |
|
5972 |
-
return
|
5973 |
}
|
5974 |
|
5975 |
/**
|
5976 |
-
* Depricated since v1.9.8
|
5977 |
* This function is redundant and will be removed later
|
5978 |
*/
|
5979 |
public function get_course_id_by_assignment( $assignment_id = 0 ) {
|
5980 |
$assignment_id = $this->get_post_id( $assignment_id );
|
5981 |
-
return $this->get_course_id_by('assignment', $assignment_id);
|
5982 |
}
|
5983 |
|
5984 |
/**
|
5985 |
-
* @param int
|
5986 |
* @param string $option_key
|
5987 |
-
* @param bool
|
5988 |
*
|
5989 |
* @return array|bool|mixed
|
5990 |
*
|
@@ -5994,7 +6339,7 @@ class Utils {
|
|
5994 |
*/
|
5995 |
public function get_assignment_option( $assignment_id = 0, $option_key = '', $default = false ) {
|
5996 |
$assignment_id = $this->get_post_id( $assignment_id );
|
5997 |
-
$get_option_meta = maybe_unserialize( get_post_meta($assignment_id, 'assignment_option', true ) );
|
5998 |
|
5999 |
if ( ! $option_key && ! empty( $get_option_meta ) ) {
|
6000 |
return $get_option_meta;
|
@@ -6023,21 +6368,23 @@ class Utils {
|
|
6023 |
global $wpdb;
|
6024 |
|
6025 |
$assignment_id = $this->get_post_id( $assignment_id );
|
6026 |
-
$user_id
|
6027 |
|
6028 |
-
$is_running_submit = (int) $wpdb->get_var(
|
6029 |
-
|
|
|
6030 |
FROM {$wpdb->comments}
|
6031 |
-
WHERE comment_type = %s
|
6032 |
-
AND comment_approved = %s
|
6033 |
AND user_id = %d
|
6034 |
AND comment_post_ID = %d;
|
6035 |
",
|
6036 |
-
|
6037 |
-
|
6038 |
-
|
6039 |
-
|
6040 |
-
|
|
|
6041 |
|
6042 |
return $is_running_submit;
|
6043 |
}
|
@@ -6058,19 +6405,21 @@ class Utils {
|
|
6058 |
$assignment_id = $this->get_post_id( $assignment_id );
|
6059 |
$user_id = $this->get_user_id( $user_id );
|
6060 |
|
6061 |
-
$has_submitted = $wpdb->get_row(
|
6062 |
-
|
|
|
6063 |
FROM {$wpdb->comments}
|
6064 |
WHERE comment_type = %s
|
6065 |
AND comment_approved = %s
|
6066 |
AND user_id = %d
|
6067 |
AND comment_post_ID = %d;
|
6068 |
",
|
6069 |
-
|
6070 |
-
|
6071 |
-
|
6072 |
-
|
6073 |
-
|
|
|
6074 |
|
6075 |
return $has_submitted;
|
6076 |
}
|
@@ -6080,17 +6429,19 @@ class Utils {
|
|
6080 |
|
6081 |
$assignment_submitted_id = $this->get_post_id( $assignment_submitted_id );
|
6082 |
|
6083 |
-
$submitted_info = $wpdb->get_row(
|
6084 |
-
|
|
|
6085 |
FROM {$wpdb->comments}
|
6086 |
WHERE comment_ID = %d
|
6087 |
AND comment_type = %s
|
6088 |
AND comment_approved = %s;
|
6089 |
",
|
6090 |
-
|
6091 |
-
|
6092 |
-
|
6093 |
-
|
|
|
6094 |
|
6095 |
return $submitted_info;
|
6096 |
}
|
@@ -6102,15 +6453,17 @@ class Utils {
|
|
6102 |
public function get_total_assignments() {
|
6103 |
global $wpdb;
|
6104 |
|
6105 |
-
$count = $wpdb->get_var(
|
6106 |
-
|
|
|
6107 |
FROM {$wpdb->comments}
|
6108 |
WHERE comment_type = %s
|
6109 |
AND comment_approved = %s;
|
6110 |
",
|
6111 |
-
|
6112 |
-
|
6113 |
-
|
|
|
6114 |
|
6115 |
return (int) $count;
|
6116 |
}
|
@@ -6122,15 +6475,17 @@ class Utils {
|
|
6122 |
public function get_assignments() {
|
6123 |
global $wpdb;
|
6124 |
|
6125 |
-
$results = $wpdb->get_results(
|
6126 |
-
|
|
|
6127 |
FROM {$wpdb->comments}
|
6128 |
WHERE comment_type = %s
|
6129 |
AND comment_approved = %s;
|
6130 |
",
|
6131 |
-
|
6132 |
-
|
6133 |
-
|
|
|
6134 |
|
6135 |
return $results;
|
6136 |
}
|
@@ -6149,14 +6504,16 @@ class Utils {
|
|
6149 |
$user_id = $this->get_user_id( $user_id );
|
6150 |
$course_post_type = tutor()->course_post_type;
|
6151 |
|
6152 |
-
$get_assigned_courses_ids = $wpdb->get_col(
|
6153 |
-
|
6154 |
-
|
6155 |
-
|
6156 |
-
|
|
|
6157 |
AND meta.user_id = %d GROUP BY meta_value",
|
6158 |
-
|
6159 |
-
|
|
|
6160 |
|
6161 |
return $get_assigned_courses_ids;
|
6162 |
}
|
@@ -6171,17 +6528,20 @@ class Utils {
|
|
6171 |
* @since v.1.3.4
|
6172 |
*/
|
6173 |
public function get_course_categories( $parent = 0 ) {
|
6174 |
-
$args = apply_filters(
|
6175 |
-
'
|
6176 |
-
|
6177 |
-
|
6178 |
-
|
|
|
|
|
|
|
6179 |
|
6180 |
$terms = get_terms( $args );
|
6181 |
|
6182 |
$children = array();
|
6183 |
foreach ( $terms as $term ) {
|
6184 |
-
$term->children
|
6185 |
$children[ $term->term_id ] = $term;
|
6186 |
}
|
6187 |
|
@@ -6197,17 +6557,20 @@ class Utils {
|
|
6197 |
*
|
6198 |
* @since v.1.9.3
|
6199 |
*/
|
6200 |
-
public function get_course_tags(
|
6201 |
-
$args = apply_filters(
|
6202 |
-
'
|
6203 |
-
|
6204 |
-
|
|
|
|
|
|
|
6205 |
|
6206 |
$terms = get_terms( $args );
|
6207 |
|
6208 |
$children = array();
|
6209 |
foreach ( $terms as $term ) {
|
6210 |
-
$term->children
|
6211 |
$children[ $term->term_id ] = $term;
|
6212 |
}
|
6213 |
|
@@ -6224,11 +6587,14 @@ class Utils {
|
|
6224 |
* @since v.1.3.5
|
6225 |
*/
|
6226 |
public function get_course_categories_term( $parent_id = 0 ) {
|
6227 |
-
$args = apply_filters(
|
6228 |
-
'
|
6229 |
-
|
6230 |
-
|
6231 |
-
|
|
|
|
|
|
|
6232 |
|
6233 |
$terms = get_terms( $args );
|
6234 |
|
@@ -6258,9 +6624,9 @@ class Utils {
|
|
6258 |
public function course_edit_link( $course_id = 0 ) {
|
6259 |
$course_id = $this->get_post_id( $course_id );
|
6260 |
|
6261 |
-
$url = admin_url("post.php?post={$course_id}&action=edit");
|
6262 |
if ( tutor()->has_pro ) {
|
6263 |
-
$url = $this->tutor_dashboard_url(
|
6264 |
}
|
6265 |
|
6266 |
return $url;
|
@@ -6276,7 +6642,7 @@ class Utils {
|
|
6276 |
$in_course_ids = implode( "','", $course_ids );
|
6277 |
|
6278 |
$pagination_query = $date_query = '';
|
6279 |
-
$sort_query
|
6280 |
if ( $this->count( $filter_data ) ) {
|
6281 |
extract( $filter_data );
|
6282 |
|
@@ -6285,7 +6651,7 @@ class Utils {
|
|
6285 |
}
|
6286 |
if ( ! empty( $date_filter ) ) {
|
6287 |
$date_filter = tutor_get_formated_date( 'Y-m-d', $date_filter );
|
6288 |
-
$date_query
|
6289 |
}
|
6290 |
if ( ! empty( $order_filter ) ) {
|
6291 |
$sort_query = " ORDER BY ID {$order_filter} ";
|
@@ -6296,8 +6662,9 @@ class Utils {
|
|
6296 |
}
|
6297 |
}
|
6298 |
|
6299 |
-
$count = (int) $wpdb->get_var(
|
6300 |
-
|
|
|
6301 |
FROM {$wpdb->postmeta} post_meta
|
6302 |
INNER JOIN {$wpdb->posts} assignment
|
6303 |
ON post_meta.post_id = assignment.ID
|
@@ -6306,25 +6673,31 @@ class Utils {
|
|
6306 |
AND post_meta.meta_value IN('$in_course_ids')
|
6307 |
{$date_query}
|
6308 |
",
|
6309 |
-
|
6310 |
-
|
|
|
6311 |
|
6312 |
-
$query = $wpdb->get_results(
|
6313 |
-
|
|
|
6314 |
FROM {$wpdb->postmeta} post_meta
|
6315 |
INNER JOIN {$wpdb->posts} assignment
|
6316 |
ON post_meta.post_id = assignment.ID
|
6317 |
AND post_meta.meta_key = '_tutor_course_id_for_assignments'
|
6318 |
WHERE post_type = %s
|
6319 |
-
AND post_meta.meta_value IN('$in_course_ids')
|
6320 |
{$date_query}
|
6321 |
{$sort_query}
|
6322 |
{$pagination_query}
|
6323 |
",
|
6324 |
-
|
6325 |
-
|
|
|
6326 |
|
6327 |
-
return (object) array(
|
|
|
|
|
|
|
6328 |
}
|
6329 |
|
6330 |
/**
|
@@ -6342,8 +6715,9 @@ class Utils {
|
|
6342 |
|
6343 |
$assignment_post_type = 'tutor_assignments';
|
6344 |
|
6345 |
-
$count = (int) $wpdb->get_var(
|
6346 |
-
|
|
|
6347 |
FROM {$wpdb->postmeta} post_meta
|
6348 |
INNER JOIN {$wpdb->posts} assignment
|
6349 |
ON post_meta.post_id = assignment.ID
|
@@ -6352,12 +6726,14 @@ class Utils {
|
|
6352 |
AND post_meta.meta_value = %d
|
6353 |
ORDER BY ID DESC;
|
6354 |
",
|
6355 |
-
|
6356 |
-
|
6357 |
-
|
|
|
6358 |
|
6359 |
-
$query = $wpdb->get_results(
|
6360 |
-
|
|
|
6361 |
FROM {$wpdb->postmeta} post_meta
|
6362 |
INNER JOIN {$wpdb->posts} assignment
|
6363 |
ON post_meta.post_id = assignment.ID
|
@@ -6366,11 +6742,15 @@ class Utils {
|
|
6366 |
AND post_meta.meta_value = %d
|
6367 |
ORDER BY ID DESC;
|
6368 |
",
|
6369 |
-
|
6370 |
-
|
6371 |
-
|
|
|
6372 |
|
6373 |
-
return (object) array(
|
|
|
|
|
|
|
6374 |
}
|
6375 |
|
6376 |
/**
|
@@ -6408,6 +6788,7 @@ class Utils {
|
|
6408 |
|
6409 |
/**
|
6410 |
* Get total Enrolments
|
|
|
6411 |
* @since v.1.4.0
|
6412 |
*/
|
6413 |
public function get_total_enrolments( $search_term = '' ) {
|
@@ -6415,8 +6796,9 @@ class Utils {
|
|
6415 |
|
6416 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
6417 |
|
6418 |
-
$count = $wpdb->get_var(
|
6419 |
-
|
|
|
6420 |
FROM {$wpdb->posts} enrol
|
6421 |
INNER JOIN {$wpdb->posts} course
|
6422 |
ON enrol.post_parent = course.ID
|
@@ -6425,12 +6807,13 @@ class Utils {
|
|
6425 |
WHERE enrol.post_type = %s
|
6426 |
AND ( enrol.ID LIKE %s OR student.display_name LIKE %s OR student.user_email LIKE %s OR course.post_title LIKE %s );
|
6427 |
",
|
6428 |
-
|
6429 |
-
|
6430 |
-
|
6431 |
-
|
6432 |
-
|
6433 |
-
|
|
|
6434 |
|
6435 |
return (int) $count;
|
6436 |
}
|
@@ -6440,8 +6823,9 @@ class Utils {
|
|
6440 |
|
6441 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
6442 |
|
6443 |
-
$enrolments = $wpdb->get_results(
|
6444 |
-
|
|
|
6445 |
enrol.post_author AS student_id,
|
6446 |
enrol.post_date AS enrol_date,
|
6447 |
enrol.post_title AS enrol_title,
|
@@ -6458,17 +6842,18 @@ class Utils {
|
|
6458 |
ON enrol.post_author = student.ID
|
6459 |
WHERE enrol.post_type = %s
|
6460 |
AND ( enrol.ID LIKE %s OR student.display_name LIKE %s OR student.user_email LIKE %s OR course.post_title LIKE %s )
|
6461 |
-
ORDER BY enrol_id DESC
|
6462 |
LIMIT %d, %d;
|
6463 |
",
|
6464 |
-
|
6465 |
-
|
6466 |
-
|
6467 |
-
|
6468 |
-
|
6469 |
-
|
6470 |
-
|
6471 |
-
|
|
|
6472 |
|
6473 |
return $enrolments;
|
6474 |
}
|
@@ -6510,30 +6895,32 @@ class Utils {
|
|
6510 |
'review' => '',
|
6511 |
);
|
6512 |
|
6513 |
-
$rating = $wpdb->get_row(
|
6514 |
-
|
|
|
6515 |
comment_content AS review
|
6516 |
FROM {$wpdb->comments}
|
6517 |
-
INNER JOIN {$wpdb->commentmeta}
|
6518 |
-
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
6519 |
WHERE {$wpdb->comments}.comment_ID = %d;
|
6520 |
-
",
|
6521 |
-
|
6522 |
-
|
|
|
6523 |
|
6524 |
if ( $rating ) {
|
6525 |
$rating_format = number_format( $rating->rating, 2 );
|
6526 |
|
6527 |
$ratings = array(
|
6528 |
-
'rating'
|
6529 |
-
'review'
|
6530 |
);
|
6531 |
}
|
6532 |
return (object) $ratings;
|
6533 |
}
|
6534 |
|
6535 |
/**
|
6536 |
-
* @param int
|
6537 |
* @param null $key
|
6538 |
* @param bool $default
|
6539 |
*
|
@@ -6550,7 +6937,7 @@ class Utils {
|
|
6550 |
}
|
6551 |
|
6552 |
/**
|
6553 |
-
* @param int
|
6554 |
* @param null $key
|
6555 |
* @param bool $default
|
6556 |
*
|
@@ -6585,7 +6972,7 @@ class Utils {
|
|
6585 |
while ( $topics->have_posts() ) {
|
6586 |
$topics->the_post();
|
6587 |
$topic_id = get_the_ID();
|
6588 |
-
$lessons
|
6589 |
if ( $lessons->have_posts() ) {
|
6590 |
while ( $lessons->have_posts() ) {
|
6591 |
$lessons->the_post();
|
@@ -6593,15 +6980,14 @@ class Utils {
|
|
6593 |
$contents[] = $post;
|
6594 |
}
|
6595 |
}
|
6596 |
-
|
6597 |
}
|
6598 |
}
|
6599 |
|
6600 |
-
if ( tutils()->count( $contents) ) {
|
6601 |
foreach ( $contents as $key => $content ) {
|
6602 |
if ( $current_item->ID == $content->ID ) {
|
6603 |
-
if ( ! empty( $contents[ $key-1 ]->ID ) ) {
|
6604 |
-
return $contents[ $key-1 ]->ID;
|
6605 |
}
|
6606 |
}
|
6607 |
}
|
@@ -6621,15 +7007,17 @@ class Utils {
|
|
6621 |
global $wpdb;
|
6622 |
$post = get_post( $post );
|
6623 |
|
6624 |
-
$course_id = $wpdb->get_var(
|
6625 |
-
|
|
|
6626 |
FROM {$wpdb->posts}
|
6627 |
WHERE ID = %d
|
6628 |
AND post_type = %s
|
6629 |
",
|
6630 |
-
|
6631 |
-
|
6632 |
-
|
|
|
6633 |
|
6634 |
return (int) $course_id;
|
6635 |
}
|
@@ -6648,8 +7036,9 @@ class Utils {
|
|
6648 |
|
6649 |
$course_id = $this->get_post_id( $course_id );
|
6650 |
|
6651 |
-
$contents = $wpdb->get_results(
|
6652 |
-
|
|
|
6653 |
FROM {$wpdb->posts} topic
|
6654 |
INNER JOIN {$wpdb->posts} items
|
6655 |
ON topic.ID = items.post_parent
|
@@ -6658,9 +7047,10 @@ class Utils {
|
|
6658 |
ORDER BY topic.menu_order ASC,
|
6659 |
items.menu_order ASC;
|
6660 |
",
|
6661 |
-
|
6662 |
-
|
6663 |
-
|
|
|
6664 |
|
6665 |
return $contents;
|
6666 |
}
|
@@ -6676,7 +7066,7 @@ class Utils {
|
|
6676 |
*/
|
6677 |
public function get_gradebooks() {
|
6678 |
global $wpdb;
|
6679 |
-
$results = $wpdb->get_results("SELECT * FROM {$wpdb->tutor_gradebooks} ORDER BY grade_point DESC ");
|
6680 |
return $results;
|
6681 |
}
|
6682 |
|
@@ -6700,23 +7090,25 @@ class Utils {
|
|
6700 |
$attempt = false;
|
6701 |
|
6702 |
$quiz_grade_method = get_tutor_option( 'quiz_grade_method', 'highest_grade' );
|
6703 |
-
$from_string
|
6704 |
|
6705 |
-
if ( $quiz_grade_method === 'highest_grade') {
|
6706 |
|
6707 |
$attempt = $wpdb->get_row( $wpdb->prepare( "SELECT * {$from_string} ORDER BY earned_marks DESC LIMIT 1; ", $quiz_id, $user_id ) );
|
6708 |
|
6709 |
-
} elseif ($quiz_grade_method === 'average_grade' ) {
|
6710 |
|
6711 |
-
$attempt = $wpdb->get_row(
|
6712 |
-
|
|
|
6713 |
COUNT(attempt_id) AS attempt_count,
|
6714 |
AVG(total_marks) AS total_marks,
|
6715 |
AVG(earned_marks) AS earned_marks {$from_string}
|
6716 |
",
|
6717 |
-
|
6718 |
-
|
6719 |
-
|
|
|
6720 |
|
6721 |
} elseif ( $quiz_grade_method === 'first_attempt' ) {
|
6722 |
|
@@ -6747,13 +7139,13 @@ class Utils {
|
|
6747 |
|
6748 |
$html = '';
|
6749 |
if ( $is_completed ) {
|
6750 |
-
$html = '<span class="course-completion-status course-completed"><i class="tutor-icon-mark"></i> '.__('Completed', 'tutor').' </span>';
|
6751 |
} else {
|
6752 |
$is_in_progress = tutor_utils()->get_completed_lesson_count_by_course( $course_id, $user_id );
|
6753 |
if ( $is_in_progress ) {
|
6754 |
-
$html = '<span class="course-completion-status course-inprogress"><i class="tutor-icon-refresh-button-1"></i> '.__('In Progress', 'tutor').' </span>';
|
6755 |
} else {
|
6756 |
-
$html = '<span class="course-completion-status course-not-taken"><i class="tutor-icon-spinner"></i> '.__('Not Taken', 'tutor').' </span>';
|
6757 |
}
|
6758 |
}
|
6759 |
return $html;
|
@@ -6787,11 +7179,14 @@ class Utils {
|
|
6787 |
* @since v.1.4.3
|
6788 |
*/
|
6789 |
public function tutor_pages() {
|
6790 |
-
$pages = apply_filters(
|
6791 |
-
'
|
6792 |
-
|
6793 |
-
|
6794 |
-
|
|
|
|
|
|
|
6795 |
|
6796 |
$new_pages = array();
|
6797 |
foreach ( $pages as $key => $page ) {
|
@@ -6808,12 +7203,12 @@ class Utils {
|
|
6808 |
}
|
6809 |
|
6810 |
$new_pages[] = array(
|
6811 |
-
'option_key'
|
6812 |
-
'page_name'
|
6813 |
-
'wp_page_name'
|
6814 |
-
'page_id'
|
6815 |
-
'page_exists'
|
6816 |
-
'page_visible'
|
6817 |
);
|
6818 |
}
|
6819 |
|
@@ -6831,15 +7226,15 @@ class Utils {
|
|
6831 |
*/
|
6832 |
public function get_course_prev_next_contents_by_id( $content_id = 0 ) {
|
6833 |
|
6834 |
-
$course_id = $this->get_course_id_by_content($content_id);
|
6835 |
-
$course_contents = $this->get_course_contents_by_id($course_id);
|
6836 |
$previous_id = 0;
|
6837 |
$next_id = 0;
|
6838 |
|
6839 |
if ( $this->count( $course_contents ) ) {
|
6840 |
$ids = wp_list_pluck( $course_contents, 'ID' );
|
6841 |
|
6842 |
-
$i=0;
|
6843 |
foreach ( $ids as $key => $id ) {
|
6844 |
$previous_i = $key - 1;
|
6845 |
$next_i = $key + 1;
|
@@ -6856,14 +7251,17 @@ class Utils {
|
|
6856 |
}
|
6857 |
}
|
6858 |
|
6859 |
-
return (object)
|
|
|
|
|
|
|
6860 |
}
|
6861 |
|
6862 |
/**
|
6863 |
* Get a subset of the items from the given array.
|
6864 |
*
|
6865 |
-
* @param array
|
6866 |
-
* @param array|string
|
6867 |
*
|
6868 |
* @return array|bool
|
6869 |
*
|
@@ -6887,28 +7285,30 @@ class Utils {
|
|
6887 |
*
|
6888 |
* @since v.1.6.4
|
6889 |
*/
|
6890 |
-
public function is_instructor_of_this_course( $instructor_id=0, $course_id=0 ) {
|
6891 |
global $wpdb;
|
6892 |
|
6893 |
-
$instructor_id
|
6894 |
-
$course_id
|
6895 |
|
6896 |
if ( ! $instructor_id || ! $course_id ) {
|
6897 |
return false;
|
6898 |
}
|
6899 |
|
6900 |
-
$instructor = $wpdb->get_col(
|
6901 |
-
|
|
|
6902 |
FROM {$wpdb->usermeta}
|
6903 |
WHERE user_id = %d
|
6904 |
AND meta_key = '_tutor_instructor_course_id'
|
6905 |
AND meta_value = %d
|
6906 |
",
|
6907 |
-
|
6908 |
-
|
6909 |
-
|
6910 |
-
|
6911 |
-
|
|
|
6912 |
return $instructor;
|
6913 |
}
|
6914 |
|
@@ -6925,29 +7325,32 @@ class Utils {
|
|
6925 |
* @since v.1.6.6
|
6926 |
*/
|
6927 |
public function user_profile_completion( $user_id = 0 ) {
|
6928 |
-
$user_id
|
6929 |
-
$instructor
|
6930 |
$instructor_status = get_user_meta( $user_id, '_tutor_instructor_status', true );
|
6931 |
|
6932 |
-
$required_fields = apply_filters(
|
6933 |
-
'
|
6934 |
-
|
6935 |
-
|
6936 |
-
|
6937 |
-
|
|
|
|
|
|
|
6938 |
|
6939 |
-
if ( 'approved' !== $instructor_status && array_key_exists(
|
6940 |
-
unset( $required_fields[
|
6941 |
}
|
6942 |
|
6943 |
$empty_fields = array();
|
6944 |
foreach ( $required_fields as $key => $field ) {
|
6945 |
$value = get_user_meta( $user_id, $key, true );
|
6946 |
-
if (
|
6947 |
array_push( $empty_fields, $field );
|
6948 |
}
|
6949 |
}
|
6950 |
-
|
6951 |
$total_empty_fields = count( $empty_fields );
|
6952 |
$total_required_fields = count( $required_fields );
|
6953 |
$signup_point = apply_filters( 'tutor_profile_completion_signup_point', 50 );
|
@@ -6955,9 +7358,9 @@ class Utils {
|
|
6955 |
if ( $total_empty_fields == 0 ) {
|
6956 |
$progress = 100;
|
6957 |
} else {
|
6958 |
-
$completed_field = $total_required_fields
|
6959 |
$per_field_point = $signup_point / $total_required_fields;
|
6960 |
-
$progress = $signup_point + ceil($per_field_point * $completed_field);
|
6961 |
}
|
6962 |
|
6963 |
$return = array(
|
@@ -6980,8 +7383,9 @@ class Utils {
|
|
6980 |
public function get_enrolment_by_enrol_id( $enrol_id = 0 ) {
|
6981 |
global $wpdb;
|
6982 |
|
6983 |
-
$enrolment = $wpdb->get_row(
|
6984 |
-
|
|
|
6985 |
enrol.post_author AS student_id,
|
6986 |
enrol.post_date AS enrol_date,
|
6987 |
enrol.post_title AS enrol_title,
|
@@ -6997,7 +7401,10 @@ class Utils {
|
|
6997 |
INNER JOIN {$wpdb->users} student
|
6998 |
ON enrol.post_author = student.id
|
6999 |
WHERE enrol.id = %d;
|
7000 |
-
",
|
|
|
|
|
|
|
7001 |
|
7002 |
if ( $enrolment ) {
|
7003 |
return $enrolment;
|
@@ -7011,19 +7418,21 @@ class Utils {
|
|
7011 |
global $wpdb;
|
7012 |
$course_id = $this->get_post_id( $course_id );
|
7013 |
|
7014 |
-
$student_data = $wpdb->get_results(
|
7015 |
-
|
|
|
7016 |
FROM {$wpdb->posts} enrol
|
7017 |
INNER JOIN {$wpdb->users} student
|
7018 |
ON enrol.post_author = student.id
|
7019 |
WHERE enrol.post_type = %s
|
7020 |
AND enrol.post_parent = %d
|
7021 |
-
AND enrol.post_status = %s;
|
7022 |
",
|
7023 |
-
|
7024 |
-
|
7025 |
-
|
7026 |
-
|
|
|
7027 |
|
7028 |
return array_column( $student_data, $field_name );
|
7029 |
}
|
@@ -7032,7 +7441,7 @@ class Utils {
|
|
7032 |
* @param int $course_id
|
7033 |
*
|
7034 |
* @return array
|
7035 |
-
*
|
7036 |
* @since v1.6.9
|
7037 |
*
|
7038 |
* Get students email by course id
|
@@ -7045,38 +7454,40 @@ class Utils {
|
|
7045 |
*requie post id & user id
|
7046 |
*return single comment post
|
7047 |
*/
|
7048 |
-
public function get_single_comment_user_post_id( $post_id
|
7049 |
global $wpdb;
|
7050 |
-
$table = $wpdb->prefix .
|
7051 |
-
$query = $wpdb->get_row(
|
7052 |
-
|
|
|
7053 |
FROM $table
|
7054 |
WHERE comment_post_ID = %d
|
7055 |
AND user_id = %d
|
7056 |
LIMIT 1
|
7057 |
",
|
7058 |
-
|
7059 |
-
|
7060 |
-
|
|
|
7061 |
return $query ? $query : false;
|
7062 |
}
|
7063 |
-
|
7064 |
/**
|
7065 |
* @param int $course_id
|
7066 |
*
|
7067 |
* @return bool
|
7068 |
-
*
|
7069 |
* @since v1.7.5
|
7070 |
*
|
7071 |
* Check if course is in wc cart
|
7072 |
*/
|
7073 |
-
public function is_course_added_to_cart( $course_or_product_id = 0, $is_product_id=false ) {
|
7074 |
-
|
7075 |
-
switch( $this->get_option( 'monetize_by' ) ) {
|
7076 |
case 'wc':
|
7077 |
global $woocommerce;
|
7078 |
$product_id = $is_product_id ? $course_or_product_id : $this->get_course_product_id( $course_or_product_id );
|
7079 |
-
|
7080 |
if ( $woocommerce->cart ) {
|
7081 |
foreach ( $woocommerce->cart->get_cart() as $key => $val ) {
|
7082 |
if ( $product_id == $val['product_id'] ) {
|
@@ -7092,7 +7503,7 @@ class Utils {
|
|
7092 |
* @param int $user_id
|
7093 |
*
|
7094 |
* @return bool
|
7095 |
-
*
|
7096 |
* @since v1.7.5
|
7097 |
*
|
7098 |
* Get profile pic url
|
@@ -7101,7 +7512,7 @@ class Utils {
|
|
7101 |
$cover_photo_src = tutor()->url . 'assets/images/cover-photo.jpg';
|
7102 |
$cover_photo_id = get_user_meta( $user_id, '_tutor_cover_photo', true );
|
7103 |
if ( $cover_photo_id ) {
|
7104 |
-
$url
|
7105 |
! empty( $url ) ? $cover_photo_src = $url : 0;
|
7106 |
}
|
7107 |
|
@@ -7110,7 +7521,7 @@ class Utils {
|
|
7110 |
|
7111 |
/**
|
7112 |
* @return int
|
7113 |
-
*
|
7114 |
* @since v1.7.9
|
7115 |
*
|
7116 |
* Return the course ID by lession, quiz, answer etc.
|
@@ -7120,49 +7531,57 @@ class Utils {
|
|
7120 |
$course_id = null;
|
7121 |
|
7122 |
switch ( $content ) {
|
7123 |
-
case 'course'
|
7124 |
$course_id = $object_id;
|
7125 |
break;
|
7126 |
|
7127 |
-
case 'topic'
|
7128 |
-
case 'announcement'
|
7129 |
-
$course_id = $wpdb->get_var(
|
7130 |
-
|
7131 |
-
|
|
|
7132 |
WHERE ID=%d
|
7133 |
LIMIT 1",
|
7134 |
-
|
|
|
|
|
7135 |
break;
|
7136 |
-
|
7137 |
-
case 'lesson'
|
7138 |
-
case 'quiz'
|
7139 |
-
case 'assignment'
|
7140 |
-
$course_id = $wpdb->get_var(
|
7141 |
-
|
7142 |
-
|
|
|
7143 |
WHERE ID = (SELECT post_parent FROM {$wpdb->posts} WHERE ID = %d);
|
7144 |
",
|
7145 |
-
|
7146 |
-
|
|
|
7147 |
break;
|
7148 |
-
|
7149 |
-
case 'question'
|
7150 |
-
$course_id = $wpdb->get_var(
|
7151 |
-
|
|
|
7152 |
FROM {$wpdb->posts} topic
|
7153 |
-
INNER JOIN {$wpdb->posts} quiz
|
7154 |
ON quiz.post_parent=topic.ID
|
7155 |
INNER JOIN {$wpdb->prefix}tutor_quiz_questions question
|
7156 |
ON question.quiz_id=quiz.ID
|
7157 |
WHERE question.question_id = %d;
|
7158 |
",
|
7159 |
-
|
7160 |
-
|
|
|
7161 |
break;
|
7162 |
-
|
7163 |
-
case 'quiz_answer'
|
7164 |
-
$course_id = $wpdb->get_var(
|
7165 |
-
|
|
|
7166 |
FROM {$wpdb->posts} topic
|
7167 |
INNER JOIN {$wpdb->posts} quiz
|
7168 |
ON quiz.post_parent=topic.ID
|
@@ -7172,39 +7591,46 @@ class Utils {
|
|
7172 |
ON answer.belongs_question_id=question.question_id
|
7173 |
WHERE answer.answer_id = %d;
|
7174 |
",
|
7175 |
-
|
7176 |
-
|
|
|
7177 |
break;
|
7178 |
-
|
7179 |
-
case 'attempt'
|
7180 |
-
$course_id = $wpdb->get_var(
|
7181 |
-
|
|
|
7182 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
7183 |
WHERE attempt_id=%d;
|
7184 |
",
|
7185 |
-
|
7186 |
-
|
|
|
7187 |
break;
|
7188 |
|
7189 |
-
case 'attempt_answer'
|
7190 |
-
$course_id = $wpdb->get_var(
|
7191 |
-
|
7192 |
-
|
|
|
7193 |
WHERE attempt_id = (SELECT quiz_attempt_id FROM {$wpdb->prefix}tutor_quiz_attempt_answers WHERE attempt_answer_id=%d)
|
7194 |
",
|
7195 |
-
|
7196 |
-
|
|
|
7197 |
break;
|
7198 |
|
7199 |
-
case 'review'
|
7200 |
-
case 'qa_question'
|
7201 |
-
$course_id = $wpdb->get_var(
|
7202 |
-
|
|
|
7203 |
FROM {$wpdb->comments}
|
7204 |
WHERE comment_ID = %d;
|
7205 |
",
|
7206 |
-
|
7207 |
-
|
|
|
7208 |
break;
|
7209 |
}
|
7210 |
|
@@ -7213,28 +7639,31 @@ class Utils {
|
|
7213 |
|
7214 |
/**
|
7215 |
* @return bool
|
7216 |
-
*
|
7217 |
* @since v1.7.7
|
7218 |
*
|
7219 |
-
* Check if user can create, edit, delete various tutor contents such as lesson, quiz, answer etc.
|
7220 |
*/
|
7221 |
-
public function can_user_manage( $content, $object_id, $user_id=0, $allow_current_admin=true ) {
|
7222 |
-
|
7223 |
-
if( $allow_current_admin && current_user_can( 'administrator' ) ) {
|
7224 |
// Admin has access to everything
|
7225 |
return true;
|
7226 |
}
|
7227 |
|
7228 |
$course_id = $this->get_course_id_by( $content, $object_id );
|
7229 |
|
7230 |
-
if( $course_id ) {
|
7231 |
-
|
7232 |
$instructors = $this->get_instructors_by_course( $course_id );
|
7233 |
-
$instructor_ids = is_array( $instructors ) ? array_map(
|
7234 |
-
|
7235 |
-
|
7236 |
-
|
7237 |
-
|
|
|
|
|
|
|
7238 |
$is_listed = in_array( $user_id, $instructor_ids );
|
7239 |
|
7240 |
return $is_listed;
|
@@ -7245,15 +7674,15 @@ class Utils {
|
|
7245 |
|
7246 |
/**
|
7247 |
* @return bool
|
7248 |
-
*
|
7249 |
* @since v1.7.9
|
7250 |
*
|
7251 |
* Check if user has access for content like lesson, quiz, assignment etc.
|
7252 |
*/
|
7253 |
-
public function has_enrolled_content_access( $content, $object_id=0, $user_id=0 ) {
|
7254 |
-
$user_id
|
7255 |
-
$object_id
|
7256 |
-
$course_id
|
7257 |
$course_content_access = (bool) get_tutor_option( 'course_content_access_for_ia' );
|
7258 |
|
7259 |
do_action( 'tutor_before_enrolment_check', $course_id, $user_id );
|
@@ -7264,8 +7693,8 @@ class Utils {
|
|
7264 |
if ( $course_content_access && ( current_user_can( 'administrator' ) || current_user_can( tutor()->instructor_role ) ) ) {
|
7265 |
return true;
|
7266 |
}
|
7267 |
-
//Check Lesson edit access to support page builders (eg: Oxygen)
|
7268 |
-
if ( current_user_can(tutor()->instructor_role) && tutils()->has_lesson_edit_access() ) {
|
7269 |
return true;
|
7270 |
}
|
7271 |
|
@@ -7274,19 +7703,19 @@ class Utils {
|
|
7274 |
|
7275 |
/**
|
7276 |
* @return date
|
7277 |
-
*
|
7278 |
* @since v1.8.0
|
7279 |
*
|
7280 |
* Return the assignment deadline date based on duration and assignment creation date
|
7281 |
*/
|
7282 |
-
public function get_assignment_deadline_date( $assignment_id, $format=null, $fallback=null ) {
|
7283 |
-
|
7284 |
-
! $format ? $format='j F, Y, g:i a' : 0;
|
7285 |
|
7286 |
$value = $this->get_assignment_option( $assignment_id, 'time_duration.value' );
|
7287 |
$time = $this->get_assignment_option( $assignment_id, 'time_duration.time' );
|
7288 |
-
|
7289 |
-
if (
|
7290 |
return $fallback;
|
7291 |
}
|
7292 |
|
@@ -7300,7 +7729,7 @@ class Utils {
|
|
7300 |
|
7301 |
/**
|
7302 |
* @return array
|
7303 |
-
*
|
7304 |
* @since v1.8.2
|
7305 |
*
|
7306 |
* Get earning chart data
|
@@ -7318,28 +7747,30 @@ class Utils {
|
|
7318 |
|
7319 |
$datesPeriod = array();
|
7320 |
foreach ( $period as $dt ) {
|
7321 |
-
$datesPeriod[ $dt->format(
|
7322 |
}
|
7323 |
|
7324 |
// Get statuses
|
7325 |
$complete_status = tutor_utils()->get_earnings_completed_statuses();
|
7326 |
$statuses = $complete_status;
|
7327 |
-
$complete_status = "'" . implode( "','", $complete_status) . "'";
|
7328 |
-
|
7329 |
-
$salesQuery = $wpdb->get_results(
|
7330 |
-
|
7331 |
-
|
7332 |
-
|
7333 |
-
|
7334 |
-
|
|
|
7335 |
AND (created_at BETWEEN %s AND %s)
|
7336 |
GROUP BY date_format
|
7337 |
ORDER BY created_at ASC;
|
7338 |
-
",
|
7339 |
-
|
7340 |
-
|
7341 |
-
|
7342 |
-
|
|
|
7343 |
|
7344 |
$total_earning = wp_list_pluck( $salesQuery, 'total_earning' );
|
7345 |
$queried_date = wp_list_pluck( $salesQuery, 'date_format' );
|
@@ -7348,27 +7779,27 @@ class Utils {
|
|
7348 |
|
7349 |
foreach ( $chartData as $key => $salesCount ) {
|
7350 |
unset( $chartData[ $key ] );
|
7351 |
-
$formatDate
|
7352 |
$chartData[ $formatDate ] = $salesCount;
|
7353 |
}
|
7354 |
|
7355 |
-
$statements = tutor_utils()->get_earning_statements( $user_id, compact('start_date', 'end_date', 'statuses' ) );
|
7356 |
$earning_sum = tutor_utils()->get_earning_sum( $user_id, compact( 'start_date', 'end_date' ) );
|
7357 |
|
7358 |
return array(
|
7359 |
-
'chartData' => $chartData,
|
7360 |
'statements' => $statements,
|
7361 |
'statuses' => $statuses,
|
7362 |
'begin' => $begin,
|
7363 |
'end' => $end,
|
7364 |
'earning_sum' => $earning_sum,
|
7365 |
-
'datesPeriod' => $datesPeriod
|
7366 |
);
|
7367 |
}
|
7368 |
|
7369 |
/**
|
7370 |
* @return array
|
7371 |
-
*
|
7372 |
* @since v1.8.2
|
7373 |
*
|
7374 |
* Get earning chart data yearly
|
@@ -7378,21 +7809,23 @@ class Utils {
|
|
7378 |
|
7379 |
$complete_status = tutor_utils()->get_earnings_completed_statuses();
|
7380 |
$statuses = $complete_status;
|
7381 |
-
$complete_status = "'" . implode( "','", $complete_status) . "'";
|
7382 |
-
|
7383 |
-
$salesQuery = $wpdb->get_results(
|
7384 |
-
|
7385 |
-
|
7386 |
-
|
7387 |
-
|
7388 |
-
|
7389 |
-
AND
|
7390 |
-
|
|
|
7391 |
ORDER BY MONTH(created_at) ASC;
|
7392 |
-
",
|
7393 |
-
|
7394 |
-
|
7395 |
-
|
|
|
7396 |
|
7397 |
$total_earning = wp_list_pluck( $salesQuery, 'total_earning' );
|
7398 |
$months = wp_list_pluck( $salesQuery, 'month_name' );
|
@@ -7404,24 +7837,24 @@ class Utils {
|
|
7404 |
* Format yearly
|
7405 |
*/
|
7406 |
$emptyMonths = array();
|
7407 |
-
for ( $m=1; $m <= 12; $m++ ) {
|
7408 |
-
$emptyMonths[ date('F', mktime( 0, 0, 0, $m, 1, date( 'Y' ) ) ) ] = 0;
|
7409 |
}
|
7410 |
|
7411 |
$chartData = array_merge( $emptyMonths, $monthWiseSales );
|
7412 |
-
$statements = tutor_utils()->get_earning_statements( $user_id, compact('year', 'dataFor', 'statuses' ) );
|
7413 |
$earning_sum = tutor_utils()->get_earning_sum( $user_id, compact( 'year', 'dataFor' ) );
|
7414 |
|
7415 |
-
return
|
7416 |
'chartData' => $chartData,
|
7417 |
'statements' => $statements,
|
7418 |
-
'earning_sum' => $earning_sum
|
7419 |
-
|
7420 |
}
|
7421 |
|
7422 |
/**
|
7423 |
* @return object
|
7424 |
-
*
|
7425 |
* @since v1.8.4
|
7426 |
*
|
7427 |
* Return object from vendor package
|
@@ -7429,163 +7862,164 @@ class Utils {
|
|
7429 |
function get_package_object() {
|
7430 |
|
7431 |
$params = func_get_args();
|
7432 |
-
|
7433 |
-
$is_pro
|
7434 |
-
$class
|
7435 |
$class_args = array_slice( $params, 2 );
|
7436 |
-
$root_path
|
7437 |
|
7438 |
require_once $root_path . '/vendor/autoload.php';
|
7439 |
-
|
7440 |
$reflector = new \ReflectionClass( $class );
|
7441 |
-
$object
|
7442 |
|
7443 |
return $object;
|
7444 |
}
|
7445 |
|
7446 |
/**
|
7447 |
* @return boolean
|
7448 |
-
*
|
7449 |
* @since v1.8.9
|
7450 |
-
*
|
7451 |
* Check if user has specific role
|
7452 |
*/
|
7453 |
-
public function has_user_role($roles, $user_id = 0) {
|
7454 |
-
|
7455 |
-
|
7456 |
-
!is_array($roles) ? $roles = array($roles) : 0;
|
7457 |
-
|
7458 |
-
$user = get_userdata($user_id);
|
7459 |
-
$role_list = (is_object($user) && is_array($user->roles)) ? $user->roles : array();
|
7460 |
|
7461 |
-
$
|
|
|
7462 |
|
7463 |
-
|
|
|
|
|
7464 |
}
|
7465 |
|
7466 |
/**
|
7467 |
* @return boolean
|
7468 |
-
*
|
7469 |
* @since v1.8.9
|
7470 |
-
*
|
7471 |
* Check if user can edit course
|
7472 |
*/
|
7473 |
-
public function can_user_edit_course($user_id, $course_id)
|
7474 |
-
|
7475 |
-
return $this->has_user_role(array('administrator', 'editor')) || $this->is_instructor_of_this_course($user_id, $course_id);
|
7476 |
}
|
7477 |
|
7478 |
-
|
7479 |
/**
|
7480 |
* @return boolean
|
7481 |
-
*
|
7482 |
* @since v1.9.0
|
7483 |
-
*
|
7484 |
* Check if course member limit full
|
7485 |
*/
|
7486 |
-
public function is_course_fully_booked($course_id = 0) {
|
|
|
|
|
|
|
7487 |
|
7488 |
-
$total_enrolled = $this->count_enrolled_users_by_course($course_id);
|
7489 |
-
$maximum_students = (int) $this->get_course_settings($course_id, 'maximum_students');
|
7490 |
-
|
7491 |
return $maximum_students && $maximum_students <= $total_enrolled;
|
7492 |
}
|
7493 |
|
7494 |
/**
|
7495 |
* @return boolean
|
7496 |
-
*
|
7497 |
* @since v1.9.2
|
7498 |
-
*
|
7499 |
* Check if current screen is under tutor dashboard
|
7500 |
*/
|
7501 |
-
public function is_tutor_dashboard($subpage = null) {
|
7502 |
|
7503 |
// To Do: Add subpage check later
|
7504 |
|
7505 |
-
if(function_exists('is_admin') && is_admin()) {
|
7506 |
$screen = get_current_screen();
|
7507 |
return is_object( $screen ) && $screen->parent_base == 'tutor';
|
7508 |
}
|
7509 |
-
|
7510 |
return false;
|
7511 |
}
|
7512 |
|
7513 |
/**
|
7514 |
* @return boolean
|
7515 |
-
*
|
7516 |
* @since v1.9.4
|
7517 |
-
*
|
7518 |
* Check if current screen tutor frontend dashboard
|
7519 |
*/
|
7520 |
-
public function is_tutor_frontend_dashboard($subpage = null) {
|
7521 |
|
7522 |
global $wp_query;
|
7523 |
-
if ($wp_query->is_page) {
|
7524 |
-
$dashboard_page = tutor_utils()->array_get('tutor_dashboard_page', $wp_query->query_vars);
|
7525 |
|
7526 |
-
if($subpage && $dashboard_page == $subpage) {
|
7527 |
return true;
|
7528 |
}
|
7529 |
|
7530 |
-
if($wp_query->queried_object && $wp_query->queried_object->ID) {
|
7531 |
-
return $wp_query->queried_object->ID == tutor_utils()->get_option('tutor_dashboard_page_id');
|
7532 |
}
|
7533 |
}
|
7534 |
|
7535 |
return false;
|
7536 |
}
|
7537 |
|
7538 |
-
public function get_unique_slug($slug, $post_type=null, $num_assigned=false) {
|
7539 |
|
7540 |
global $wpdb;
|
7541 |
-
$existing_slug = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM {$wpdb->posts} WHERE post_name=%s" . ($post_type ? " AND post_type='{$post_type}' LIMIT 1" :
|
7542 |
|
7543 |
-
if(
|
7544 |
return $slug;
|
7545 |
}
|
7546 |
|
7547 |
-
if(
|
7548 |
$new_slug = $slug . '-' . 2;
|
7549 |
} else {
|
7550 |
-
$new_slug = explode('-', $slug);
|
7551 |
-
$number
|
7552 |
-
|
7553 |
-
array_pop($new_slug);
|
7554 |
|
7555 |
-
|
|
|
|
|
7556 |
}
|
7557 |
|
7558 |
-
return $this->get_unique_slug($new_slug, $post_type, true);
|
7559 |
}
|
7560 |
|
7561 |
-
public function get_course_content_ids_by($content_type, $ancestor_type, $ancestor_ids) {
|
7562 |
-
global $wpdb;
|
7563 |
$ids = array();
|
7564 |
|
7565 |
// Convert single id to array
|
7566 |
-
!is_array($ancestor_ids) ? $ancestor_ids=array($ancestor_ids) : 0;
|
7567 |
-
$ancestor_ids
|
7568 |
|
7569 |
-
switch($content_type) {
|
7570 |
|
7571 |
// Get lesson, quiz, assignment IDs
|
7572 |
-
case tutor()->lesson_post_type
|
7573 |
-
case 'tutor_quiz'
|
7574 |
-
case 'tutor_assignments'
|
7575 |
-
switch($ancestor_type) {
|
7576 |
|
7577 |
// Get lesson, quiz, assignment IDs by course ID
|
7578 |
-
case tutor()->course_post_type
|
7579 |
-
$content_ids = $wpdb->get_col(
|
7580 |
-
|
7581 |
-
|
|
|
7582 |
INNER JOIN {$wpdb->posts} content ON topic.ID=content.post_parent
|
7583 |
WHERE course.ID IN ({$ancestor_ids}) AND content.post_type=%s",
|
7584 |
-
|
7585 |
-
|
|
|
7586 |
|
7587 |
// Assign id array to the variable
|
7588 |
-
is_array($content_ids) ? $ids
|
7589 |
break 2;
|
7590 |
}
|
7591 |
}
|
@@ -7595,82 +8029,88 @@ class Utils {
|
|
7595 |
|
7596 |
/**
|
7597 |
* Custom Pagination for Tutor Shortcode
|
7598 |
-
*
|
7599 |
* @param int $total_num_pages
|
7600 |
-
*
|
7601 |
* @return void
|
7602 |
*/
|
7603 |
public function tutor_custom_pagination( $total_num_pages = 1 ) {
|
7604 |
|
7605 |
do_action( 'tutor_course/archive/pagination/before' ); ?>
|
7606 |
-
|
7607 |
<div class="tutor-pagination-wrap">
|
7608 |
<?php
|
7609 |
$big = 999999999; // need an unlikely integer
|
7610 |
-
|
7611 |
-
echo paginate_links(
|
7612 |
-
|
7613 |
-
|
7614 |
-
|
7615 |
-
|
7616 |
-
|
|
|
|
|
7617 |
?>
|
7618 |
</div>
|
7619 |
-
|
7620 |
-
<?php
|
|
|
7621 |
}
|
7622 |
|
7623 |
/**
|
7624 |
* Get all courses along with topics & course materials for current student
|
7625 |
-
*
|
7626 |
* @since 1.9.10
|
7627 |
-
*
|
7628 |
* @return array
|
7629 |
*/
|
7630 |
public function course_with_materials(): array {
|
7631 |
-
$user_id
|
7632 |
$enrolled_courses = $this->get_enrolled_courses_by_user( $user_id );
|
7633 |
|
7634 |
if ( false === $enrolled_courses ) {
|
7635 |
-
return
|
7636 |
}
|
7637 |
-
$data =
|
7638 |
foreach ( $enrolled_courses->posts as $key => $course ) {
|
7639 |
-
//push courses
|
7640 |
-
array_push($data,
|
7641 |
$topics = $this->get_topics( $course->ID );
|
7642 |
|
7643 |
-
if ( !is_null( $topics) || count( $topics->posts ) ) {
|
7644 |
foreach ( $topics->posts as $topic_key => $topic ) {
|
7645 |
$materials = $this->get_course_contents_by_topic( $topic->ID, -1 );
|
7646 |
-
if ( count( $materials->posts ) || !is_null( $materials->posts ) ) {
|
7647 |
$topic->materials = $materials->posts;
|
7648 |
}
|
7649 |
-
//push topics
|
7650 |
-
array_push( $data[$key]['course'],
|
7651 |
}
|
7652 |
}
|
7653 |
-
|
7654 |
}
|
7655 |
return $data;
|
7656 |
}
|
7657 |
|
7658 |
-
public function get_course_duration($course_id, $return_array, $texts = array(
|
7659 |
-
|
7660 |
-
|
7661 |
-
|
7662 |
-
|
|
|
|
|
|
|
|
|
7663 |
|
7664 |
-
if($return_array) {
|
7665 |
return array(
|
7666 |
-
'duration'
|
7667 |
-
'durationHours'
|
7668 |
'durationMinutes' => $durationMinutes,
|
7669 |
'durationSeconds' => $durationSeconds,
|
7670 |
);
|
7671 |
}
|
7672 |
|
7673 |
-
if(
|
7674 |
return '';
|
7675 |
}
|
7676 |
|
@@ -7678,4 +8118,4 @@ class Utils {
|
|
7678 |
$durationMinutes . $texts['m'] . ' ' .
|
7679 |
$durationSeconds . $texts['s'];
|
7680 |
}
|
7681 |
-
}
|
1 |
<?php
|
2 |
/**
|
3 |
* Tutor Utils Helper functions
|
4 |
+
*
|
5 |
* @package TUTOR
|
6 |
*
|
7 |
* @since v.1.0.0
|
9 |
|
10 |
namespace TUTOR;
|
11 |
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
|
16 |
class Utils {
|
17 |
/**
|
25 |
* @since v.1.0.0
|
26 |
*/
|
27 |
public function get_option( $key = null, $default = false ) {
|
28 |
+
$option = (array) maybe_unserialize( get_option( 'tutor_option' ) );
|
29 |
|
30 |
if ( empty( $option ) || ! is_array( $option ) ) {
|
31 |
return $default;
|
34 |
return $option;
|
35 |
}
|
36 |
if ( array_key_exists( $key, $option ) ) {
|
37 |
+
return apply_filters( $key, $option[ $key ] );
|
38 |
}
|
39 |
+
// Access array value via dot notation, such as option->get('value.subvalue')
|
40 |
+
if ( strpos( $key, '.' ) ) {
|
41 |
$option_key_array = explode( '.', $key );
|
42 |
|
43 |
$new_option = $option;
|
44 |
foreach ( $option_key_array as $dotKey ) {
|
45 |
+
if ( isset( $new_option[ $dotKey ] ) ) {
|
46 |
+
$new_option = $new_option[ $dotKey ];
|
47 |
+
} else {
|
48 |
return $default;
|
49 |
}
|
50 |
}
|
63 |
* @since v.1.0.0
|
64 |
*/
|
65 |
public function update_option( $key = null, $value = false ) {
|
66 |
+
$option = (array) maybe_unserialize( get_option( 'tutor_option' ) );
|
67 |
+
$option[ $key ] = $value;
|
68 |
update_option( 'tutor_option', $option );
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
+
* @param null $key
|
73 |
* @param array $array
|
74 |
*
|
75 |
* @return array|bool|mixed
|
82 |
*/
|
83 |
public function avalue_dot( $key = null, $array = array(), $default = false ) {
|
84 |
$array = (array) $array;
|
85 |
+
if ( ! $key || ! count( $array ) ) {
|
86 |
return $default;
|
87 |
}
|
88 |
$option_key_array = explode( '.', $key );
|
90 |
$value = $array;
|
91 |
|
92 |
foreach ( $option_key_array as $dotKey ) {
|
93 |
+
if ( isset( $value[ $dotKey ] ) ) {
|
94 |
+
$value = $value[ $dotKey ];
|
95 |
} else {
|
96 |
return $default;
|
97 |
}
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
+
* @param null $key
|
104 |
* @param array $array
|
105 |
*
|
106 |
* @return array|bool|mixed
|
128 |
|
129 |
do_action( 'tutor_utils/get_pages/before' );
|
130 |
|
131 |
+
$pages = array();
|
132 |
$wp_pages = get_pages();
|
133 |
|
134 |
+
if ( is_array( $wp_pages ) && count( $wp_pages ) ) {
|
135 |
+
foreach ( $wp_pages as $page ) {
|
136 |
+
$pages[ $page->ID ] = $page->post_title;
|
137 |
}
|
138 |
}
|
139 |
+
|
140 |
do_action( 'tutor_utils/get_pages/after' );
|
141 |
|
142 |
return $pages;
|
153 |
$course_post_type = tutor()->course_post_type;
|
154 |
$course_page_url = trailingslashit( home_url() ) . $course_post_type;
|
155 |
|
156 |
+
$course_archive_page = $this->get_option( 'course_archive_page' );
|
157 |
if ( $course_archive_page && $course_archive_page !== '-1' ) {
|
158 |
$course_page_url = get_permalink( $course_archive_page );
|
159 |
}
|
175 |
$user_name = '';
|
176 |
if ( $student_id ) {
|
177 |
global $wpdb;
|
178 |
+
$user = $wpdb->get_row(
|
179 |
+
$wpdb->prepare(
|
180 |
+
"SELECT user_nicename
|
181 |
+
FROM {$wpdb->users}
|
182 |
WHERE ID = %d;
|
183 |
+
",
|
184 |
+
$student_id
|
185 |
+
)
|
186 |
+
);
|
187 |
|
188 |
+
if ( $user ) {
|
189 |
$user_name = $user->user_nicename;
|
190 |
}
|
|
|
191 |
} else {
|
192 |
$user_name = 'user_name';
|
193 |
}
|
194 |
|
195 |
+
return $site_url . $user_name;
|
196 |
}
|
197 |
|
198 |
/**
|
206 |
*/
|
207 |
public function get_user_by_login( $user_nicename = '' ) {
|
208 |
global $wpdb;
|
209 |
+
$user_nicename = sanitize_text_field( $user_nicename );
|
210 |
+
$user = $wpdb->get_row(
|
211 |
+
$wpdb->prepare(
|
212 |
+
"SELECT *
|
213 |
FROM {$wpdb->users}
|
214 |
WHERE user_nicename = %s;
|
215 |
",
|
216 |
+
$user_nicename
|
217 |
+
)
|
218 |
+
);
|
219 |
return $user;
|
220 |
}
|
221 |
|
225 |
* Check if WooCommerce Activated
|
226 |
*
|
227 |
* @since v.1.0.0
|
228 |
+
* @updated @1.5.9
|
229 |
*/
|
230 |
public function has_wc() {
|
231 |
return class_exists( 'WooCommerce' );
|
252 |
*
|
253 |
* @since v.1.3.6
|
254 |
*/
|
255 |
+
public function has_pmpro( $check_monetization = false ) {
|
256 |
+
$has_pmpro = $this->is_plugin_active( 'paid-memberships-pro/paid-memberships-pro.php' );
|
257 |
+
return $has_pmpro && ( ! $check_monetization || get_tutor_option( 'monetize_by' ) == 'pmpro' );
|
258 |
}
|
259 |
|
260 |
+
public function is_plugin_active( $plugin_path ) {
|
261 |
$activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) );
|
262 |
+
$depends = is_array( $plugin_path ) ? $plugin_path : array( $plugin_path );
|
263 |
$has_plugin = count( array_intersect( $depends, $activated_plugins ) ) == count( $depends );
|
264 |
+
|
265 |
return $has_plugin;
|
266 |
}
|
267 |
|
268 |
+
public function has_wcs() {
|
269 |
+
$has_wcs = $this->is_plugin_active( 'woocommerce-subscriptions/woocommerce-subscriptions.php' );
|
270 |
return $has_wcs;
|
271 |
}
|
272 |
|
273 |
+
public function is_addon_enabled( $basename ) {
|
274 |
+
if ( $this->is_plugin_active( 'tutor-pro/tutor-pro.php' ) ) {
|
275 |
+
$addonConfig = $this->get_addon_config( $basename );
|
276 |
+
|
277 |
+
return (bool) $this->avalue_dot( 'is_enable', $addonConfig );
|
278 |
}
|
279 |
}
|
280 |
|
285 |
*
|
286 |
* @since v.1.4.8
|
287 |
*/
|
288 |
+
public function has_bp() {
|
289 |
$activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) );
|
290 |
$depends = array( 'buddypress/bp-loader.php' );
|
291 |
$has_bp = count( array_intersect( $depends, $activated_plugins ) ) == count( $depends );
|
299 |
*/
|
300 |
public function languages() {
|
301 |
$language_codes = array(
|
302 |
+
'en' => 'English',
|
303 |
+
'aa' => 'Afar',
|
304 |
+
'ab' => 'Abkhazian',
|
305 |
+
'af' => 'Afrikaans',
|
306 |
+
'am' => 'Amharic',
|
307 |
+
'ar' => 'Arabic',
|
308 |
+
'as' => 'Assamese',
|
309 |
+
'ay' => 'Aymara',
|
310 |
+
'az' => 'Azerbaijani',
|
311 |
+
'ba' => 'Bashkir',
|
312 |
+
'be' => 'Byelorussian',
|
313 |
+
'bg' => 'Bulgarian',
|
314 |
+
'bh' => 'Bihari',
|
315 |
+
'bi' => 'Bislama',
|
316 |
+
'bn' => 'Bengali/Bangla',
|
317 |
+
'bo' => 'Tibetan',
|
318 |
+
'br' => 'Breton',
|
319 |
+
'ca' => 'Catalan',
|
320 |
+
'co' => 'Corsican',
|
321 |
+
'cs' => 'Czech',
|
322 |
+
'cy' => 'Welsh',
|
323 |
+
'da' => 'Danish',
|
324 |
+
'de' => 'German',
|
325 |
+
'dz' => 'Bhutani',
|
326 |
+
'el' => 'Greek',
|
327 |
+
'eo' => 'Esperanto',
|
328 |
+
'es' => 'Spanish',
|
329 |
+
'et' => 'Estonian',
|
330 |
+
'eu' => 'Basque',
|
331 |
+
'fa' => 'Persian',
|
332 |
+
'fi' => 'Finnish',
|
333 |
+
'fj' => 'Fiji',
|
334 |
+
'fo' => 'Faeroese',
|
335 |
+
'fr' => 'French',
|
336 |
+
'fy' => 'Frisian',
|
337 |
+
'ga' => 'Irish',
|
338 |
+
'gd' => 'Scots/Gaelic',
|
339 |
+
'gl' => 'Galician',
|
340 |
+
'gn' => 'Guarani',
|
341 |
+
'gu' => 'Gujarati',
|
342 |
+
'ha' => 'Hausa',
|
343 |
+
'hi' => 'Hindi',
|
344 |
+
'hr' => 'Croatian',
|
345 |
+
'hu' => 'Hungarian',
|
346 |
+
'hy' => 'Armenian',
|
347 |
+
'ia' => 'Interlingua',
|
348 |
+
'ie' => 'Interlingue',
|
349 |
+
'ik' => 'Inupiak',
|
350 |
+
'in' => 'Indonesian',
|
351 |
+
'is' => 'Icelandic',
|
352 |
+
'it' => 'Italian',
|
353 |
+
'iw' => 'Hebrew',
|
354 |
+
'ja' => 'Japanese',
|
355 |
+
'ji' => 'Yiddish',
|
356 |
+
'jw' => 'Javanese',
|
357 |
+
'ka' => 'Georgian',
|
358 |
+
'kk' => 'Kazakh',
|
359 |
+
'kl' => 'Greenlandic',
|
360 |
+
'km' => 'Cambodian',
|
361 |
+
'kn' => 'Kannada',
|
362 |
+
'ko' => 'Korean',
|
363 |
+
'ks' => 'Kashmiri',
|
364 |
+
'ku' => 'Kurdish',
|
365 |
+
'ky' => 'Kirghiz',
|
366 |
+
'la' => 'Latin',
|
367 |
+
'ln' => 'Lingala',
|
368 |
+
'lo' => 'Laothian',
|
369 |
+
'lt' => 'Lithuanian',
|
370 |
+
'lv' => 'Latvian/Lettish',
|
371 |
+
'mg' => 'Malagasy',
|
372 |
+
'mi' => 'Maori',
|
373 |
+
'mk' => 'Macedonian',
|
374 |
+
'ml' => 'Malayalam',
|
375 |
+
'mn' => 'Mongolian',
|
376 |
+
'mo' => 'Moldavian',
|
377 |
+
'mr' => 'Marathi',
|
378 |
+
'ms' => 'Malay',
|
379 |
+
'mt' => 'Maltese',
|
380 |
+
'my' => 'Burmese',
|
381 |
+
'na' => 'Nauru',
|
382 |
+
'ne' => 'Nepali',
|
383 |
+
'nl' => 'Dutch',
|
384 |
+
'no' => 'Norwegian',
|
385 |
+
'oc' => 'Occitan',
|
386 |
+
'om' => '(Afan)/Oromoor/Oriya',
|
387 |
+
'pa' => 'Punjabi',
|
388 |
+
'pl' => 'Polish',
|
389 |
+
'ps' => 'Pashto/Pushto',
|
390 |
+
'pt' => 'Portuguese',
|
391 |
+
'qu' => 'Quechua',
|
392 |
+
'rm' => 'Rhaeto-Romance',
|
393 |
+
'rn' => 'Kirundi',
|
394 |
+
'ro' => 'Romanian',
|
395 |
+
'ru' => 'Russian',
|
396 |
+
'rw' => 'Kinyarwanda',
|
397 |
+
'sa' => 'Sanskrit',
|
398 |
+
'sd' => 'Sindhi',
|
399 |
+
'sg' => 'Sangro',
|
400 |
+
'sh' => 'Serbo-Croatian',
|
401 |
+
'si' => 'Singhalese',
|
402 |
+
'sk' => 'Slovak',
|
403 |
+
'sl' => 'Slovenian',
|
404 |
+
'sm' => 'Samoan',
|
405 |
+
'sn' => 'Shona',
|
406 |
+
'so' => 'Somali',
|
407 |
+
'sq' => 'Albanian',
|
408 |
+
'sr' => 'Serbian',
|
409 |
+
'ss' => 'Siswati',
|
410 |
+
'st' => 'Sesotho',
|
411 |
+
'su' => 'Sundanese',
|
412 |
+
'sv' => 'Swedish',
|
413 |
+
'sw' => 'Swahili',
|
414 |
+
'ta' => 'Tamil',
|
415 |
+
'te' => 'Tegulu',
|
416 |
+
'tg' => 'Tajik',
|
417 |
+
'th' => 'Thai',
|
418 |
+
'ti' => 'Tigrinya',
|
419 |
+
'tk' => 'Turkmen',
|
420 |
+
'tl' => 'Tagalog',
|
421 |
+
'tn' => 'Setswana',
|
422 |
+
'to' => 'Tonga',
|
423 |
+
'tr' => 'Turkish',
|
424 |
+
'ts' => 'Tsonga',
|
425 |
+
'tt' => 'Tatar',
|
426 |
+
'tw' => 'Twi',
|
427 |
+
'uk' => 'Ukrainian',
|
428 |
+
'ur' => 'Urdu',
|
429 |
+
'uz' => 'Uzbek',
|
430 |
+
'vi' => 'Vietnamese',
|
431 |
+
'vo' => 'Volapuk',
|
432 |
+
'wo' => 'Wolof',
|
433 |
+
'xh' => 'Xhosa',
|
434 |
+
'yo' => 'Yoruba',
|
435 |
+
'zh' => 'Chinese',
|
436 |
+
'zu' => 'Zulu',
|
437 |
);
|
438 |
|
439 |
return apply_filters( 'tutor/utils/languages', $language_codes );
|
448 |
*/
|
449 |
public function print_view( $value = '' ) {
|
450 |
echo '<pre>';
|
451 |
+
print_r( $value );
|
452 |
echo '</pre>';
|
453 |
}
|
454 |
|
471 |
$exclude_query = implode( "','", $excludes );
|
472 |
}
|
473 |
|
474 |
+
$post_status = array_map(
|
475 |
+
function( $element ) {
|
476 |
+
return "'" . $element . "'";
|
477 |
+
},
|
478 |
+
$post_status
|
479 |
+
);
|
480 |
|
481 |
$post_status = implode( ',', $post_status );
|
482 |
$course_post_type = tutor()->course_post_type;
|
483 |
|
484 |
+
$query = $wpdb->get_results(
|
485 |
+
$wpdb->prepare(
|
486 |
+
"SELECT ID,
|
487 |
post_author,
|
488 |
post_title,
|
489 |
post_name,
|
490 |
post_status,
|
491 |
+
menu_order
|
492 |
+
FROM {$wpdb->posts}
|
493 |
WHERE post_status IN ({$post_status})
|
494 |
AND ID NOT IN('$exclude_query')
|
495 |
AND post_type = %s;
|
496 |
",
|
497 |
+
$course_post_type
|
498 |
+
)
|
499 |
+
);
|
500 |
|
501 |
return $query;
|
502 |
}
|
517 |
$course_post_type = tutor()->course_post_type;
|
518 |
|
519 |
global $current_user;
|
520 |
+
$courses = get_posts(
|
521 |
+
array(
|
522 |
+
'post_type' => $course_post_type,
|
523 |
+
'author' => $instructor_id,
|
524 |
+
'post_status' => array( 'publish', 'pending' ),
|
525 |
+
'posts_per_page' => -1,
|
526 |
+
)
|
527 |
+
);
|
528 |
+
|
529 |
return $courses;
|
530 |
}
|
531 |
|
543 |
|
544 |
$course_post_type = tutor()->course_post_type;
|
545 |
|
546 |
+
$count = $wpdb->get_var(
|
547 |
+
$wpdb->prepare(
|
548 |
+
"SELECT COUNT(ID)
|
549 |
FROM {$wpdb->posts}
|
550 |
INNER JOIN {$wpdb->usermeta}
|
551 |
ON user_id = %d
|
552 |
AND meta_key = %s
|
553 |
AND meta_value = ID
|
554 |
+
WHERE post_status = %s
|
555 |
AND post_type = %s;
|
556 |
",
|
557 |
+
$instructor_id,
|
558 |
+
'_tutor_instructor_course_id',
|
559 |
+
'publish',
|
560 |
+
$course_post_type
|
561 |
+
)
|
562 |
+
);
|
563 |
|
564 |
return $count;
|
565 |
}
|
576 |
public function get_courses_by_instructor( $instructor_id = 0, $post_status = array( 'publish' ) ) {
|
577 |
global $wpdb;
|
578 |
|
579 |
+
$instructor_id = $this->get_user_id( $instructor_id );
|
580 |
$course_post_type = tutor()->course_post_type;
|
581 |
|
582 |
if ( $post_status === 'any' ) {
|
583 |
+
$where_post_status = '';
|
584 |
} else {
|
585 |
$post_status = (array) $post_status;
|
586 |
$statuses = "'" . implode( "','", $post_status ) . "'";
|
587 |
$where_post_status = "AND $wpdb->posts.post_status IN({$statuses}) ";
|
588 |
}
|
589 |
|
590 |
+
$pageposts = $wpdb->get_results(
|
591 |
+
$wpdb->prepare(
|
592 |
+
"SELECT $wpdb->posts.*
|
593 |
FROM $wpdb->posts
|
594 |
INNER JOIN {$wpdb->usermeta}
|
595 |
ON $wpdb->usermeta.user_id = %d
|
596 |
AND $wpdb->usermeta.meta_key = %s
|
597 |
+
AND $wpdb->usermeta.meta_value = $wpdb->posts.ID
|
598 |
WHERE 1 = 1 {$where_post_status}
|
599 |
AND $wpdb->posts.post_type = %s
|
600 |
ORDER BY $wpdb->posts.post_date DESC;
|
601 |
",
|
602 |
+
$instructor_id,
|
603 |
+
'_tutor_instructor_course_id',
|
604 |
+
$course_post_type
|
605 |
+
),
|
606 |
+
OBJECT
|
607 |
+
);
|
608 |
|
609 |
return $pageposts;
|
610 |
}
|
633 |
|
634 |
$course_post_type = tutor()->course_post_type;
|
635 |
|
636 |
+
$count = $wpdb->get_var(
|
637 |
+
$wpdb->prepare(
|
638 |
+
"SELECT COUNT(ID)
|
639 |
FROM {$wpdb->posts}
|
640 |
WHERE post_status = %s
|
641 |
AND post_type = %s;
|
642 |
",
|
643 |
+
'publish',
|
644 |
+
$course_post_type
|
645 |
+
)
|
646 |
+
);
|
647 |
+
|
648 |
return $count;
|
649 |
}
|
650 |
|
660 |
|
661 |
$lesson_post_type = tutor()->lesson_post_type;
|
662 |
|
663 |
+
$count = $wpdb->get_var(
|
664 |
+
$wpdb->prepare(
|
665 |
+
"SELECT COUNT(ID)
|
666 |
FROM {$wpdb->posts}
|
667 |
WHERE post_status = %s
|
668 |
AND post_type = %s;
|
669 |
",
|
670 |
+
'publish',
|
671 |
+
$lesson_post_type
|
672 |
+
)
|
673 |
+
);
|
674 |
+
|
675 |
return $count;
|
676 |
}
|
677 |
|
736 |
$user_id = $this->get_user_id( $user_id );
|
737 |
|
738 |
$lesson_ids = $this->get_course_content_ids_by( tutor()->lesson_post_type, tutor()->course_post_type, $course_id );
|
739 |
+
|
740 |
$count = 0;
|
741 |
+
if ( count( $lesson_ids ) ) {
|
742 |
$completed_lesson_meta_ids = array();
|
743 |
foreach ( $lesson_ids as $lesson_id ) {
|
744 |
$completed_lesson_meta_ids[] = '_tutor_completed_lesson_id_' . $lesson_id;
|
745 |
}
|
746 |
$in_ids = implode( "','", $completed_lesson_meta_ids );
|
747 |
|
748 |
+
$count = (int) $wpdb->get_var(
|
749 |
+
$wpdb->prepare(
|
750 |
+
"SELECT count(umeta_id)
|
751 |
FROM {$wpdb->usermeta}
|
752 |
WHERE user_id = %d
|
753 |
AND meta_key IN ('{$in_ids}')
|
754 |
",
|
755 |
+
$user_id
|
756 |
+
)
|
757 |
+
);
|
758 |
}
|
759 |
|
760 |
return $count;
|
767 |
* @return float|int
|
768 |
*
|
769 |
* @since v.1.0.0
|
770 |
+
* @updated v.1.6.1
|
771 |
*/
|
772 |
public function get_course_completed_percent( $course_id = 0, $user_id = 0 ) {
|
773 |
+
$course_id = $this->get_post_id( $course_id );
|
774 |
+
$user_id = $this->get_user_id( $user_id );
|
775 |
+
$completed_lesson = $this->get_completed_lesson_count_by_course( $course_id, $user_id );
|
776 |
+
$course_contents = tutils()->get_course_contents_by_id( $course_id );
|
777 |
+
$totalContents = $this->count( $course_contents );
|
778 |
+
$totalContents = $totalContents ? $totalContents : 0;
|
779 |
+
$completedCount = $completed_lesson;
|
780 |
+
|
781 |
+
if ( tutils()->count( $course_contents ) ) {
|
782 |
+
foreach ( $course_contents as $content ) {
|
783 |
+
if ( $content->post_type === 'tutor_quiz' ) {
|
784 |
+
$attempt = $this->get_quiz_attempt( $content->ID, $user_id );
|
785 |
+
if ( $attempt ) {
|
786 |
+
$completedCount++;
|
787 |
+
}
|
788 |
+
} elseif ( $content->post_type === 'tutor_assignments' ) {
|
789 |
+
$isSubmitted = $this->is_assignment_submitted( $content->ID, $user_id );
|
790 |
+
if ( $isSubmitted ) {
|
791 |
+
$completedCount++;
|
792 |
+
}
|
793 |
+
}
|
794 |
+
}
|
795 |
+
}
|
796 |
|
797 |
if ( $totalContents > 0 && $completedCount > 0 ) {
|
798 |
return number_format( ( $completedCount * 100 ) / $totalContents );
|
838 |
public function get_next_topic_order_id( $course_ID ) {
|
839 |
global $wpdb;
|
840 |
|
841 |
+
$last_order = (int) $wpdb->get_var(
|
842 |
+
$wpdb->prepare(
|
843 |
+
"SELECT MAX(menu_order)
|
844 |
FROM {$wpdb->posts}
|
845 |
WHERE post_parent = %d
|
846 |
AND post_type = %s;
|
847 |
",
|
848 |
+
$course_ID,
|
849 |
+
'topics'
|
850 |
+
)
|
851 |
+
);
|
852 |
+
|
853 |
return $last_order + 1;
|
854 |
}
|
855 |
|
865 |
public function get_next_course_content_order_id( $topic_ID ) {
|
866 |
global $wpdb;
|
867 |
|
868 |
+
$last_order = (int) $wpdb->get_var(
|
869 |
+
$wpdb->prepare(
|
870 |
+
"SELECT MAX(menu_order)
|
871 |
FROM {$wpdb->posts}
|
872 |
WHERE post_parent = %d;
|
873 |
",
|
874 |
+
$topic_ID
|
875 |
+
)
|
876 |
+
);
|
877 |
|
878 |
+
return is_numeric( $last_order ) ? $last_order + 1 : 0;
|
879 |
}
|
880 |
|
881 |
/**
|
891 |
public function get_lessons_by_topic( $topics_id = 0, $limit = 10 ) {
|
892 |
$topics_id = $this->get_post_id( $topics_id );
|
893 |
$lesson_post_type = tutor()->lesson_post_type;
|
894 |
+
|
895 |
$args = array(
|
896 |
'post_type' => $lesson_post_type,
|
897 |
'post_parent' => $topics_id,
|
916 |
* @since v.1.0.0
|
917 |
*/
|
918 |
public function get_course_contents_by_topic( $topics_id = 0, $limit = 10 ) {
|
919 |
+
$topics_id = $this->get_post_id( $topics_id );
|
920 |
$lesson_post_type = tutor()->lesson_post_type;
|
921 |
$post_type = apply_filters( 'tutor_course_contents_post_types', array( $lesson_post_type, 'tutor_quiz' ) );
|
922 |
|
942 |
*/
|
943 |
public function checking_nonce( $request_method = 'post' ) {
|
944 |
|
945 |
+
$data = $request_method === 'post' ? $_POST : $_GET;
|
946 |
+
$nonce_value = sanitize_text_field( tutils()->array_get( tutor()->nonce, $data, null ) );
|
947 |
+
$matched = $nonce_value && wp_verify_nonce( $nonce_value, tutor()->nonce_action );
|
948 |
|
949 |
+
! $matched ? exit( __( 'Nonce not matched', 'tutor' ) ) : 0;
|
950 |
}
|
951 |
|
952 |
/**
|
984 |
$course_id = $this->get_post_id( $course_id );
|
985 |
|
986 |
if ( $this->is_course_purchasable() ) {
|
987 |
+
$monetize_by = $this->get_option( 'monetize_by' );
|
988 |
|
989 |
if ( $this->has_wc() && $monetize_by === 'wc' ) {
|
990 |
$product_id = tutor_utils()->get_course_product_id( $course_id );
|
1020 |
'sale_price' => 0,
|
1021 |
);
|
1022 |
|
1023 |
+
$monetize_by = $this->get_option( 'monetize_by' );
|
1024 |
|
1025 |
$product_id = $this->get_course_product_id( $course_id );
|
1026 |
if ( $product_id ) {
|
1069 |
|
1070 |
do_action( 'tutor_is_enrolled_before', $course_id, $user_id );
|
1071 |
|
1072 |
+
$getEnrolledInfo = $wpdb->get_row(
|
1073 |
+
$wpdb->prepare(
|
1074 |
+
"SELECT ID,
|
1075 |
post_author,
|
1076 |
post_date,
|
1077 |
post_date_gmt,
|
1082 |
AND post_author = %d
|
1083 |
AND post_status = %s;
|
1084 |
",
|
1085 |
+
'tutor_enrolled',
|
1086 |
+
$course_id,
|
1087 |
+
$user_id,
|
1088 |
+
'completed'
|
1089 |
+
)
|
1090 |
+
);
|
1091 |
|
1092 |
if ( $getEnrolledInfo ) {
|
1093 |
return apply_filters( 'tutor_is_enrolled', $getEnrolledInfo, $course_id, $user_id );
|
1112 |
$user_id = $this->get_user_id( $user_id );
|
1113 |
|
1114 |
// Delete Quiz submissions
|
1115 |
+
$attempts = $this->get_quiz_attempts_by_course_ids( $start = 0, $limit = 99999999, $course_ids = array( $course_id ), $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '', $user_id = $user_id );
|
1116 |
+
|
1117 |
+
if ( is_array( $attempts ) ) {
|
1118 |
+
$attempt_ids = array_map(
|
1119 |
+
function( $attempt ) {
|
1120 |
+
return is_object( $attempt ) ? $attempt->attempt_id : 0;
|
1121 |
+
},
|
1122 |
+
$attempts
|
1123 |
+
);
|
1124 |
|
1125 |
+
$this->delete_quiz_attempt( $attempt_ids );
|
1126 |
}
|
1127 |
|
1128 |
// Delete Course completion row
|
1129 |
$del_where = array(
|
1130 |
+
'user_id' => $user_id,
|
1131 |
'comment_post_ID' => $course_id,
|
1132 |
+
'comment_type' => 'course_completed',
|
1133 |
+
'comment_agent' => 'TutorLMSPlugin',
|
1134 |
);
|
1135 |
+
$wpdb->delete( $wpdb->comments, $del_where );
|
1136 |
|
1137 |
// Delete Completed lesson count
|
1138 |
+
$lesson_ids = $this->get_course_content_ids_by( tutor()->lesson_post_type, tutor()->course_post_type, $course_id );
|
1139 |
+
foreach ( $lesson_ids as $id ) {
|
1140 |
+
delete_user_meta( $user_id, '_tutor_completed_lesson_id_' . $id );
|
1141 |
}
|
1142 |
|
1143 |
// Delete other addon-wise stuffs by hook, specially assignment.
|
1161 |
if ( is_user_logged_in() ) {
|
1162 |
global $wpdb;
|
1163 |
|
1164 |
+
$getEnrolledInfo = $wpdb->get_row(
|
1165 |
+
$wpdb->prepare(
|
1166 |
+
"SELECT ID,
|
1167 |
post_author,
|
1168 |
post_date,
|
1169 |
post_date_gmt,
|
1170 |
post_title
|
1171 |
FROM {$wpdb->posts}
|
1172 |
+
WHERE post_type = %s
|
1173 |
AND post_parent = %d
|
1174 |
AND post_author = %d;
|
1175 |
",
|
1176 |
+
'tutor_enrolled',
|
1177 |
+
$course_id,
|
1178 |
+
$user_id
|
1179 |
+
)
|
1180 |
+
);
|
1181 |
|
1182 |
if ( $getEnrolledInfo ) {
|
1183 |
return $getEnrolledInfo;
|
1188 |
}
|
1189 |
|
1190 |
|
1191 |
+
/**
|
1192 |
+
* @param int $enrol_id
|
1193 |
+
* @return array|bool|\WP_Post|null
|
1194 |
+
*
|
1195 |
+
* Get course by enrol id
|
1196 |
+
*
|
1197 |
+
* @since v.1.6.1
|
1198 |
+
*/
|
1199 |
public function get_course_by_enrol_id( $enrol_id = 0 ) {
|
1200 |
+
if ( ! $enrol_id ) {
|
1201 |
+
return false;
|
1202 |
+
}
|
1203 |
|
1204 |
+
global $wpdb;
|
1205 |
|
1206 |
+
$course_id = (int) $wpdb->get_var(
|
1207 |
+
$wpdb->prepare(
|
1208 |
+
"SELECT post_parent
|
1209 |
FROM {$wpdb->posts}
|
1210 |
WHERE post_type = %s
|
1211 |
AND ID = %d
|
1212 |
",
|
1213 |
+
'tutor_enrolled',
|
1214 |
+
$enrol_id
|
1215 |
+
)
|
1216 |
+
);
|
1217 |
|
1218 |
+
if ( $course_id ) {
|
1219 |
+
return get_post( $course_id );
|
1220 |
+
}
|
1221 |
|
1222 |
+
return null;
|
1223 |
+
}
|
1224 |
|
1225 |
/**
|
1226 |
* @param int $lesson_id
|
1254 |
*/
|
1255 |
public function get_course_id_by_lesson( $lesson_id = 0 ) {
|
1256 |
$lesson_id = $this->get_post_id( $lesson_id );
|
1257 |
+
$course_id = tutor_utils()->get_course_id_by( 'lesson', $lesson_id );
|
1258 |
|
1259 |
if ( ! $course_id ) {
|
1260 |
$course_id = $this->get_course_id_by_content( $lesson_id );
|
1275 |
*
|
1276 |
* @since v.1.0.0
|
1277 |
*/
|
1278 |
+
public function get_course_first_lesson( $course_id = 0, $post_type = null ) {
|
1279 |
global $wpdb;
|
1280 |
|
1281 |
$course_id = $this->get_post_id( $course_id );
|
1282 |
$user_id = get_current_user_id();
|
1283 |
|
1284 |
+
$lessons = $wpdb->get_results(
|
1285 |
+
$wpdb->prepare(
|
1286 |
+
"SELECT items.ID
|
1287 |
FROM {$wpdb->posts} topic
|
1288 |
INNER JOIN {$wpdb->posts} items
|
1289 |
ON topic.ID = items.post_parent
|
1290 |
WHERE topic.post_parent = %d
|
1291 |
AND items.post_status = %s
|
1292 |
+
" . ( $post_type ? " AND items.post_type='{$post_type}' " : '' ) . '
|
1293 |
ORDER BY topic.menu_order ASC,
|
1294 |
items.menu_order ASC;
|
1295 |
+
',
|
1296 |
+
$course_id,
|
1297 |
+
'publish'
|
1298 |
+
)
|
1299 |
+
);
|
1300 |
|
1301 |
$first_lesson = false;
|
1302 |
|
1303 |
if ( tutils()->count( $lessons ) ) {
|
1304 |
+
if ( ! empty( $lessons[0] ) ) {
|
1305 |
+
$first_lesson = $lessons[0];
|
1306 |
+
}
|
1307 |
|
1308 |
foreach ( $lessons as $lesson ) {
|
1309 |
$is_complete = get_user_meta( $user_id, "_tutor_completed_lesson_id_{$lesson->ID}", true );
|
1313 |
}
|
1314 |
}
|
1315 |
|
1316 |
+
if ( ! empty( $first_lesson->ID ) ) {
|
1317 |
return get_permalink( $first_lesson->ID );
|
1318 |
}
|
1319 |
}
|
1329 |
*/
|
1330 |
public function course_sub_pages() {
|
1331 |
$nav_items = array(
|
1332 |
+
'questions' => __( 'Q&A', 'tutor' ),
|
1333 |
+
'announcements' => __( 'Announcements', 'tutor' ),
|
1334 |
);
|
1335 |
|
1336 |
return apply_filters( 'tutor_course/single/enrolled/nav_items', $nav_items );
|
1353 |
}
|
1354 |
|
1355 |
/**
|
1356 |
+
* @param int $post_id
|
1357 |
* @param array $video_data
|
1358 |
*
|
1359 |
* @return bool
|
1380 |
$attachments = maybe_unserialize( get_post_meta( $post_id, '_tutor_attachments', true ) );
|
1381 |
$attachments_arr = array();
|
1382 |
|
1383 |
+
$font_icons = apply_filters(
|
1384 |
+
'tutor_file_types_icon',
|
1385 |
+
array(
|
1386 |
+
'archive',
|
1387 |
+
'audio',
|
1388 |
+
'code',
|
1389 |
+
'default',
|
1390 |
+
'document',
|
1391 |
+
'interactive',
|
1392 |
+
'spreadsheet',
|
1393 |
+
'text',
|
1394 |
+
'video',
|
1395 |
+
'image',
|
1396 |
+
)
|
1397 |
+
);
|
1398 |
|
1399 |
if ( is_array( $attachments ) && count( $attachments ) ) {
|
1400 |
foreach ( $attachments as $attachment ) {
|
1401 |
$url = wp_get_attachment_url( $attachment );
|
1402 |
$file_type = wp_check_filetype( $url );
|
1403 |
$ext = $file_type['ext'];
|
1404 |
+
$title = get_the_title( $attachment );
|
1405 |
|
1406 |
$file_path = get_attached_file( $attachment );
|
1407 |
+
$size_bytes = file_exists( $file_path ) ? filesize( $file_path ) : 0;
|
1408 |
$size = size_format( $size_bytes, 2 );
|
1409 |
$type = wp_ext2type( $ext );
|
1410 |
|
1443 |
* @since v.1.0.0
|
1444 |
*/
|
1445 |
public function playtime_string( $seconds ) {
|
1446 |
+
$sign = ( ( $seconds < 0 ) ? '-' : '' );
|
1447 |
$seconds = round( abs( $seconds ) );
|
1448 |
+
$H = (int) floor( $seconds / 3600 );
|
1449 |
+
$M = (int) floor( ( $seconds - ( 3600 * $H ) ) / 60 );
|
1450 |
+
$S = (int) round( $seconds - ( 3600 * $H ) - ( 60 * $M ) );
|
1451 |
+
return $sign . ( $H ? $H . ':' : '' ) . ( $H ? str_pad( $M, 2, '0', STR_PAD_LEFT ) : intval( $M ) ) . ':' . str_pad( $S, 2, 0, STR_PAD_LEFT );
|
1452 |
}
|
1453 |
|
1454 |
/**
|
1467 |
'seconds' => '00',
|
1468 |
);
|
1469 |
|
1470 |
+
if ( $seconds <= 0 ) {
|
1471 |
return $run_time_format;
|
1472 |
}
|
1473 |
|
1474 |
$playTimeString = $this->playtime_string( $seconds );
|
1475 |
$timeInArray = explode( ':', $playTimeString );
|
1476 |
|
1477 |
+
$run_time_size = count( $timeInArray );
|
1478 |
if ( $run_time_size === 3 ) {
|
1479 |
+
$run_time_format['hours'] = $timeInArray[0];
|
1480 |
+
$run_time_format['minutes'] = $timeInArray[1];
|
1481 |
+
$run_time_format['seconds'] = $timeInArray[2];
|
1482 |
} elseif ( $run_time_size === 2 ) {
|
1483 |
+
$run_time_format['minutes'] = $timeInArray[0];
|
1484 |
+
$run_time_format['seconds'] = $timeInArray[1];
|
1485 |
}
|
1486 |
|
1487 |
return $run_time_format;
|
1497 |
* @since v.1.0.0
|
1498 |
*/
|
1499 |
public function seconds_to_time_context( $seconds ) {
|
1500 |
+
$sign = ( ( $seconds < 0 ) ? '-' : '' );
|
1501 |
$seconds = round( abs( $seconds ) );
|
1502 |
+
$H = (int) floor( $seconds / 3600 );
|
1503 |
+
$M = (int) floor( ( $seconds - ( 3600 * $H ) ) / 60 );
|
1504 |
+
$S = (int) round( $seconds - ( 3600 * $H ) - ( 60 * $M ) );
|
1505 |
|
1506 |
+
return $sign . ( $H ? $H . 'h ' : '' ) . ( $H ? str_pad( $M, 2, '0', STR_PAD_LEFT ) : intval( $M ) ) . 'm ' . str_pad( $S, 2, 0, STR_PAD_LEFT ) . 's';
|
1507 |
}
|
1508 |
|
1509 |
/**
|
1525 |
'playtime' => '00:00',
|
1526 |
);
|
1527 |
|
1528 |
+
$types = apply_filters(
|
1529 |
+
'tutor_video_types',
|
1530 |
+
array(
|
1531 |
+
'mp4' => 'video/mp4',
|
1532 |
+
'webm' => 'video/webm',
|
1533 |
+
'ogg' => 'video/ogg',
|
1534 |
+
)
|
1535 |
+
);
|
1536 |
|
1537 |
+
$videoSource = $this->avalue_dot( 'source', $video );
|
1538 |
|
1539 |
if ( $videoSource === 'html5' ) {
|
1540 |
$sourceVideoID = $this->avalue_dot( 'source_video_id', $video );
|
1541 |
$video_info = get_post_meta( $sourceVideoID, '_wp_attachment_metadata', true );
|
1542 |
|
1543 |
+
if ( $video_info && in_array( $this->array_get( 'mime_type', $video_info ), $types ) ) {
|
1544 |
$path = get_attached_file( $sourceVideoID );
|
1545 |
$info['playtime'] = $video_info['length_formatted'];
|
1546 |
$info['path'] = $path;
|
1569 |
}
|
1570 |
|
1571 |
public function get_optimized_duration( $duration ) {
|
1572 |
+
/*
|
1573 |
+
if(is_string($duration)){
|
1574 |
strpos($duration, '00:')===0 ? $duration=substr($duration, 3) : 0; // Remove Empty hour
|
1575 |
strpos($duration, '00:')===0 ? $duration=substr($duration, 3) : 0; // Remove empty minute
|
1576 |
} */
|
1604 |
*
|
1605 |
* return lesson type icon
|
1606 |
*
|
1607 |
+
* @param int $lesson_id
|
1608 |
* @param bool $html
|
1609 |
* @param bool $echo
|
1610 |
*
|
1628 |
}
|
1629 |
|
1630 |
if ( $echo ) {
|
1631 |
+
echo $tutor_lesson_type_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1632 |
}
|
1633 |
|
1634 |
return $tutor_lesson_type_icon;
|
1645 |
public function is_completed_lesson( $lesson_id = 0, $user_id = 0 ) {
|
1646 |
$lesson_id = $this->get_post_id( $lesson_id );
|
1647 |
$user_id = $this->get_user_id( $user_id );
|
1648 |
+
$is_completed = get_user_meta( $user_id, '_tutor_completed_lesson_id_' . $lesson_id, true );
|
1649 |
|
1650 |
if ( $is_completed ) {
|
1651 |
return $is_completed;
|
1667 |
* @updated v.1.4.9
|
1668 |
*/
|
1669 |
public function is_completed_course( $course_id = 0, $user_id = 0 ) {
|
1670 |
+
|
1671 |
global $wpdb;
|
1672 |
+
$course_id = $this->get_post_id( $course_id );
|
1673 |
+
$user_id = $this->get_user_id( $user_id );
|
1674 |
+
|
1675 |
+
$is_completed = $wpdb->get_row(
|
1676 |
+
$wpdb->prepare(
|
1677 |
+
"SELECT comment_ID,
|
1678 |
+
comment_post_ID AS course_id,
|
1679 |
+
comment_author AS completed_user_id,
|
1680 |
+
comment_date AS completion_date,
|
1681 |
+
comment_content AS completed_hash
|
1682 |
+
FROM {$wpdb->comments}
|
1683 |
+
WHERE comment_agent = %s
|
1684 |
+
AND comment_type = %s
|
1685 |
+
AND comment_post_ID = %d
|
1686 |
AND user_id = %d;
|
1687 |
",
|
1688 |
+
'TutorLMSPlugin',
|
1689 |
+
'course_completed',
|
1690 |
+
$course_id,
|
1691 |
+
$user_id
|
1692 |
+
)
|
1693 |
+
);
|
1694 |
|
1695 |
if ( $is_completed ) {
|
1696 |
return apply_filters( 'is_completed_course', $is_completed, $course_id, $user_id );
|
1713 |
|
1714 |
if ( is_array( $input ) && count( $input ) ) {
|
1715 |
foreach ( $input as $key => $value ) {
|
1716 |
+
if ( is_array( $value ) ) {
|
1717 |
+
$array[ $key ] = $this->sanitize_array( $value );
|
1718 |
} else {
|
1719 |
+
$key = sanitize_text_field( $key );
|
1720 |
+
$value = sanitize_text_field( $value );
|
1721 |
+
$array[ $key ] = $value;
|
1722 |
}
|
1723 |
}
|
1724 |
}
|
1738 |
public function has_video_in_single( $post_id = 0 ) {
|
1739 |
if ( is_single() ) {
|
1740 |
$post_id = $this->get_post_id( $post_id );
|
1741 |
+
|
1742 |
$video = $this->get_video( $post_id );
|
1743 |
if ( $video && $this->array_get( 'source', $video ) !== '-1' ) {
|
1744 |
+
|
1745 |
+
$not_empty = ! empty( $video['source_video_id'] ) ||
|
1746 |
+
! empty( $video['source_external_url'] ) ||
|
1747 |
+
! empty( $video['source_youtube'] ) ||
|
1748 |
+
! empty( $video['source_vimeo'] ) ||
|
1749 |
+
! empty( $video['source_embedded'] );
|
1750 |
+
|
1751 |
return $not_empty ? $video : false;
|
1752 |
}
|
1753 |
}
|
1755 |
}
|
1756 |
|
1757 |
/**
|
1758 |
+
* @param int $start
|
1759 |
+
* @param int $limit
|
1760 |
* @param string $search_term
|
1761 |
+
* @param int $course_id
|
1762 |
*
|
1763 |
* @return array|null|object
|
1764 |
*
|
1774 |
|
1775 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
1776 |
|
1777 |
+
$students = $wpdb->get_results(
|
1778 |
+
$wpdb->prepare(
|
1779 |
+
"SELECT SQL_CALC_FOUND_ROWS {$wpdb->users}.*
|
1780 |
FROM {$wpdb->users}
|
1781 |
INNER JOIN {$wpdb->usermeta}
|
1782 |
ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
|
1785 |
ORDER BY {$wpdb->usermeta}.meta_value DESC
|
1786 |
LIMIT {$start}, {$limit};
|
1787 |
",
|
1788 |
+
'_is_tutor_student',
|
1789 |
+
$search_term,
|
1790 |
+
$search_term
|
1791 |
+
)
|
1792 |
+
);
|
1793 |
|
1794 |
return $students;
|
1795 |
}
|
1809 |
|
1810 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
1811 |
|
1812 |
+
$count = $wpdb->get_var(
|
1813 |
+
$wpdb->prepare(
|
1814 |
+
"SELECT COUNT({$wpdb->users}.ID)
|
1815 |
FROM {$wpdb->users}
|
1816 |
INNER JOIN {$wpdb->usermeta}
|
1817 |
ON ( {$wpdb->users}.ID = {$wpdb->usermeta}.user_id )
|
1818 |
WHERE {$wpdb->usermeta}.meta_key = %s
|
1819 |
AND ( {$wpdb->users}.display_name LIKE %s OR {$wpdb->users}.user_email LIKE %s );
|
1820 |
",
|
1821 |
+
'_is_tutor_student',
|
1822 |
+
$search_term,
|
1823 |
+
$search_term
|
1824 |
+
)
|
1825 |
+
);
|
1826 |
|
1827 |
return (int) $count;
|
1828 |
}
|
1841 |
|
1842 |
$user_id = $this->get_user_id( $user_id );
|
1843 |
|
1844 |
+
$course_ids = (array) $wpdb->get_col(
|
1845 |
+
$wpdb->prepare(
|
1846 |
+
"SELECT comment_post_ID AS course_id
|
1847 |
+
FROM {$wpdb->comments}
|
1848 |
+
WHERE comment_agent = %s
|
1849 |
AND comment_type = %s
|
1850 |
AND user_id = %d
|
1851 |
",
|
1852 |
+
'TutorLMSPlugin',
|
1853 |
+
'course_completed',
|
1854 |
+
$user_id
|
1855 |
+
)
|
1856 |
+
);
|
1857 |
|
1858 |
return $course_ids;
|
1859 |
}
|
1871 |
$user_id = $this->get_user_id( $user_id );
|
1872 |
$course_ids = $this->get_completed_courses_ids_by_user( $user_id );
|
1873 |
|
1874 |
+
if ( count( $course_ids ) ) {
|
1875 |
$course_post_type = tutor()->course_post_type;
|
1876 |
+
$course_args = array(
|
1877 |
'post_type' => $course_post_type,
|
1878 |
'post_status' => 'publish',
|
1879 |
'post__in' => $course_ids,
|
1880 |
+
'posts_per_page' => -1,
|
1881 |
);
|
1882 |
|
1883 |
return new \WP_Query( $course_args );
|
1903 |
|
1904 |
if ( count( $active_courses ) ) {
|
1905 |
$course_post_type = tutor()->course_post_type;
|
1906 |
+
$course_args = array(
|
1907 |
'post_type' => $course_post_type,
|
1908 |
'post_status' => 'publish',
|
1909 |
'post__in' => $active_courses,
|
1910 |
+
'posts_per_page' => -1,
|
1911 |
);
|
1912 |
|
1913 |
return new \WP_Query( $course_args );
|
1927 |
*/
|
1928 |
public function get_enrolled_courses_ids_by_user( $user_id = 0 ) {
|
1929 |
global $wpdb;
|
1930 |
+
$user_id = $this->get_user_id( $user_id );
|
1931 |
+
$course_ids = $wpdb->get_col(
|
1932 |
+
$wpdb->prepare(
|
1933 |
+
"SELECT DISTINCT post_parent
|
1934 |
FROM {$wpdb->posts}
|
1935 |
WHERE post_type = %s
|
1936 |
AND post_status = %s
|
1937 |
AND post_author = %d;
|
1938 |
",
|
1939 |
+
'tutor_enrolled',
|
1940 |
+
'completed',
|
1941 |
+
$user_id
|
1942 |
+
)
|
1943 |
+
);
|
1944 |
|
1945 |
return $course_ids;
|
1946 |
}
|
1947 |
|
1948 |
/**
|
1949 |
* Get total enrolled students by course id
|
1950 |
+
*
|
1951 |
+
* @param int $course_id
|
1952 |
*
|
1953 |
* @param $period string | optional added since 1.9.9
|
1954 |
+
*
|
1955 |
* @return int
|
1956 |
+
*
|
1957 |
* @since 1.9.9
|
1958 |
*/
|
1959 |
+
public function count_enrolled_users_by_course( $course_id = 0, $period = '' ) {
|
1960 |
global $wpdb;
|
1961 |
|
1962 |
$course_id = $this->get_post_id( $course_id );
|
1963 |
+
// set period wise query
|
1964 |
$period_filter = '';
|
1965 |
if ( 'today' === $period ) {
|
1966 |
+
$period_filter = 'AND DATE(post_date) = CURDATE()';
|
1967 |
+
}
|
1968 |
if ( 'monthly' === $period ) {
|
1969 |
+
$period_filter = 'AND MONTH(post_date) = MONTH(CURDATE()) ';
|
1970 |
}
|
1971 |
if ( 'yearly' === $period ) {
|
1972 |
+
$period_filter = 'AND YEAR(post_date) = YEAR(CURDATE()) ';
|
1973 |
}
|
1974 |
|
1975 |
+
$course_ids = $wpdb->get_var(
|
1976 |
+
$wpdb->prepare(
|
1977 |
+
"SELECT COUNT(ID)
|
1978 |
+
FROM {$wpdb->posts}
|
1979 |
WHERE post_type = %s
|
1980 |
AND post_status = %s
|
1981 |
AND post_parent = %d;
|
1982 |
{$period_filter}
|
1983 |
",
|
1984 |
+
'tutor_enrolled',
|
1985 |
+
'completed',
|
1986 |
+
$course_id
|
1987 |
+
)
|
1988 |
+
);
|
1989 |
|
1990 |
return (int) $course_ids;
|
1991 |
}
|
1997 |
*
|
1998 |
* Get the enrolled courses by user
|
1999 |
*/
|
2000 |
+
public function get_enrolled_courses_by_user( $user_id = 0, $post_status = 'publish' ) {
|
2001 |
global $wpdb;
|
2002 |
|
2003 |
+
$user_id = $this->get_user_id( $user_id );
|
2004 |
$course_ids = $this->get_enrolled_courses_ids_by_user( $user_id );
|
2005 |
|
2006 |
if ( count( $course_ids ) ) {
|
2007 |
$course_post_type = tutor()->course_post_type;
|
2008 |
+
$course_args = array(
|
2009 |
'post_type' => $course_post_type,
|
2010 |
'post_status' => $post_status,
|
2011 |
'post__in' => $course_ids,
|
2012 |
+
'posts_per_page' => -1,
|
2013 |
);
|
2014 |
return new \WP_Query( $course_args );
|
2015 |
}
|
2032 |
$video_url = trailingslashit( home_url() ) . 'video-url/' . $post->post_name;
|
2033 |
} else {
|
2034 |
$video_info = tutor_utils()->get_video_info( $post_id );
|
2035 |
+
$video_url = $video_info->url;
|
2036 |
}
|
2037 |
|
2038 |
return $video_url;
|
2050 |
*/
|
2051 |
public function get_lesson_reading_info_full( $lesson_id = 0, $user_id = 0 ) {
|
2052 |
$lesson_id = $this->get_post_id( $lesson_id );
|
2053 |
+
$user_id = $this->get_user_id( $user_id );
|
2054 |
|
2055 |
$lesson_info = (array) maybe_unserialize( get_user_meta( $user_id, '_lesson_reading_info', true ) );
|
2056 |
return $this->avalue_dot( $lesson_id, $lesson_info );
|
2065 |
*
|
2066 |
* @since v.1.0.0
|
2067 |
*/
|
2068 |
+
public function get_post_id( $post_id = 0 ) {
|
2069 |
if ( ! $post_id ) {
|
2070 |
$post_id = get_the_ID();
|
2071 |
if ( ! $post_id ) {
|
2086 |
* @since v.1.0.0
|
2087 |
*/
|
2088 |
public function get_user_id( $user_id = 0 ) {
|
2089 |
+
if ( ! $user_id ) {
|
2090 |
$user_id = get_current_user_id();
|
2091 |
if ( ! $user_id ) {
|
2092 |
return false;
|
2097 |
}
|
2098 |
|
2099 |
/**
|
2100 |
+
* @param int $lesson_id
|
2101 |
+
* @param int $user_id
|
2102 |
* @param string $key
|
2103 |
*
|
2104 |
* @return array|bool|mixed
|
2112 |
$user_id = $this->get_user_id( $user_id );
|
2113 |
$lesson_info = $this->get_lesson_reading_info_full( $lesson_id, $user_id );
|
2114 |
|
2115 |
+
return $this->avalue_dot( $key, $lesson_info );
|
2116 |
}
|
2117 |
|
2118 |
/**
|
2119 |
+
* @param int $lesson_id
|
2120 |
+
* @param int $user_id
|
2121 |
* @param array $data
|
2122 |
*
|
2123 |
* @return bool
|
2127 |
* @since v.1.0.0
|
2128 |
*/
|
2129 |
public function update_lesson_reading_info( $lesson_id = 0, $user_id = 0, $key = '', $value = '' ) {
|
2130 |
+
$lesson_id = $this->get_post_id( $lesson_id );
|
2131 |
+
$user_id = $this->get_user_id( $user_id );
|
2132 |
|
2133 |
if ( $key && $value ) {
|
2134 |
+
$lesson_info = (array) maybe_unserialize( get_user_meta( $user_id, '_lesson_reading_info', true ) );
|
2135 |
$lesson_info[ $lesson_id ][ $key ] = $value;
|
2136 |
update_user_meta( $user_id, '_lesson_reading_info', $lesson_info );
|
2137 |
}
|
2146 |
*
|
2147 |
* @since v.1.0.0
|
2148 |
*/
|
2149 |
+
public function get_youtube_video_id( $url = '' ) {
|
2150 |
if ( ! $url ) {
|
2151 |
return false;
|
2152 |
}
|
2171 |
* @since v.1.0.0
|
2172 |
*/
|
2173 |
public function get_vimeo_video_id( $url = '' ) {
|
2174 |
+
if ( preg_match( '%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im', $url, $match ) ) {
|
2175 |
if ( isset( $match[3] ) ) {
|
2176 |
return $match[3];
|
2177 |
}
|
2191 |
$user_id = $this->get_user_id( $user_id );
|
2192 |
|
2193 |
do_action( 'tutor_mark_lesson_complete_before', $post_id, $user_id );
|
2194 |
+
update_user_meta( $user_id, '_tutor_completed_lesson_id_' . $post_id, tutor_time() );
|
2195 |
do_action( 'tutor_mark_lesson_complete_after', $post_id, $user_id );
|
2196 |
}
|
2197 |
|
2220 |
|
2221 |
do_action( 'tutor_before_enroll', $course_id );
|
2222 |
$user_id = $this->get_user_id( $user_id );
|
2223 |
+
$title = __( 'Course Enrolled', 'tutor' ) . ' – ' . date( get_option( 'date_format' ) ) . ' @ ' . date( get_option( 'time_format' ) );
|
2224 |
|
2225 |
if ( $course_id && $user_id ) {
|
2226 |
if ( $this->is_enrolled( $course_id, $user_id ) ) {
|
2227 |
+
return;
|
2228 |
}
|
2229 |
}
|
2230 |
|
2237 |
$enrolment_status = 'pending';
|
2238 |
}
|
2239 |
|
2240 |
+
$enroll_data = apply_filters(
|
2241 |
+
'tutor_enroll_data',
|
2242 |
array(
|
2243 |
+
'post_type' => 'tutor_enrolled',
|
2244 |
+
'post_title' => $title,
|
2245 |
+
'post_status' => $enrolment_status,
|
2246 |
+
'post_author' => $user_id,
|
2247 |
+
'post_parent' => $course_id,
|
2248 |
)
|
2249 |
);
|
2250 |
|
2256 |
do_action( 'tutor_after_enroll', $course_id, $isEnrolled );
|
2257 |
|
2258 |
// Run this hook for completed enrollment regardless of payment provider and free/paid mode
|
2259 |
+
if ( $enroll_data['post_status'] == 'completed' ) {
|
2260 |
+
do_action( 'tutor_after_enrolled', $course_id, $user_id, $isEnrolled );
|
2261 |
}
|
2262 |
|
2263 |
+
// Mark Current User as Students with user meta data
|
2264 |
update_user_meta( $user_id, '_is_tutor_student', tutor_time() );
|
2265 |
|
2266 |
if ( $order_id ) {
|
2267 |
+
// Mark order for course and user
|
2268 |
$product_id = $this->get_course_product_id( $course_id );
|
2269 |
update_post_meta( $isEnrolled, '_tutor_enrolled_by_order_id', $order_id );
|
2270 |
update_post_meta( $isEnrolled, '_tutor_enrolled_by_product_id', $product_id );
|
2271 |
update_post_meta( $order_id, '_is_tutor_order_for_course', tutor_time() );
|
2272 |
+
update_post_meta( $order_id, '_tutor_order_for_course_id_' . $course_id, $isEnrolled );
|
2273 |
}
|
2274 |
return true;
|
2275 |
}
|
2277 |
return false;
|
2278 |
}
|
2279 |
|
2280 |
+
/**
|
2281 |
+
* @param bool $enrol_id
|
2282 |
+
* @param string $new_status
|
2283 |
+
*
|
2284 |
+
* Enrol Status change
|
2285 |
+
*
|
2286 |
+
* @since v.1.6.1
|
2287 |
+
*/
|
2288 |
public function course_enrol_status_change( $enrol_id = false, $new_status = '' ) {
|
2289 |
+
if ( ! $enrol_id ) {
|
2290 |
+
return;
|
2291 |
+
}
|
2292 |
+
|
2293 |
+
global $wpdb;
|
2294 |
+
|
2295 |
+
do_action( 'tutor/course/enrol_status_change/before', $enrol_id, $new_status );
|
2296 |
+
$wpdb->update( $wpdb->posts, array( 'post_status' => $new_status ), array( 'ID' => $enrol_id ) );
|
2297 |
+
do_action( 'tutor/course/enrol_status_change/after', $enrol_id, $new_status );
|
2298 |
+
}
|
2299 |
+
|
2300 |
+
/**
|
2301 |
+
* @param int $course_id
|
2302 |
+
* @param int $user_id
|
2303 |
+
* @param string $cancel_status
|
2304 |
+
*/
|
2305 |
public function cancel_course_enrol( $course_id = 0, $user_id = 0, $cancel_status = 'canceled' ) {
|
2306 |
+
$course_id = $this->get_post_id( $course_id );
|
2307 |
+
$user_id = $this->get_user_id( $user_id );
|
2308 |
+
$enrolled = $this->is_enrolled( $course_id, $user_id );
|
2309 |
+
|
2310 |
+
if ( $enrolled ) {
|
2311 |
+
global $wpdb;
|
2312 |
+
|
2313 |
+
if ( $cancel_status === 'delete' ) {
|
2314 |
+
$wpdb->delete(
|
2315 |
+
$wpdb->posts,
|
2316 |
+
array(
|
2317 |
+
'post_type' => 'tutor_enrolled',
|
2318 |
+
'post_author' => $user_id,
|
2319 |
+
'post_parent' => $course_id,
|
2320 |
+
)
|
2321 |
+
);
|
2322 |
+
|
2323 |
+
// Delete Related Meta Data
|
2324 |
+
delete_post_meta( $enrolled->ID, '_tutor_enrolled_by_product_id' );
|
2325 |
+
$order_id = get_post_meta( $enrolled->ID, '_tutor_enrolled_by_order_id', true );
|
2326 |
+
if ( $order_id ) {
|
2327 |
+
delete_post_meta( $enrolled->ID, '_tutor_enrolled_by_order_id' );
|
2328 |
+
delete_post_meta( $order_id, '_is_tutor_order_for_course' );
|
2329 |
+
delete_post_meta( $order_id, '_tutor_order_for_course_id_' . $course_id );
|
2330 |
+
|
2331 |
do_action( 'tutor_enrollment/after/delete', $enrolled->ID );
|
2332 |
+
}
|
2333 |
+
} else {
|
2334 |
+
$wpdb->update(
|
2335 |
+
$wpdb->posts,
|
2336 |
+
array( 'post_status' => $cancel_status ),
|
2337 |
+
array(
|
2338 |
+
'post_type' => 'tutor_enrolled',
|
2339 |
+
'post_author' => $user_id,
|
2340 |
+
'post_parent' => $course_id,
|
2341 |
+
)
|
2342 |
+
);
|
2343 |
+
|
2344 |
if ( $cancel_status === 'cancel' ) {
|
2345 |
do_action( 'tutor_enrollment/after/cancel', $enrolled->ID );
|
2346 |
}
|
2347 |
}
|
2348 |
+
}
|
2349 |
+
}
|
2350 |
|
2351 |
/**
|
2352 |
* @param $order_id
|
2384 |
public function get_course_enrolled_ids_by_order_id( $order_id ) {
|
2385 |
global $wpdb;
|
2386 |
|
2387 |
+
// Getting all of courses ids within this order
|
2388 |
+
$courses_ids = $wpdb->get_results(
|
2389 |
+
$wpdb->prepare(
|
2390 |
+
"SELECT *
|
2391 |
FROM {$wpdb->postmeta}
|
2392 |
+
WHERE post_id = %d
|
2393 |
AND meta_key LIKE '_tutor_order_for_course_id_%'
|
2394 |
+
",
|
2395 |
+
$order_id
|
2396 |
+
)
|
2397 |
+
);
|
2398 |
|
2399 |
if ( is_array( $courses_ids ) && count( $courses_ids ) ) {
|
2400 |
$course_enrolled_by_order = array();
|
2401 |
foreach ( $courses_ids as $courses_id ) {
|
2402 |
+
$course_id = str_replace( '_tutor_order_for_course_id_', '', $courses_id->meta_key );
|
2403 |
$course_enrolled_by_order[] = array(
|
2404 |
'course_id' => $course_id,
|
2405 |
'enrolled_id' => $courses_id->meta_value,
|
2406 |
+
'order_id' => $courses_id->post_id,
|
2407 |
);
|
2408 |
}
|
2409 |
return $course_enrolled_by_order;
|
2424 |
*/
|
2425 |
public function get_wc_products_db() {
|
2426 |
global $wpdb;
|
2427 |
+
$query = $wpdb->get_results(
|
2428 |
+
$wpdb->prepare(
|
2429 |
+
"SELECT ID,
|
2430 |
post_title
|
2431 |
FROM {$wpdb->posts}
|
2432 |
WHERE post_status = %s
|
2433 |
AND post_type = %s;
|
2434 |
",
|
2435 |
+
'publish',
|
2436 |
+
'product'
|
2437 |
+
)
|
2438 |
+
);
|
2439 |
|
2440 |
return $query;
|
2441 |
}
|
2447 |
*/
|
2448 |
public function get_edd_products() {
|
2449 |
global $wpdb;
|
2450 |
+
$query = $wpdb->get_results(
|
2451 |
+
$wpdb->prepare(
|
2452 |
+
"SELECT ID,
|
2453 |
post_title
|
2454 |
FROM {$wpdb->posts}
|
2455 |
WHERE post_status = %s
|
2456 |
AND post_type = %s;
|
2457 |
",
|
2458 |
+
'publish',
|
2459 |
+
'download'
|
2460 |
+
)
|
2461 |
+
);
|
2462 |
|
2463 |
return $query;
|
2464 |
}
|
2491 |
public function product_belongs_with_course( $product_id = 0 ) {
|
2492 |
global $wpdb;
|
2493 |
|
2494 |
+
$query = $wpdb->get_row(
|
2495 |
+
$wpdb->prepare(
|
2496 |
+
"SELECT *
|
2497 |
FROM {$wpdb->postmeta}
|
2498 |
+
WHERE meta_key = %s
|
2499 |
+
AND meta_value = %d
|
2500 |
limit 1
|
2501 |
",
|
2502 |
+
'_tutor_course_product_id',
|
2503 |
+
$product_id
|
2504 |
+
)
|
2505 |
+
);
|
2506 |
+
|
2507 |
return $query;
|
2508 |
}
|
2509 |
|
2515 |
public function get_enrolled_statuses() {
|
2516 |
return apply_filters(
|
2517 |
'tutor_get_enrolled_statuses',
|
2518 |
+
array(
|
2519 |
'pending',
|
2520 |
'processing',
|
2521 |
'on-hold',
|
2548 |
* @since v.1.0.0
|
2549 |
*/
|
2550 |
public function tutor_dashboard_pages() {
|
2551 |
+
$nav_items = apply_filters(
|
2552 |
+
'tutor_dashboard/nav_items',
|
2553 |
+
array(
|
2554 |
+
'index' => __( 'Dashboard', 'tutor' ),
|
2555 |
+
'my-profile' => __( 'My Profile', 'tutor' ),
|
2556 |
+
'enrolled-courses' => __( 'Enrolled Courses', 'tutor' ),
|
2557 |
+
'wishlist' => __( 'Wishlist', 'tutor' ),
|
2558 |
+
'reviews' => __( 'Reviews', 'tutor' ),
|
2559 |
+
'my-quiz-attempts' => __( 'My Quiz Attempts', 'tutor' ),
|
2560 |
+
'purchase_history' => __( 'Purchase History', 'tutor' ),
|
2561 |
+
)
|
2562 |
+
);
|
2563 |
+
|
2564 |
+
$instructor_nav_items = apply_filters(
|
2565 |
+
'tutor_dashboard/instructor_nav_items',
|
2566 |
+
array(
|
2567 |
+
'separator-1' => array(
|
2568 |
+
'title' => __( 'Instructor', 'tutor' ),
|
2569 |
+
'auth_cap' => tutor()->instructor_role,
|
2570 |
+
'type' => 'separator',
|
2571 |
+
),
|
2572 |
+
'create-course' => array(
|
2573 |
+
'title' => __( 'Create Course', 'tutor' ),
|
2574 |
+
'show_ui' => false,
|
2575 |
+
'auth_cap' => tutor()->instructor_role,
|
2576 |
+
),
|
2577 |
+
'my-courses' => array(
|
2578 |
+
'title' => __( 'My Courses', 'tutor' ),
|
2579 |
+
'auth_cap' => tutor()->instructor_role,
|
2580 |
+
),
|
2581 |
+
'announcements' => array(
|
2582 |
+
'title' => __( 'Announcements', 'tutor' ),
|
2583 |
+
'auth_cap' => tutor()->instructor_role,
|
2584 |
+
),
|
2585 |
+
'withdraw' => array(
|
2586 |
+
'title' => __( 'Withdrawals', 'tutor' ),
|
2587 |
+
'auth_cap' => tutor()->instructor_role,
|
2588 |
+
),
|
2589 |
+
'quiz-attempts' => array(
|
2590 |
+
'title' => __( 'Quiz Attempts', 'tutor' ),
|
2591 |
+
'auth_cap' => tutor()->instructor_role,
|
2592 |
+
),
|
2593 |
+
'question-answer' => array(
|
2594 |
+
'title' => __( 'Question & Answer', 'tutor' ),
|
2595 |
+
'auth_cap' => tutor()->instructor_role,
|
2596 |
+
),
|
2597 |
+
)
|
2598 |
+
);
|
2599 |
|
2600 |
$disable = get_tutor_option( 'disable_course_review' );
|
2601 |
if ( $disable && isset( $nav_items['reviews'] ) ) {
|
2604 |
|
2605 |
$nav_items = array_merge( $nav_items, $instructor_nav_items );
|
2606 |
|
2607 |
+
$new_navs = apply_filters(
|
2608 |
+
'tutor_dashboard/bottom_nav_items',
|
2609 |
+
array(
|
2610 |
+
'separator-2' => array(
|
2611 |
+
'title' => '',
|
2612 |
+
'type' => 'separator',
|
2613 |
+
),
|
2614 |
+
'settings' => __( 'Settings', 'tutor' ),
|
2615 |
+
'logout' => __( 'Logout', 'tutor' ),
|
2616 |
+
)
|
2617 |
+
);
|
2618 |
$all_nav_items = array_merge( $nav_items, $new_navs );
|
2619 |
|
2620 |
return apply_filters( 'tutor_dashboard/nav_items_all', $all_nav_items );
|
2623 |
public function tutor_dashboard_permalinks() {
|
2624 |
$dashboard_pages = $this->tutor_dashboard_pages();
|
2625 |
|
2626 |
+
$dashboard_permalinks = apply_filters(
|
2627 |
+
'tutor_dashboard/permalinks',
|
2628 |
+
array(
|
2629 |
+
'retrieve-password' => array(
|
2630 |
+
'title' => __( 'Retrieve Password', 'tutor' ),
|
2631 |
+
'login_require' => false,
|
2632 |
+
),
|
2633 |
+
)
|
2634 |
+
);
|
2635 |
|
2636 |
$dashboard_pages = array_merge( $dashboard_pages, $dashboard_permalinks );
|
2637 |
|
2650 |
$nav_items = $this->tutor_dashboard_pages();
|
2651 |
|
2652 |
foreach ( $nav_items as $key => $nav_item ) {
|
2653 |
+
if ( is_array( $nav_item ) ) {
|
2654 |
|
2655 |
if ( isset( $nav_item['show_ui'] ) && ! tutor_utils()->array_get( 'show_ui', $nav_item ) ) {
|
2656 |
unset( $nav_items[ $key ] );
|
2657 |
}
|
2658 |
+
if ( isset( $nav_item['auth_cap'] ) && ! current_user_can( $nav_item['auth_cap'] ) ) {
|
2659 |
unset( $nav_items[ $key ] );
|
2660 |
}
|
2661 |
}
|
2662 |
}
|
2663 |
|
2664 |
+
return apply_filters( 'tutor_dashboard/nav_ui_items', $nav_items );
|
2665 |
}
|
2666 |
|
2667 |
/**
|
2668 |
* @param string $page_key
|
2669 |
+
* @param int $page_id
|
2670 |
*
|
2671 |
* @return string
|
2672 |
*
|
2679 |
$page_key = '';
|
2680 |
}
|
2681 |
if ( ! $page_id ) {
|
2682 |
+
$page_id = (int) tutils()->get_option( 'tutor_dashboard_page_id' );
|
2683 |
+
}
|
2684 |
return trailingslashit( get_permalink( $page_id ) ) . $page_key;
|
2685 |
}
|
2686 |
|
2696 |
*/
|
2697 |
public function input_old( $input = '', $old_data = null ) {
|
2698 |
if ( ! $old_data ) {
|
2699 |
+
$old_data = tutor_sanitize_data( $_REQUEST );
|
2700 |
}
|
2701 |
$value = $this->avalue_dot( $input, $old_data );
|
2702 |
if ( $value ) {
|
2721 |
}
|
2722 |
|
2723 |
/**
|
2724 |
+
* @param int $user_id
|
2725 |
* @param bool $status_name
|
2726 |
*
|
2727 |
* @return bool|mixed
|
2733 |
public function instructor_status( $user_id = 0, $status_name = true ) {
|
2734 |
$user_id = $this->get_user_id( $user_id );
|
2735 |
|
2736 |
+
$instructor_status = apply_filters(
|
2737 |
+
'tutor_instructor_statuses',
|
2738 |
+
array(
|
2739 |
+
'pending' => __( 'Pending', 'tutor' ),
|
2740 |
+
'approved' => __( 'Approved', 'tutor' ),
|
2741 |
+
'blocked' => __( 'Blocked', 'tutor' ),
|
2742 |
+
)
|
2743 |
+
);
|
2744 |
|
2745 |
$status = get_user_meta( $user_id, '_tutor_instructor_status', true );
|
2746 |
|
2747 |
+
if ( isset( $instructor_status[ $status ] ) ) {
|
2748 |
if ( ! $status_name ) {
|
2749 |
return $status;
|
2750 |
}
|
2751 |
+
return $instructor_status[ $status ];
|
2752 |
}
|
2753 |
return false;
|
2754 |
}
|
2762 |
*
|
2763 |
* @since v.1.0.0
|
2764 |
*/
|
2765 |
+
public function get_total_instructors( $search_filter = '' ) {
|
2766 |
global $wpdb;
|
2767 |
|
2768 |
+
sanitize_text_field( $search_filter );
|
|
|
|
|
2769 |
|
2770 |
+
$search_filter = '%' . $wpdb->esc_like( $search_filter ) . '%';
|
2771 |
+
|
2772 |
+
$count = $wpdb->get_var(
|
2773 |
+
$wpdb->prepare(
|
2774 |
+
"SELECT COUNT(user.ID)
|
2775 |
FROM {$wpdb->users} as user
|
2776 |
INNER JOIN {$wpdb->usermeta} as user_meta
|
2777 |
ON ( user_meta.user_id = user.ID )
|
2778 |
+
|
2779 |
WHERE user_meta.meta_key = %s
|
2780 |
AND ( user.display_name LIKE %s OR user.user_email LIKE %s );
|
2781 |
",
|
2782 |
+
'_is_tutor_instructor',
|
2783 |
+
$search_filter,
|
2784 |
+
$search_filter
|
2785 |
+
)
|
2786 |
+
);
|
2787 |
return $count;
|
2788 |
}
|
2789 |
|
2790 |
/**
|
2791 |
+
* @param int $start
|
2792 |
+
* @param int $limit
|
2793 |
* @param string $search_term
|
2794 |
*
|
2795 |
* @return array|null|object
|
2801 |
public function get_instructors( $start = 0, $limit = 10, $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '', $status = null, $cat_ids = array() ) {
|
2802 |
global $wpdb;
|
2803 |
|
2804 |
+
sanitize_text_field( $search_filter );
|
2805 |
+
sanitize_text_field( $course_filter );
|
2806 |
+
sanitize_text_field( $date_filter );
|
2807 |
+
sanitize_text_field( $order_filter );
|
2808 |
|
2809 |
+
$search_filter = '%' . $wpdb->esc_like( $search_filter ) . '%';
|
2810 |
+
$course_filter = $course_filter != '' ? " AND inst_status.meta_key = '_tutor_instructor_course_id' AND inst_status.meta_value = $course_filter " : '';
|
2811 |
|
2812 |
if ( '' != $date_filter ) {
|
2813 |
$date_filter = tutor_get_formated_date( 'Y-m-d', $date_filter );
|
2814 |
}
|
|
|
|
|
2815 |
|
2816 |
+
$date_filter = $date_filter != '' ? " AND DATE(user.user_registered) = '$date_filter' " : '';
|
2817 |
+
|
2818 |
+
$category_join = '';
|
2819 |
$category_where = '';
|
2820 |
|
2821 |
if ( $status ) {
|
2822 |
+
! is_array( $status ) ? $status = array( $status ) : 0;
|
2823 |
|
2824 |
+
$status = array_map(
|
2825 |
+
function( $str ) {
|
2826 |
+
return "'{$str}'";
|
2827 |
+
},
|
2828 |
+
$status
|
2829 |
+
);
|
2830 |
|
2831 |
+
$status = ' AND inst_status.meta_value IN (' . implode( ',', $status ) . ')';
|
2832 |
}
|
2833 |
|
2834 |
+
$cat_ids = array_filter(
|
2835 |
+
$cat_ids,
|
2836 |
+
function( $id ) {
|
2837 |
+
return is_numeric( $id );
|
2838 |
+
}
|
2839 |
+
);
|
2840 |
|
2841 |
+
if ( count( $cat_ids ) ) {
|
2842 |
|
2843 |
$category_join =
|
2844 |
"INNER JOIN {$wpdb->posts} course
|
2850 |
INNER JOIN {$wpdb->prefix}terms term
|
2851 |
ON term.term_id=taxonomy.term_id";
|
2852 |
|
2853 |
+
$cat_ids = implode( ',', $cat_ids );
|
2854 |
$category_where = " AND term.term_id IN ({$cat_ids})";
|
2855 |
}
|
2856 |
|
2857 |
+
$instructors = $wpdb->get_results(
|
2858 |
+
$wpdb->prepare(
|
2859 |
+
"SELECT DISTINCT user.*, user_meta.meta_value AS instructor_from_date
|
2860 |
FROM {$wpdb->users} user
|
2861 |
INNER JOIN {$wpdb->usermeta} user_meta
|
2862 |
+
ON ( user.ID = user_meta.user_id )
|
2863 |
+
INNER JOIN {$wpdb->usermeta} inst_status
|
2864 |
+
ON ( user.ID = inst_status.user_id )
|
2865 |
{$category_join}
|
2866 |
WHERE user_meta.meta_key = %s
|
2867 |
AND ( user.display_name LIKE %s OR user.user_email LIKE %s )
|
2872 |
ORDER BY user_meta.meta_value {$order_filter}
|
2873 |
LIMIT %d, %d;
|
2874 |
",
|
2875 |
+
'_is_tutor_instructor',
|
2876 |
+
$search_filter,
|
2877 |
+
$search_filter,
|
2878 |
+
$start,
|
2879 |
+
$limit
|
2880 |
+
)
|
2881 |
+
);
|
2882 |
|
2883 |
return $instructors;
|
2884 |
}
|
2896 |
global $wpdb;
|
2897 |
$course_id = $this->get_post_id( $course_id );
|
2898 |
|
2899 |
+
$instructors = $wpdb->get_results(
|
2900 |
+
$wpdb->prepare(
|
2901 |
+
"SELECT ID,
|
2902 |
display_name,
|
2903 |
get_course.meta_value AS taught_course_id,
|
2904 |
tutor_job_title.meta_value AS tutor_profile_job_title,
|
2905 |
tutor_bio.meta_value AS tutor_profile_bio,
|
2906 |
+
tutor_photo.meta_value AS tutor_profile_photo
|
2907 |
+
FROM {$wpdb->users}
|
2908 |
+
INNER JOIN {$wpdb->usermeta} get_course
|
2909 |
+
ON ID = get_course.user_id
|
2910 |
+
AND get_course.meta_key = %s
|
2911 |
+
AND get_course.meta_value = %d
|
2912 |
+
LEFT JOIN {$wpdb->usermeta} tutor_job_title
|
2913 |
+
ON ID = tutor_job_title.user_id
|
2914 |
+
AND tutor_job_title.meta_key = %s
|
2915 |
+
LEFT JOIN {$wpdb->usermeta} tutor_bio
|
2916 |
+
ON ID = tutor_bio.user_id
|
2917 |
+
AND tutor_bio.meta_key = %s
|
2918 |
+
LEFT JOIN {$wpdb->usermeta} tutor_photo
|
2919 |
+
ON ID = tutor_photo.user_id
|
2920 |
AND tutor_photo.meta_key = %s
|
2921 |
",
|
2922 |
+
'_tutor_instructor_course_id',
|
2923 |
+
$course_id,
|
2924 |
+
'_tutor_profile_job_title',
|
2925 |
+
'_tutor_profile_bio',
|
2926 |
+
'_tutor_profile_photo'
|
2927 |
+
)
|
2928 |
+
);
|
2929 |
|
2930 |
if ( is_array( $instructors ) && count( $instructors ) ) {
|
2931 |
return $instructors;
|
2949 |
|
2950 |
$course_post_type = tutor()->course_post_type;
|
2951 |
|
2952 |
+
$count = $wpdb->get_var(
|
2953 |
+
$wpdb->prepare(
|
2954 |
+
"SELECT COUNT(enrollment.ID)
|
2955 |
+
FROM {$wpdb->posts} enrollment
|
2956 |
INNER JOIN {$wpdb->posts} course
|
2957 |
ON enrollment.post_parent=course.ID
|
2958 |
WHERE course.post_author = %d
|
2961 |
AND enrollment.post_type = %s
|
2962 |
AND enrollment.post_status = %s;
|
2963 |
",
|
2964 |
+
$instructor_id,
|
2965 |
+
$course_post_type,
|
2966 |
+
'publish',
|
2967 |
+
'tutor_enrolled',
|
2968 |
+
'completed'
|
2969 |
+
)
|
2970 |
+
);
|
2971 |
|
2972 |
return (int) $count;
|
2973 |
}
|
2974 |
|
2975 |
/**
|
2976 |
* Get all students by instructor_id
|
2977 |
+
*
|
2978 |
* @param $instructor_id int | required
|
2979 |
+
*
|
2980 |
* @param $offset int | required
|
2981 |
+
*
|
2982 |
* @param $limit int | required
|
2983 |
+
*
|
2984 |
* @param $search string | optional
|
2985 |
+
*
|
2986 |
* @param $course_id int | optional
|
2987 |
+
*
|
2988 |
* @param $date string | optional
|
2989 |
+
*
|
2990 |
* @return array
|
2991 |
+
*
|
2992 |
* @since 1.9.9
|
2993 |
*/
|
2994 |
public function get_students_by_instructor( int $instructor_id, int $offset, int $limit, $search_filter = '', $course_id = '', $date_filter = '', $order_by = '', $order = '' ): array {
|
2995 |
global $wpdb;
|
2996 |
+
$instructor_id = sanitize_text_field( $instructor_id );
|
2997 |
+
$limit = sanitize_text_field( $limit );
|
2998 |
+
$offset = sanitize_text_field( $offset );
|
2999 |
+
$course_id = sanitize_text_field( $course_id );
|
3000 |
+
$date_filter = sanitize_text_field( $date_filter );
|
3001 |
+
$search_filter = sanitize_text_field( $search_filter );
|
3002 |
+
|
3003 |
+
$order_by = 'user.ID';
|
3004 |
if ( 'registration_date' === $order_by ) {
|
3005 |
$order_by = 'enrollment.post_date';
|
3006 |
+
} elseif ( 'course_taken' === $order_by ) {
|
3007 |
$order_by = 'course_taken';
|
3008 |
} else {
|
3009 |
$order_by = 'user.ID';
|
3010 |
}
|
3011 |
|
3012 |
+
$order = sanitize_text_field( $order );
|
3013 |
|
3014 |
if ( '' !== $date_filter ) {
|
3015 |
$date_filter = \tutor_get_formated_date( 'Y-m-d', $date_filter );
|
3028 |
$date_query = " AND DATE(user.user_registered) = CAST( '$date_filter' AS DATE ) ";
|
3029 |
}
|
3030 |
|
3031 |
+
$students = $wpdb->get_results(
|
3032 |
+
$wpdb->prepare(
|
3033 |
+
"SELECT COUNT(enrollment.post_author) AS course_taken, user.*, (SELECT post_date FROM {$wpdb->posts} WHERE post_author = user.ID LIMIT 1) AS enroll_date
|
3034 |
+
FROM {$wpdb->posts} enrollment
|
3035 |
INNER JOIN {$wpdb->posts} AS course
|
3036 |
ON enrollment.post_parent=course.ID
|
3037 |
INNER JOIN {$wpdb->users} AS user
|
3049 |
ORDER BY {$order_by} {$order}
|
3050 |
LIMIT %d, %d
|
3051 |
",
|
3052 |
+
$instructor_id,
|
3053 |
+
$course_post_type,
|
3054 |
+
'publish',
|
3055 |
+
'tutor_enrolled',
|
3056 |
+
'completed',
|
3057 |
+
$search_query,
|
3058 |
+
$search_query,
|
3059 |
+
$search_query,
|
3060 |
+
$search_query,
|
3061 |
+
$offset,
|
3062 |
+
$limit
|
3063 |
+
)
|
3064 |
+
);
|
3065 |
+
$total_students = $wpdb->get_results(
|
3066 |
+
$wpdb->prepare(
|
3067 |
+
"SELECT COUNT(enrollment.post_author) AS course_taken, user.*, enrollment.post_date AS enroll_date
|
3068 |
+
FROM {$wpdb->posts} enrollment
|
3069 |
+
INNER JOIN {$wpdb->posts} AS course
|
3070 |
+
ON enrollment.post_parent=course.ID
|
3071 |
INNER JOIN {$wpdb->users} AS user
|
3072 |
ON user.ID = enrollment.post_author
|
3073 |
WHERE course.post_author = %d
|
3080 |
{$date_query}
|
3081 |
GROUP BY enrollment.post_author
|
3082 |
ORDER BY {$order_by} {$order}
|
3083 |
+
|
3084 |
",
|
3085 |
+
$instructor_id,
|
3086 |
+
$course_post_type,
|
3087 |
+
'publish',
|
3088 |
+
'tutor_enrolled',
|
3089 |
+
'completed',
|
3090 |
+
$search_query,
|
3091 |
+
$search_query,
|
3092 |
+
$search_query,
|
3093 |
+
$search_query
|
3094 |
+
)
|
3095 |
+
);
|
3096 |
|
3097 |
return array(
|
3098 |
+
'students' => $students,
|
3099 |
+
'total_students' => count( $total_students ),
|
3100 |
);
|
3101 |
}
|
3102 |
|
3103 |
/**
|
3104 |
* Get all course for a give student & instructor id
|
3105 |
+
*
|
3106 |
* @param $student_id int | required
|
3107 |
+
*
|
3108 |
* @param $instructor_id int | required
|
3109 |
+
*
|
3110 |
* @return array
|
3111 |
+
*
|
3112 |
* @since 1.9.9
|
3113 |
*/
|
3114 |
+
public function get_courses_by_student_instructor_id( int $student_id, int $instructor_id ): array {
|
3115 |
global $wpdb;
|
3116 |
$course_post_type = tutor()->course_post_type;
|
3117 |
+
$students = $wpdb->get_results(
|
3118 |
+
$wpdb->prepare(
|
3119 |
+
"SELECT course.*
|
3120 |
+
FROM {$wpdb->posts} enrollment
|
3121 |
INNER JOIN {$wpdb->posts} AS course
|
3122 |
ON enrollment.post_parent=course.ID
|
3123 |
WHERE course.post_author = %d
|
3128 |
AND enrollment.post_author = %d
|
3129 |
ORDER BY course.post_date DESC
|
3130 |
",
|
3131 |
+
$instructor_id,
|
3132 |
+
$course_post_type,
|
3133 |
+
'publish',
|
3134 |
+
'tutor_enrolled',
|
3135 |
+
'completed',
|
3136 |
+
$student_id
|
3137 |
+
)
|
3138 |
+
);
|
3139 |
return $students;
|
3140 |
}
|
3141 |
|
3142 |
/**
|
3143 |
* Get total number of completed assignment
|
3144 |
+
*
|
3145 |
* @param $course_id int | required
|
3146 |
+
*
|
3147 |
* @param $student | required
|
3148 |
+
*
|
3149 |
* @since 1.9.9
|
3150 |
*/
|
3151 |
+
public function get_completed_assignment( int $course_id, int $student_id ): int {
|
3152 |
global $wpdb;
|
3153 |
+
$course_id = sanitize_text_field( $course_id );
|
3154 |
$student_id = sanitize_text_field( $student_id );
|
3155 |
+
$count = $wpdb->get_var(
|
3156 |
+
$wpdb->prepare(
|
3157 |
+
'SELECT COUNT(ID) FROM wp_posts
|
3158 |
INNER JOIN wp_comments c ON c.comment_post_ID = wp_posts.ID AND c.user_id = %d AND c.comment_approved = %s
|
3159 |
WHERE post_parent IN (SELECT ID FROM wp_posts WHERE post_type = %s AND post_parent = %d AND post_status = %s)
|
3160 |
+
AND post_type =%s
|
3161 |
AND post_status = %s
|
3162 |
+
',
|
3163 |
+
$student_id,
|
3164 |
+
'submitted',
|
3165 |
+
'topics',
|
3166 |
+
$course_id,
|
3167 |
+
'publish',
|
3168 |
+
'tutor_assignments',
|
3169 |
+
'publish'
|
3170 |
+
)
|
3171 |
+
);
|
3172 |
return (int) $count;
|
3173 |
}
|
3174 |
/**
|
3175 |
* Get total number of completed quiz
|
3176 |
+
*
|
3177 |
* @param $course_id int | required
|
3178 |
+
*
|
3179 |
* @param $student | required
|
3180 |
+
*
|
3181 |
* @since 1.9.9
|
3182 |
*/
|
3183 |
+
public function get_completed_quiz( int $course_id, int $student_id ): int {
|
3184 |
global $wpdb;
|
3185 |
+
$course_id = sanitize_text_field( $course_id );
|
3186 |
$student_id = sanitize_text_field( $student_id );
|
3187 |
+
$count = $wpdb->get_var(
|
3188 |
+
$wpdb->prepare(
|
3189 |
+
"SELECT COUNT(DISTINCT quiz_id) AS total
|
3190 |
+
FROM {$wpdb->prefix}tutor_quiz_attempts
|
3191 |
+
WHERE course_id = %d
|
3192 |
AND user_id = %d
|
3193 |
AND attempt_status = %s
|
3194 |
",
|
3195 |
+
$course_id,
|
3196 |
+
$student_id,
|
3197 |
+
'attempt_ended'
|
3198 |
+
)
|
3199 |
+
);
|
3200 |
return (int) $count;
|
3201 |
}
|
3202 |
|
3211 |
*/
|
3212 |
public function get_rating_value( $input = 0.00 ) {
|
3213 |
|
3214 |
+
if ( $input > 0 ) {
|
3215 |
+
$input = number_format( $input, 2 );
|
3216 |
$int_value = (int) $input;
|
3217 |
+
$fraction = $input - $int_value;
|
3218 |
|
3219 |
if ( $fraction == 0 ) {
|
3220 |
$fraction = 0.00;
|
3232 |
|
3233 |
/**
|
3234 |
* @param float $current_rating
|
3235 |
+
* @param bool $echo
|
3236 |
*
|
3237 |
* @return string
|
3238 |
*
|
3243 |
public function star_rating_generator( $current_rating = 0.00, $echo = true ) {
|
3244 |
$output = '<div class="tutor-star-rating-group">';
|
3245 |
|
3246 |
+
for ( $i = 1; $i <= 5; $i++ ) {
|
3247 |
$intRating = (int) $current_rating;
|
3248 |
|
3249 |
if ( $intRating >= $i ) {
|
3250 |
+
$output .= '<i class="tutor-icon-star-full" data-rating-value="' . $i . '"></i>';
|
3251 |
} else {
|
3252 |
+
if ( ( $current_rating - $i ) == -0.5 ) {
|
3253 |
+
$output .= '<i class="tutor-icon-star-half" data-rating-value="' . $i . '"></i>';
|
3254 |
} else {
|
3255 |
+
$output .= '<i class="tutor-icon-star-line" data-rating-value="' . $i . '"></i>';
|
3256 |
}
|
3257 |
}
|
3258 |
}
|
3259 |
|
3260 |
+
$output .= '<div class="tutor-rating-gen-input"><input type="hidden" name="tutor_rating_gen_input" value="' . $current_rating . '" /></div>';
|
3261 |
|
3262 |
+
$output .= '</div>';
|
3263 |
|
3264 |
if ( $echo ) {
|
3265 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
3266 |
}
|
3267 |
|
3268 |
return $output;
|
3274 |
* @return string
|
3275 |
*
|
3276 |
* Split string regardless of ASCI, Unicode
|
|
|
|
|
3277 |
*/
|
3278 |
public function str_split( $string ) {
|
3279 |
$strlen = mb_strlen( $string );
|
3280 |
while ( $strlen ) {
|
3281 |
+
$array[] = mb_substr( $string, 0, 1, 'UTF-8' );
|
3282 |
+
$string = mb_substr( $string, 1, $strlen, 'UTF-8' );
|
3283 |
+
$strlen = mb_strlen( $string );
|
3284 |
}
|
3285 |
return $array;
|
3286 |
+
}
|
3287 |
|
3288 |
/**
|
3289 |
* @param null $name
|
3303 |
|
3304 |
$user = $this->get_tutor_user( $user_id );
|
3305 |
if ( $user->tutor_profile_photo ) {
|
3306 |
+
return '<img src="' . wp_get_attachment_image_url( $user->tutor_profile_photo, $size ) . '" class="tutor-image-avatar" alt="" /> ';
|
3307 |
}
|
3308 |
|
3309 |
$name = $user->display_name;
|
3310 |
+
$arr = explode( ' ', trim( $name ) );
|
3311 |
|
3312 |
+
$first_char = ! empty( $arr[0] ) ? $this->str_split( $arr[0] )[0] : '';
|
3313 |
+
$second_char = ! empty( $arr[1] ) ? $this->str_split( $arr[1] )[0] : '';
|
3314 |
+
$initial_avatar = strtoupper( $first_char . $second_char );
|
3315 |
|
3316 |
+
$bg_color = '#' . substr( md5( $initial_avatar ), 0, 6 );
|
3317 |
+
$initial_avatar = '<span class="tutor-text-avatar" style="background-color: ' . $bg_color . '; color: #fff8e5">' . $initial_avatar . '</span>';
|
3318 |
|
3319 |
return $initial_avatar;
|
3320 |
}
|
3331 |
public function get_tutor_user( $user_id ) {
|
3332 |
global $wpdb;
|
3333 |
|
3334 |
+
$user = $wpdb->get_row(
|
3335 |
+
$wpdb->prepare(
|
3336 |
+
"SELECT ID,
|
3337 |
+
display_name,
|
3338 |
+
tutor_job_title.meta_value AS tutor_profile_job_title,
|
3339 |
tutor_bio.meta_value AS tutor_profile_bio,
|
3340 |
tutor_photo.meta_value AS tutor_profile_photo
|
3341 |
FROM {$wpdb->users}
|
3342 |
+
LEFT JOIN {$wpdb->usermeta} tutor_job_title
|
3343 |
+
ON ID = tutor_job_title.user_id
|
3344 |
AND tutor_job_title.meta_key = '_tutor_profile_job_title'
|
3345 |
LEFT JOIN {$wpdb->usermeta} tutor_bio
|
3346 |
ON ID = tutor_bio.user_id
|
3350 |
AND tutor_photo.meta_key = '_tutor_profile_photo'
|
3351 |
WHERE ID = %d
|
3352 |
",
|
3353 |
+
$user_id
|
3354 |
+
)
|
3355 |
+
);
|
3356 |
|
3357 |
return $user;
|
3358 |
}
|
3372 |
$course_id = $this->get_post_id( $course_id );
|
3373 |
global $wpdb;
|
3374 |
|
3375 |
+
$reviews = $wpdb->get_results(
|
3376 |
+
$wpdb->prepare(
|
3377 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
3378 |
+
{$wpdb->comments}.comment_post_ID,
|
3379 |
+
{$wpdb->comments}.comment_author,
|
3380 |
+
{$wpdb->comments}.comment_author_email,
|
3381 |
+
{$wpdb->comments}.comment_date,
|
3382 |
+
{$wpdb->comments}.comment_content,
|
3383 |
+
{$wpdb->comments}.user_id,
|
3384 |
{$wpdb->commentmeta}.meta_value AS rating,
|
3385 |
+
{$wpdb->users}.display_name
|
3386 |
+
|
3387 |
FROM {$wpdb->comments}
|
3388 |
+
INNER JOIN {$wpdb->commentmeta}
|
3389 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3390 |
LEFT JOIN {$wpdb->users}
|
3391 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3392 |
+
WHERE {$wpdb->comments}.comment_post_ID = %d
|
3393 |
AND comment_type = 'tutor_course_rating' AND meta_key = 'tutor_rating'
|
3394 |
ORDER BY comment_ID DESC
|
3395 |
LIMIT %d, %d;
|
3396 |
",
|
3397 |
+
$course_id,
|
3398 |
+
$offset,
|
3399 |
+
$limit
|
3400 |
+
)
|
3401 |
+
);
|
3402 |
|
3403 |
return $reviews;
|
3404 |
}
|
3420 |
'rating_count' => 0,
|
3421 |
'rating_sum' => 0,
|
3422 |
'rating_avg' => 0.00,
|
3423 |
+
'count_by_value' => array(
|
3424 |
+
5 => 0,
|
3425 |
+
4 => 0,
|
3426 |
+
3 => 0,
|
3427 |
+
2 => 0,
|
3428 |
+
1 => 0,
|
3429 |
+
),
|
3430 |
);
|
3431 |
|
3432 |
+
$rating = $wpdb->get_row(
|
3433 |
+
$wpdb->prepare(
|
3434 |
+
"SELECT COUNT(meta_value) AS rating_count,
|
3435 |
SUM(meta_value) AS rating_sum
|
3436 |
FROM {$wpdb->comments}
|
3437 |
INNER JOIN {$wpdb->commentmeta}
|
3439 |
WHERE {$wpdb->comments}.comment_post_ID = %d
|
3440 |
AND {$wpdb->comments}.comment_type = %s
|
3441 |
AND meta_key = %s;
|
3442 |
+
",
|
3443 |
+
$course_id,
|
3444 |
+
'tutor_course_rating',
|
3445 |
+
'tutor_rating'
|
3446 |
+
)
|
3447 |
+
);
|
3448 |
|
3449 |
if ( $rating->rating_count ) {
|
3450 |
$avg_rating = number_format( ( $rating->rating_sum / $rating->rating_count ), 2 );
|
3451 |
|
3452 |
+
$stars = $wpdb->get_results(
|
3453 |
+
$wpdb->prepare(
|
3454 |
+
"SELECT commentmeta.meta_value AS rating,
|
3455 |
+
COUNT(commentmeta.meta_value) as rating_count
|
3456 |
FROM {$wpdb->comments} comments
|
3457 |
INNER JOIN {$wpdb->commentmeta} commentmeta
|
3458 |
ON comments.comment_ID = commentmeta.comment_id
|
3459 |
+
WHERE comments.comment_post_ID = %d
|
3460 |
AND comments.comment_type = %s
|
3461 |
AND commentmeta.meta_key = %s
|
3462 |
GROUP BY commentmeta.meta_value;
|
3463 |
+
",
|
3464 |
+
$course_id,
|
3465 |
+
'tutor_course_rating',
|
3466 |
+
'tutor_rating'
|
3467 |
+
)
|
3468 |
+
);
|
3469 |
|
3470 |
+
$ratings = array(
|
3471 |
+
5 => 0,
|
3472 |
+
4 => 0,
|
3473 |
+
3 => 0,
|
3474 |
+
2 => 0,
|
3475 |
+
1 => 0,
|
3476 |
+
);
|
3477 |
foreach ( $stars as $star ) {
|
3478 |
$index = (int) $star->rating;
|
3479 |
+
array_key_exists( $index, $ratings ) ? $ratings[ $index ] = $star->rating_count : 0;
|
3480 |
}
|
3481 |
|
3482 |
$ratings = array(
|
3483 |
'rating_count' => $rating->rating_count,
|
3484 |
'rating_sum' => $rating->rating_sum,
|
3485 |
'rating_avg' => $avg_rating,
|
3486 |
+
'count_by_value' => $ratings,
|
3487 |
);
|
3488 |
}
|
3489 |
|
3505 |
$user_id = $this->get_user_id( $user_id );
|
3506 |
global $wpdb;
|
3507 |
|
3508 |
+
$reviews = $wpdb->get_results(
|
3509 |
+
$wpdb->prepare(
|
3510 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
3511 |
{$wpdb->comments}.comment_post_ID,
|
3512 |
{$wpdb->comments}.comment_author,
|
3513 |
{$wpdb->comments}.comment_author_email,
|
3516 |
{$wpdb->comments}.user_id,
|
3517 |
{$wpdb->commentmeta}.meta_value as rating,
|
3518 |
{$wpdb->users}.display_name
|
3519 |
+
|
3520 |
FROM {$wpdb->comments}
|
3521 |
+
INNER JOIN {$wpdb->commentmeta}
|
3522 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3523 |
INNER JOIN {$wpdb->users}
|
3524 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3525 |
+
WHERE {$wpdb->comments}.user_id = %d
|
3526 |
AND comment_type = %s
|
3527 |
AND meta_key = %s
|
3528 |
ORDER BY comment_ID DESC
|
3529 |
LIMIT %d, %d;
|
3530 |
",
|
3531 |
+
$user_id,
|
3532 |
+
'tutor_course_rating',
|
3533 |
+
'tutor_rating',
|
3534 |
+
$offset,
|
3535 |
+
$limit
|
3536 |
+
)
|
3537 |
+
);
|
3538 |
|
3539 |
+
if ( $get_object ) {
|
3540 |
+
$count = (int) $wpdb->get_var(
|
3541 |
+
$wpdb->prepare(
|
3542 |
+
"SELECT COUNT({$wpdb->comments}.comment_ID)
|
3543 |
FROM {$wpdb->comments}
|
3544 |
+
INNER JOIN {$wpdb->commentmeta}
|
3545 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3546 |
INNER JOIN {$wpdb->users}
|
3547 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3548 |
+
WHERE {$wpdb->comments}.user_id = %d
|
3549 |
AND comment_type = %s
|
3550 |
AND meta_key = %s",
|
3551 |
+
$user_id,
|
3552 |
+
'tutor_course_rating',
|
3553 |
+
'tutor_rating'
|
3554 |
+
)
|
3555 |
+
);
|
3556 |
|
3557 |
+
return (object) array(
|
3558 |
+
'count' => $count,
|
3559 |
+
'results' => $reviews,
|
3560 |
);
|
3561 |
}
|
3562 |
|
3564 |
}
|
3565 |
|
3566 |
/**
|
3567 |
+
* @param int $user_id
|
3568 |
+
* @param int $offset
|
3569 |
+
* @param int $limit
|
3570 |
*
|
3571 |
* @return array|null|object
|
3572 |
*
|
3573 |
* Get reviews by instructor (Received by the instructor)
|
3574 |
*
|
3575 |
* @since v.1.4.0
|
3576 |
+
*
|
3577 |
* @param $course_id optional
|
3578 |
+
*
|
3579 |
* @param $date_filter optional
|
3580 |
+
*
|
3581 |
* Course id & date filter is sorting with specific course and date
|
3582 |
+
*
|
3583 |
* @since 1.9.9
|
3584 |
*/
|
3585 |
public function get_reviews_by_instructor( $instructor_id = 0, $offset = 0, $limit = 150, $course_id = '', $date_filter = '' ) {
|
3586 |
global $wpdb;
|
3587 |
+
$instructor_id = sanitize_text_field( $instructor_id );
|
3588 |
+
$offset = sanitize_text_field( $offset );
|
3589 |
+
$limit = sanitize_text_field( $limit );
|
3590 |
+
$course_id = sanitize_text_field( $course_id );
|
3591 |
+
$date_filter = sanitize_text_field( $date_filter );
|
3592 |
+
$instructor_id = $this->get_user_id( $instructor_id );
|
3593 |
|
3594 |
+
$course_query = '';
|
3595 |
+
$date_query = '';
|
3596 |
|
3597 |
if ( '' !== $course_id ) {
|
3598 |
$course_query = " AND {$wpdb->comments}.comment_post_ID = {$course_id} ";
|
3599 |
+
}
|
3600 |
if ( '' !== $date_filter ) {
|
3601 |
+
$date_filter = \tutor_get_formated_date( 'Y-m-d', $date_filter );
|
3602 |
+
$date_query = " AND DATE({$wpdb->comments}.comment_date) = CAST( '$date_filter' AS DATE ) ";
|
3603 |
+
}
|
3604 |
|
3605 |
$results = array(
|
3606 |
+
'count' => 0,
|
3607 |
+
'results' => false,
|
3608 |
);
|
3609 |
|
3610 |
$cours_ids = (array) $this->get_assigned_courses_ids_by_instructors( $instructor_id );
|
3612 |
if ( $this->count( $cours_ids ) ) {
|
3613 |
$implode_ids = implode( ',', $cours_ids );
|
3614 |
|
3615 |
+
// Count
|
3616 |
+
$results['count'] = $wpdb->get_var(
|
3617 |
+
$wpdb->prepare(
|
3618 |
+
"SELECT COUNT({$wpdb->comments}.comment_ID)
|
3619 |
FROM {$wpdb->comments}
|
3620 |
INNER JOIN {$wpdb->commentmeta}
|
3621 |
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3622 |
INNER JOIN {$wpdb->users}
|
3623 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3624 |
+
WHERE {$wpdb->comments}.comment_post_ID IN({$implode_ids})
|
3625 |
AND comment_type = %s
|
3626 |
AND meta_key = %s
|
3627 |
{$course_query}
|
3628 |
{$date_query}
|
3629 |
",
|
3630 |
+
'tutor_course_rating',
|
3631 |
+
'tutor_rating'
|
3632 |
+
)
|
3633 |
+
);
|
3634 |
+
|
3635 |
+
// Results
|
3636 |
+
$results['results'] = $wpdb->get_results(
|
3637 |
+
$wpdb->prepare(
|
3638 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
3639 |
+
{$wpdb->comments}.comment_post_ID,
|
3640 |
+
{$wpdb->comments}.comment_author,
|
3641 |
+
{$wpdb->comments}.comment_author_email,
|
3642 |
+
{$wpdb->comments}.comment_date,
|
3643 |
+
{$wpdb->comments}.comment_content,
|
3644 |
+
{$wpdb->comments}.user_id,
|
3645 |
{$wpdb->commentmeta}.meta_value AS rating,
|
3646 |
{$wpdb->users}.display_name,
|
3647 |
{$wpdb->posts}.post_title as course_title
|
3648 |
+
|
3649 |
FROM {$wpdb->comments}
|
3650 |
+
INNER JOIN {$wpdb->commentmeta}
|
3651 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3652 |
INNER JOIN {$wpdb->users}
|
3653 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3654 |
INNER JOIN {$wpdb->posts}
|
3655 |
ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID
|
3656 |
+
WHERE {$wpdb->comments}.comment_post_ID IN({$implode_ids})
|
3657 |
AND comment_type = %s
|
3658 |
AND meta_key = %s
|
3659 |
{$course_query}
|
3661 |
ORDER BY comment_ID DESC
|
3662 |
LIMIT %d, %d;
|
3663 |
",
|
3664 |
+
'tutor_course_rating',
|
3665 |
+
'tutor_rating',
|
3666 |
+
$offset,
|
3667 |
+
$limit
|
3668 |
+
)
|
3669 |
+
);
|
3670 |
}
|
3671 |
|
3672 |
return (object) $results;
|
3685 |
global $wpdb;
|
3686 |
|
3687 |
$ratings = array(
|
3688 |
+
'rating_count' => 0,
|
3689 |
+
'rating_sum' => 0,
|
3690 |
+
'rating_avg' => 0.00,
|
3691 |
);
|
3692 |
|
3693 |
+
$rating = $wpdb->get_row(
|
3694 |
+
$wpdb->prepare(
|
3695 |
+
"SELECT COUNT(rating.meta_value) as rating_count, SUM(rating.meta_value) as rating_sum
|
3696 |
FROM {$wpdb->usermeta} courses
|
3697 |
INNER JOIN {$wpdb->comments} reviews
|
3698 |
ON courses.meta_value = reviews.comment_post_ID
|
3703 |
WHERE courses.user_id = %d
|
3704 |
AND courses.meta_key = %s
|
3705 |
",
|
3706 |
+
$instructor_id,
|
3707 |
+
'_tutor_instructor_course_id'
|
3708 |
+
)
|
3709 |
+
);
|
3710 |
|
3711 |
if ( $rating->rating_count ) {
|
3712 |
$avg_rating = number_format( ( $rating->rating_sum / $rating->rating_count ), 2 );
|
3713 |
|
3714 |
$ratings = array(
|
3715 |
+
'rating_count' => $rating->rating_count,
|
3716 |
+
'rating_sum' => $rating->rating_sum,
|
3717 |
+
'rating_avg' => $avg_rating,
|
3718 |
);
|
3719 |
}
|
3720 |
|
3735 |
global $wpdb;
|
3736 |
|
3737 |
$course_id = $this->get_post_id( $course_id );
|
3738 |
+
$user_id = $this->get_user_id( $user_id );
|
3739 |
|
3740 |
$ratings = array(
|
3741 |
'rating' => 0,
|
3742 |
'review' => '',
|
3743 |
);
|
3744 |
|
3745 |
+
$rating = $wpdb->get_row(
|
3746 |
+
$wpdb->prepare(
|
3747 |
+
"SELECT meta_value AS rating,
|
3748 |
comment_content AS review
|
3749 |
FROM {$wpdb->comments}
|
3750 |
+
INNER JOIN {$wpdb->commentmeta}
|
3751 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3752 |
WHERE {$wpdb->comments}.comment_post_ID = %d
|
3753 |
AND user_id = %d
|
3754 |
AND meta_key = %s;
|
3755 |
",
|
3756 |
+
$course_id,
|
3757 |
+
$user_id,
|
3758 |
+
'tutor_rating'
|
3759 |
+
)
|
3760 |
+
);
|
3761 |
|
3762 |
if ( $rating ) {
|
3763 |
$rating_format = number_format( $rating->rating, 2 );
|
3781 |
public function count_reviews_wrote_by_user( $user_id = 0 ) {
|
3782 |
global $wpdb;
|
3783 |
|
3784 |
+
$user_id = $this->get_user_id( $user_id );
|
3785 |
|
3786 |
+
$count_reviews = $wpdb->get_var(
|
3787 |
+
$wpdb->prepare(
|
3788 |
+
"SELECT COUNT(comment_ID)
|
3789 |
FROM {$wpdb->comments}
|
3790 |
WHERE user_id = %d
|
3791 |
AND comment_type = %s
|
3792 |
",
|
3793 |
+
$user_id,
|
3794 |
+
'tutor_course_rating'
|
3795 |
+
)
|
3796 |
+
);
|
3797 |
|
3798 |
return $count_reviews;
|
3799 |
}
|
3815 |
switch ( strtoupper( $l ) ) {
|
3816 |
case 'P':
|
3817 |
$ret *= 1024;
|
3818 |
+
// No break.
|
3819 |
case 'T':
|
3820 |
$ret *= 1024;
|
3821 |
+
// No break.
|
3822 |
case 'G':
|
3823 |
$ret *= 1024;
|
3824 |
+
// No break.
|
3825 |
case 'M':
|
3826 |
$ret *= 1024;
|
3827 |
+
// No break.
|
3828 |
case 'K':
|
3829 |
$ret *= 1024;
|
3830 |
+
// No break.
|
3831 |
}
|
3832 |
return $ret;
|
3833 |
}
|
3880 |
public function get_top_question( $course_id = 0, $user_id = 0, $offset = 0, $limit = 20, $is_author = false ) {
|
3881 |
global $wpdb;
|
3882 |
|
3883 |
+
$course_id = $this->get_post_id( $course_id );
|
3884 |
+
$user_id = $this->get_user_id( $user_id );
|
3885 |
|
3886 |
+
$author_sql = $is_author ? '' : "AND {$wpdb->comments}.user_id = {$user_id}";
|
3887 |
+
|
3888 |
+
$questions = $wpdb->get_results(
|
3889 |
+
$wpdb->prepare(
|
3890 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
3891 |
+
{$wpdb->comments}.comment_post_ID,
|
3892 |
+
{$wpdb->comments}.comment_author,
|
3893 |
+
{$wpdb->comments}.comment_date,
|
3894 |
+
{$wpdb->comments}.comment_date_gmt,
|
3895 |
+
{$wpdb->comments}.comment_content,
|
3896 |
+
{$wpdb->comments}.user_id,
|
3897 |
+
{$wpdb->commentmeta}.meta_value as question_title,
|
3898 |
+
{$wpdb->users}.display_name
|
3899 |
+
FROM {$wpdb->comments}
|
3900 |
INNER JOIN {$wpdb->commentmeta}
|
3901 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3902 |
INNER JOIN {$wpdb->users}
|
3903 |
+
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3904 |
+
WHERE {$wpdb->comments}.comment_post_ID = {$course_id} {$author_sql}
|
3905 |
+
AND {$wpdb->comments}.comment_type = %s
|
3906 |
+
AND meta_key = %s
|
3907 |
+
ORDER BY comment_ID DESC
|
3908 |
LIMIT %d, %d;
|
3909 |
",
|
3910 |
+
'tutor_q_and_a',
|
3911 |
+
'tutor_question_title',
|
3912 |
+
$offset,
|
3913 |
+
$limit
|
3914 |
+
)
|
3915 |
+
);
|
3916 |
|
3917 |
return $questions;
|
3918 |
}
|
3929 |
public function get_total_qa_question( $search_term = '' ) {
|
3930 |
global $wpdb;
|
3931 |
|
3932 |
+
$user_id = get_current_user_id();
|
3933 |
$course_type = tutor()->course_post_type;
|
3934 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
3935 |
|
3939 |
*/
|
3940 |
if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
|
3941 |
|
3942 |
+
$get_course_ids = $wpdb->get_col(
|
3943 |
+
$wpdb->prepare(
|
3944 |
+
"SELECT ID
|
3945 |
FROM {$wpdb->posts}
|
3946 |
WHERE post_author = %d
|
3947 |
AND post_type = %s
|
3948 |
AND post_status = %s
|
3949 |
",
|
3950 |
+
$user_id,
|
3951 |
+
$course_type,
|
3952 |
+
'publish'
|
3953 |
+
)
|
3954 |
+
);
|
3955 |
|
3956 |
+
$get_assigned_courses_ids = $wpdb->get_col(
|
3957 |
+
$wpdb->prepare(
|
3958 |
+
"SELECT meta_value
|
3959 |
FROM {$wpdb->usermeta}
|
3960 |
WHERE meta_key = %s
|
3961 |
AND user_id = %d
|
3962 |
",
|
3963 |
+
'_tutor_instructor_course_id',
|
3964 |
+
$user_id
|
3965 |
+
)
|
3966 |
+
);
|
3967 |
|
3968 |
$my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
|
3969 |
|
3970 |
if ( $this->count( $my_course_ids ) ) {
|
3971 |
+
$implode_ids = implode( ',', $my_course_ids );
|
3972 |
$in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
|
3973 |
}
|
3974 |
}
|
3978 |
* could be retained thus total number counted and q & a showing
|
3979 |
* list is not similar
|
3980 |
* now only the q & a will be appeared that is belongs to a user
|
3981 |
+
*
|
3982 |
* @since version 1.9.0
|
3983 |
*/
|
3984 |
+
$count = $wpdb->get_var(
|
3985 |
+
$wpdb->prepare(
|
3986 |
+
"SELECT COUNT({$wpdb->comments}.comment_ID)
|
3987 |
FROM {$wpdb->comments}
|
3988 |
INNER JOIN {$wpdb->commentmeta}
|
3989 |
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
3990 |
|
3991 |
+
INNER JOIN {$wpdb->users}
|
3992 |
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
3993 |
|
3994 |
+
WHERE comment_type = %s
|
3995 |
AND comment_parent = 0 {$in_question_id_query}
|
3996 |
AND {$wpdb->commentmeta}.meta_value LIKE %s;
|
3997 |
",
|
3998 |
+
'tutor_q_and_a',
|
3999 |
+
$search_term
|
4000 |
+
)
|
4001 |
+
);
|
4002 |
|
4003 |
return (int) $count;
|
4004 |
}
|
4005 |
|
4006 |
/**
|
4007 |
+
* @param int $start
|
4008 |
+
* @param int $limit
|
4009 |
* @param string $search_term
|
4010 |
*
|
4011 |
* @return array|null|object
|
4027 |
* Get only assinged courses questions if current user is a
|
4028 |
*/
|
4029 |
if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
|
4030 |
+
|
4031 |
+
$get_course_ids = $wpdb->get_col(
|
4032 |
+
$wpdb->prepare(
|
4033 |
+
"SELECT ID
|
4034 |
FROM {$wpdb->posts}
|
4035 |
WHERE post_author = %d
|
4036 |
AND post_type = %s
|
4037 |
AND post_status = %s
|
4038 |
",
|
4039 |
+
$user_id,
|
4040 |
+
$course_type,
|
4041 |
+
'publish'
|
4042 |
+
)
|
4043 |
+
);
|
4044 |
|
4045 |
+
$get_assigned_courses_ids = $wpdb->get_col(
|
4046 |
+
$wpdb->prepare(
|
4047 |
+
"SELECT meta_value
|
4048 |
FROM {$wpdb->usermeta}
|
4049 |
WHERE meta_key = %s
|
4050 |
AND user_id = %d
|
4051 |
",
|
4052 |
+
'_tutor_instructor_course_id',
|
4053 |
+
$user_id
|
4054 |
+
)
|
4055 |
+
);
|
4056 |
|
4057 |
$my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
|
4058 |
|
4059 |
if ( $this->count( $my_course_ids ) ) {
|
4060 |
+
$implode_ids = implode( ',', $my_course_ids );
|
4061 |
$in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
|
4062 |
}
|
4063 |
}
|
4064 |
|
4065 |
+
$query = $wpdb->get_results(
|
4066 |
+
$wpdb->prepare(
|
4067 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
4068 |
+
{$wpdb->comments}.comment_post_ID,
|
4069 |
+
{$wpdb->comments}.comment_author,
|
4070 |
+
{$wpdb->comments}.comment_date,
|
4071 |
+
{$wpdb->comments}.comment_content,
|
4072 |
+
{$wpdb->comments}.user_id,
|
4073 |
+
{$wpdb->commentmeta}.meta_value as question_title,
|
4074 |
+
{$wpdb->users}.display_name,
|
4075 |
+
{$wpdb->posts}.post_title,
|
4076 |
+
( SELECT COUNT(answers_t.comment_ID)
|
4077 |
+
FROM {$wpdb->comments} answers_t
|
4078 |
WHERE answers_t.comment_parent = {$wpdb->comments}.comment_ID
|
4079 |
) AS answer_count
|
4080 |
FROM {$wpdb->comments}
|
4088 |
AND {$wpdb->comments}.comment_parent = 0
|
4089 |
AND {$wpdb->commentmeta}.meta_value LIKE %s
|
4090 |
{$in_question_id_query}
|
4091 |
+
ORDER BY {$wpdb->comments}.comment_ID DESC
|
4092 |
LIMIT %d, %d;
|
4093 |
",
|
4094 |
+
'tutor_q_and_a',
|
4095 |
+
$search_term,
|
4096 |
+
$start,
|
4097 |
+
$limit
|
4098 |
+
)
|
4099 |
+
);
|
4100 |
|
4101 |
return $query;
|
4102 |
}
|
4112 |
*/
|
4113 |
public function get_qa_question( $question_id ) {
|
4114 |
global $wpdb;
|
4115 |
+
$query = $wpdb->get_row(
|
4116 |
+
$wpdb->prepare(
|
4117 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
4118 |
+
{$wpdb->comments}.comment_post_ID,
|
4119 |
+
{$wpdb->comments}.comment_author,
|
4120 |
+
{$wpdb->comments}.comment_date,
|
4121 |
+
{$wpdb->comments}.comment_date_gmt,
|
4122 |
+
{$wpdb->comments}.comment_content,
|
4123 |
+
{$wpdb->comments}.user_id,
|
4124 |
+
{$wpdb->commentmeta}.meta_value as question_title,
|
4125 |
+
{$wpdb->users}.display_name,
|
4126 |
+
{$wpdb->posts}.post_title
|
4127 |
+
FROM {$wpdb->comments}
|
4128 |
+
INNER JOIN {$wpdb->commentmeta}
|
4129 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
4130 |
+
INNER JOIN {$wpdb->posts}
|
4131 |
+
ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
|
4132 |
INNER JOIN {$wpdb->users}
|
4133 |
+
ON {$wpdb->comments}.user_id = {$wpdb->users}.ID
|
4134 |
+
WHERE comment_type = %s
|
4135 |
AND {$wpdb->comments}.comment_ID = %d;
|
4136 |
",
|
4137 |
+
'tutor_q_and_a',
|
4138 |
+
$question_id
|
4139 |
+
)
|
4140 |
+
);
|
4141 |
|
4142 |
return $query;
|
4143 |
}
|
4151 |
*/
|
4152 |
public function get_qa_answer_by_question( $question_id ) {
|
4153 |
global $wpdb;
|
4154 |
+
$query = $wpdb->get_results(
|
4155 |
+
$wpdb->prepare(
|
4156 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
4157 |
{$wpdb->comments}.comment_post_ID,
|
4158 |
{$wpdb->comments}.comment_author,
|
4159 |
{$wpdb->comments}.comment_date,
|
4169 |
AND {$wpdb->comments}.comment_parent = %d
|
4170 |
ORDER BY {$wpdb->comments}.comment_ID ASC;
|
4171 |
",
|
4172 |
+
'tutor_q_and_a',
|
4173 |
+
$question_id
|
4174 |
+
)
|
4175 |
+
);
|
4176 |
|
4177 |
return $query;
|
4178 |
}
|
4181 |
* @param $answer_id
|
4182 |
*
|
4183 |
* @return array|null|object
|
4184 |
+
*
|
4185 |
* @since v1.6.9
|
4186 |
*
|
4187 |
* Get question and asnwer by answer_id
|
4188 |
*/
|
4189 |
public function get_qa_answer_by_answer_id( $answer_id ) {
|
4190 |
global $wpdb;
|
4191 |
+
$answer = $wpdb->get_row(
|
4192 |
+
$wpdb->prepare(
|
4193 |
+
"SELECT answer.comment_post_ID,
|
4194 |
+
answer.comment_content,
|
4195 |
users.display_name,
|
4196 |
question.user_id AS question_by,
|
4197 |
question.comment_content AS question,
|
4198 |
question_meta.meta_value AS question_title
|
4199 |
FROM {$wpdb->comments} answer
|
4200 |
INNER JOIN {$wpdb->users} users
|
4201 |
+
ON answer.user_id = users.id
|
4202 |
+
INNER JOIN {$wpdb->comments} question
|
4203 |
+
ON answer.comment_parent = question.comment_ID
|
4204 |
+
INNER JOIN {$wpdb->commentmeta} question_meta
|
4205 |
ON answer.comment_parent = question_meta.comment_id
|
4206 |
AND question_meta.meta_key = 'tutor_question_title'
|
4207 |
+
WHERE answer.comment_ID = %d
|
4208 |
AND answer.comment_type = %s;
|
4209 |
+
",
|
4210 |
+
$answer_id,
|
4211 |
+
'tutor_q_and_a'
|
4212 |
+
)
|
4213 |
+
);
|
4214 |
|
4215 |
if ( $answer ) {
|
4216 |
return $answer;
|
4226 |
* instructor as it was count unanswered question from all courses
|
4227 |
* from now on it will check if tutor instructor and count
|
4228 |
* from instructor's course
|
4229 |
+
*
|
4230 |
* @since version 1.9.0
|
4231 |
*/
|
4232 |
+
$user_id = get_current_user_id();
|
4233 |
$course_type = tutor()->course_post_type;
|
4234 |
|
4235 |
$in_question_id_query = '';
|
4238 |
*/
|
4239 |
if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
|
4240 |
|
4241 |
+
$get_course_ids = $wpdb->get_col(
|
4242 |
+
$wpdb->prepare(
|
4243 |
+
"SELECT ID
|
4244 |
FROM {$wpdb->posts}
|
4245 |
WHERE post_author = %d
|
4246 |
AND post_type = %s
|
4247 |
AND post_status = %s
|
4248 |
",
|
4249 |
+
$user_id,
|
4250 |
+
$course_type,
|
4251 |
+
'publish'
|
4252 |
+
)
|
4253 |
+
);
|
4254 |
|
4255 |
+
$get_assigned_courses_ids = $wpdb->get_col(
|
4256 |
+
$wpdb->prepare(
|
4257 |
+
"SELECT meta_value
|
4258 |
FROM {$wpdb->usermeta}
|
4259 |
WHERE meta_key = %s
|
4260 |
AND user_id = %d
|
4261 |
",
|
4262 |
+
'_tutor_instructor_course_id',
|
4263 |
+
$user_id
|
4264 |
+
)
|
4265 |
+
);
|
4266 |
|
4267 |
$my_course_ids = array_unique( array_merge( $get_course_ids, $get_assigned_courses_ids ) );
|
4268 |
|
4269 |
if ( $this->count( $my_course_ids ) ) {
|
4270 |
+
$implode_ids = implode( ',', $my_course_ids );
|
4271 |
$in_question_id_query = " AND {$wpdb->comments}.comment_post_ID IN($implode_ids) ";
|
4272 |
}
|
4273 |
}
|
4274 |
|
4275 |
+
$count = $wpdb->get_var(
|
4276 |
+
$wpdb->prepare(
|
4277 |
+
"SELECT COUNT({$wpdb->comments}.comment_ID)
|
4278 |
FROM {$wpdb->comments}
|
4279 |
INNER JOIN {$wpdb->posts}
|
4280 |
ON {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID
|
4284 |
AND {$wpdb->comments}.comment_approved = %s
|
4285 |
AND {$wpdb->comments}.comment_parent = 0 {$in_question_id_query};
|
4286 |
",
|
4287 |
+
'tutor_q_and_a',
|
4288 |
+
'waiting_for_answer'
|
4289 |
+
)
|
4290 |
+
);
|
4291 |
return (int) $count;
|
4292 |
}
|
4293 |
|
4303 |
public function get_announcements( $course_id = 0 ) {
|
4304 |
$course_id = $this->get_post_id( $course_id );
|
4305 |
global $wpdb;
|
4306 |
+
$query = $wpdb->get_results(
|
4307 |
+
$wpdb->prepare(
|
4308 |
+
"SELECT {$wpdb->posts}.ID,
|
4309 |
+
post_author,
|
4310 |
+
post_date,
|
4311 |
+
post_content,
|
4312 |
+
post_title,
|
4313 |
+
display_name
|
4314 |
+
FROM {$wpdb->posts}
|
4315 |
+
INNER JOIN {$wpdb->users}
|
4316 |
+
ON post_author = {$wpdb->users}.ID
|
4317 |
+
WHERE post_type = %s
|
4318 |
AND post_parent = %d
|
4319 |
ORDER BY {$wpdb->posts}.ID DESC;
|
4320 |
",
|
4321 |
+
'tutor_announcements',
|
4322 |
+
$course_id
|
4323 |
+
)
|
4324 |
+
);
|
4325 |
return $query;
|
4326 |
}
|
4327 |
|
4339 |
|
4340 |
$user_display_name = 'User';
|
4341 |
if ( is_user_logged_in() ) {
|
4342 |
+
$user = wp_get_current_user();
|
4343 |
$user_display_name = $user->display_name;
|
4344 |
}
|
4345 |
|
4349 |
}
|
4350 |
|
4351 |
/**
|
4352 |
+
* @param int $post_id
|
4353 |
* @param string $option_key
|
4354 |
+
* @param bool $default
|
4355 |
*
|
4356 |
* @return array|bool|mixed
|
4357 |
*
|
4358 |
* Get the quiz option from meta
|
4359 |
*/
|
4360 |
public function get_quiz_option( $post_id = 0, $option_key = '', $default = false ) {
|
4361 |
+
$post_id = $this->get_post_id( $post_id );
|
4362 |
+
$get_option_meta = maybe_unserialize( get_post_meta( $post_id, 'tutor_quiz_option', true ) );
|
4363 |
|
4364 |
if ( ! $option_key && ! empty( $get_option_meta ) ) {
|
4365 |
return $get_option_meta;
|
4384 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4385 |
global $wpdb;
|
4386 |
|
4387 |
+
$questions = $wpdb->get_results(
|
4388 |
+
$wpdb->prepare(
|
4389 |
+
"SELECT *
|
4390 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4391 |
WHERE quiz_id = %d
|
4392 |
ORDER BY question_order ASC
|
4393 |
",
|
4394 |
+
$quiz_id
|
4395 |
+
)
|
4396 |
+
);
|
4397 |
|
4398 |
if ( is_array( $questions ) && count( $questions ) ) {
|
4399 |
return $questions;
|
4413 |
global $wpdb;
|
4414 |
|
4415 |
if ( $question_id ) {
|
4416 |
+
$question = $wpdb->get_row(
|
4417 |
+
$wpdb->prepare(
|
4418 |
+
"SELECT *
|
4419 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4420 |
WHERE question_id = %d
|
4421 |
LIMIT 0, 1;
|
4422 |
",
|
4423 |
+
$question_id
|
4424 |
+
)
|
4425 |
+
);
|
4426 |
|
4427 |
return $question;
|
4428 |
}
|
4441 |
*/
|
4442 |
public function get_question_types( $type = null ) {
|
4443 |
$types = array(
|
4444 |
+
'true_false' => array(
|
4445 |
+
'name' => __( 'True/False', 'tutor' ),
|
4446 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="True/False"><i class="tutor-icon-block tutor-icon-yes-no"></i></span>',
|
4447 |
+
'is_pro' => false,
|
4448 |
+
),
|
4449 |
+
'single_choice' => array(
|
4450 |
+
'name' => __( 'Single Choice', 'tutor' ),
|
4451 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Single Choice"><i class="tutor-icon-block tutor-icon-mark"></i></span>',
|
4452 |
+
'is_pro' => false,
|
4453 |
+
),
|
4454 |
+
'multiple_choice' => array(
|
4455 |
+
'name' => __( 'Multiple Choice', 'tutor' ),
|
4456 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Multiple Choicee"><i class="tutor-icon-block tutor-icon-multiple-choice"></i></span>',
|
4457 |
+
'is_pro' => false,
|
4458 |
+
),
|
4459 |
+
'open_ended' => array(
|
4460 |
+
'name' => __( 'Open Ended/Essay', 'tutor' ),
|
4461 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Open/Essay"><i class="tutor-icon-block tutor-icon-open-ended"></i></span>',
|
4462 |
+
'is_pro' => false,
|
4463 |
+
),
|
4464 |
+
'fill_in_the_blank' => array(
|
4465 |
+
'name' => __( 'Fill In The Blanks', 'tutor' ),
|
4466 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Fill In The Blanks"><i class="tutor-icon-block tutor-icon-fill-gaps"></i></span>',
|
4467 |
+
'is_pro' => false,
|
4468 |
+
),
|
4469 |
+
'short_answer' => array(
|
4470 |
+
'name' => __( 'Short Answer', 'tutor' ),
|
4471 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Short Answer"><i class="tutor-icon-block tutor-icon-short-ans"></i></span>',
|
4472 |
+
'is_pro' => true,
|
4473 |
+
),
|
4474 |
+
'matching' => array(
|
4475 |
+
'name' => __( 'Matching', 'tutor' ),
|
4476 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Matching"><i class="tutor-icon-block tutor-icon-matching"></i></span>',
|
4477 |
+
'is_pro' => true,
|
4478 |
+
),
|
4479 |
+
'image_matching' => array(
|
4480 |
+
'name' => __( 'Image Matching', 'tutor' ),
|
4481 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Image Matching"><i class="tutor-icon-block tutor-icon-image-matching"></i></span>',
|
4482 |
+
'is_pro' => true,
|
4483 |
+
),
|
4484 |
+
'image_answering' => array(
|
4485 |
+
'name' => __( 'Image Answering', 'tutor' ),
|
4486 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Image Answering"><i class="tutor-icon-block tutor-icon-image-ans"></i></span>',
|
4487 |
+
'is_pro' => true,
|
4488 |
+
),
|
4489 |
+
'ordering' => array(
|
4490 |
+
'name' => __( 'Ordering', 'tutor' ),
|
4491 |
+
'icon' => '<span class="tooltip-btn" data-tooltip="Ordering"><i class="tutor-icon-block tutor-icon-ordering"></i></span>',
|
4492 |
+
'is_pro' => true,
|
4493 |
+
),
|
4494 |
);
|
4495 |
|
4496 |
if ( isset( $types[ $type ] ) ) {
|
4497 |
return $types[ $type ];
|
4498 |
}
|
4499 |
+
|
4500 |
return $types;
|
4501 |
}
|
4502 |
|
4503 |
public function get_quiz_answer_options_by_question( $question_id ) {
|
4504 |
global $wpdb;
|
4505 |
|
4506 |
+
$answer_options = $wpdb->get_results(
|
4507 |
+
$wpdb->prepare(
|
4508 |
+
"SELECT {$wpdb->comments}.comment_ID,
|
4509 |
+
{$wpdb->comments}.comment_post_ID,
|
4510 |
{$wpdb->comments}.comment_content
|
4511 |
FROM {$wpdb->comments}
|
4512 |
+
WHERE {$wpdb->comments}.comment_post_ID = %d
|
4513 |
AND {$wpdb->comments}.comment_type = %s
|
4514 |
ORDER BY {$wpdb->comments}.comment_karma ASC;
|
4515 |
",
|
4516 |
+
$question_id,
|
4517 |
+
'quiz_answer_option'
|
4518 |
+
)
|
4519 |
+
);
|
4520 |
|
4521 |
if ( is_array( $answer_options ) && count( $answer_options ) ) {
|
4522 |
return $answer_options;
|
4536 |
public function quiz_next_question_order_id( $quiz_id ) {
|
4537 |
global $wpdb;
|
4538 |
|
4539 |
+
$last_order = (int) $wpdb->get_var(
|
4540 |
+
$wpdb->prepare(
|
4541 |
+
"SELECT MAX(question_order)
|
4542 |
+
FROM {$wpdb->prefix}tutor_quiz_questions
|
4543 |
WHERE quiz_id = %d ;
|
4544 |
",
|
4545 |
+
$quiz_id
|
4546 |
+
)
|
4547 |
+
);
|
4548 |
|
4549 |
return $last_order + 1;
|
4550 |
}
|
4566 |
|
4567 |
public function get_quiz_id_by_question( $question_id ) {
|
4568 |
global $wpdb;
|
4569 |
+
$quiz_id = $wpdb->get_var(
|
4570 |
+
$wpdb->prepare(
|
4571 |
+
"SELECT quiz_id
|
4572 |
+
FROM {$wpdb->tutor_quiz_questions}
|
4573 |
WHERE question_id = %d;
|
4574 |
",
|
4575 |
+
$question_id
|
4576 |
+
)
|
4577 |
+
);
|
4578 |
return $quiz_id;
|
4579 |
}
|
4580 |
|
4590 |
|
4591 |
$post_id = $this->get_post_id( $post_id );
|
4592 |
|
4593 |
+
$questions = $wpdb->get_results(
|
4594 |
+
$wpdb->prepare(
|
4595 |
+
"SELECT ID,
|
4596 |
post_content,
|
4597 |
post_title,
|
4598 |
post_parent
|
4601 |
AND post_status = %s
|
4602 |
AND post_parent = %d;
|
4603 |
",
|
4604 |
+
'tutor_quiz',
|
4605 |
+
'publish',
|
4606 |
+
$post_id
|
4607 |
+
)
|
4608 |
+
);
|
4609 |
|
4610 |
if ( is_array( $questions ) && count( $questions ) ) {
|
4611 |
return $questions;
|
4627 |
global $wpdb;
|
4628 |
|
4629 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4630 |
+
$post = get_post( $quiz_id );
|
4631 |
|
4632 |
if ( $post ) {
|
4633 |
$course_post_type = tutor()->course_post_type;
|
4634 |
+
$query_string = "SELECT ID, post_author, post_name, post_type, post_parent FROM {$wpdb->posts} where ID = %d";
|
4635 |
+
$course = $wpdb->get_row( $wpdb->prepare( $query_string, $post->post_parent ) );
|
4636 |
+
|
4637 |
if ( $course ) {
|
4638 |
if ( $course->post_type !== $course_post_type ) {
|
4639 |
$course = $wpdb->get_row( $wpdb->prepare( $query_string, $course->post_parent ) );
|
4657 |
global $wpdb;
|
4658 |
|
4659 |
$max_questions_count = (int) tutor_utils()->get_quiz_option( get_the_ID(), 'max_questions_for_answer' );
|
4660 |
+
$total_question = (int) $wpdb->get_var(
|
4661 |
+
$wpdb->prepare(
|
4662 |
+
"SELECT count(question_id)
|
4663 |
FROM {$wpdb->tutor_quiz_questions}
|
4664 |
WHERE quiz_id = %d;
|
4665 |
",
|
4666 |
+
$quiz_id
|
4667 |
+
)
|
4668 |
+
);
|
4669 |
|
4670 |
+
return min( $max_questions_count, $total_question );
|
4671 |
}
|
4672 |
|
4673 |
/**
|
4685 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4686 |
$user_id = get_current_user_id();
|
4687 |
|
4688 |
+
$is_started = $wpdb->get_row(
|
4689 |
+
$wpdb->prepare(
|
4690 |
+
"SELECT *
|
4691 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4692 |
WHERE user_id = %d
|
4693 |
AND quiz_id = %d
|
4694 |
AND attempt_status = %s;
|
4695 |
",
|
4696 |
+
$user_id,
|
4697 |
+
$quiz_id,
|
4698 |
+
'attempt_started'
|
4699 |
+
)
|
4700 |
+
);
|
4701 |
|
4702 |
return $is_started;
|
4703 |
}
|
4717 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4718 |
global $wpdb;
|
4719 |
|
4720 |
+
$max_questions = (int) $wpdb->get_var(
|
4721 |
+
$wpdb->prepare(
|
4722 |
+
"SELECT count(question_id)
|
4723 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4724 |
WHERE quiz_id = %d;
|
4725 |
",
|
4726 |
+
$quiz_id
|
4727 |
+
)
|
4728 |
+
);
|
4729 |
|
4730 |
$max_mentioned = (int) $this->get_quiz_option( $quiz_id, 'max_questions_for_answer', 10 );
|
4731 |
|
4751 |
return false;
|
4752 |
}
|
4753 |
|
4754 |
+
$attempt = $wpdb->get_row(
|
4755 |
+
$wpdb->prepare(
|
4756 |
+
"SELECT *
|
4757 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4758 |
WHERE attempt_id = %d;
|
4759 |
",
|
4760 |
+
$attempt_id
|
4761 |
+
)
|
4762 |
+
);
|
4763 |
|
4764 |
return $attempt;
|
4765 |
}
|
4779 |
|
4780 |
/**
|
4781 |
* @param $quiz_attempt_id
|
4782 |
+
* @param array $attempt_info
|
4783 |
*
|
4784 |
* @return bool|int
|
4785 |
*
|
4788 |
* @since v.1.0.0
|
4789 |
*/
|
4790 |
public function quiz_update_attempt_info( $quiz_attempt_id, $attempt_info = array() ) {
|
4791 |
+
$answers = tutor_utils()->avalue_dot( 'answers', $attempt_info );
|
4792 |
+
$total_marks = array_sum( wp_list_pluck( $answers, 'question_mark' ) );
|
4793 |
+
$earned_marks = tutor_utils()->avalue_dot( 'marks_earned', $attempt_info );
|
4794 |
+
$earned_mark_percent = $earned_marks > 0 ? ( number_format( ( $earned_marks * 100 ) / $total_marks ) ) : 0;
|
4795 |
update_comment_meta( $quiz_attempt_id, 'earned_mark_percent', $earned_mark_percent );
|
4796 |
|
4797 |
+
return update_comment_meta( $quiz_attempt_id, 'quiz_attempt_info', $attempt_info );
|
4798 |
}
|
4799 |
|
4800 |
/**
|
4809 |
public function get_random_question_by_quiz( $quiz_id = 0 ) {
|
4810 |
global $wpdb;
|
4811 |
|
4812 |
+
$quiz_id = $this->get_post_id( $quiz_id );
|
4813 |
$is_attempt = $this->is_started_quiz( $quiz_id );
|
4814 |
|
4815 |
+
$tempSql = " AND question_type = 'matching' ";
|
4816 |
+
$questions = $wpdb->get_results(
|
4817 |
+
$wpdb->prepare(
|
4818 |
+
"SELECT *
|
4819 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4820 |
WHERE quiz_id = %d
|
4821 |
{$tempSql}
|
4822 |
ORDER BY RAND()
|
4823 |
LIMIT 0, 1
|
4824 |
",
|
4825 |
+
$quiz_id
|
4826 |
+
)
|
4827 |
+
);
|
4828 |
|
4829 |
return $questions;
|
4830 |
}
|
4839 |
public function get_random_questions_by_quiz( $quiz_id = 0 ) {
|
4840 |
global $wpdb;
|
4841 |
|
4842 |
+
$quiz_id = $this->get_post_id( $quiz_id );
|
4843 |
+
$attempt = $this->is_started_quiz( $quiz_id );
|
4844 |
$total_questions = (int) $attempt->total_questions;
|
4845 |
if ( ! $attempt ) {
|
4846 |
return false;
|
4848 |
|
4849 |
$questions_order = tutor_utils()->get_quiz_option( get_the_ID(), 'questions_order', 'rand' );
|
4850 |
|
4851 |
+
$order_by = '';
|
4852 |
if ( $questions_order === 'rand' ) {
|
4853 |
+
$order_by = 'ORDER BY RAND()';
|
4854 |
} elseif ( $questions_order === 'asc' ) {
|
4855 |
+
$order_by = 'ORDER BY question_id ASC';
|
4856 |
} elseif ( $questions_order === 'desc' ) {
|
4857 |
+
$order_by = 'ORDER BY question_id DESC';
|
4858 |
} elseif ( $questions_order === 'sorting' ) {
|
4859 |
+
$order_by = 'ORDER BY question_order ASC';
|
4860 |
}
|
4861 |
|
4862 |
$limit = '';
|
4864 |
$limit = "LIMIT {$total_questions} ";
|
4865 |
}
|
4866 |
|
4867 |
+
$questions = $wpdb->get_results(
|
4868 |
+
$wpdb->prepare(
|
4869 |
+
"SELECT *
|
4870 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4871 |
WHERE quiz_id = %d
|
4872 |
{$order_by}
|
4873 |
{$limit}
|
4874 |
",
|
4875 |
+
$quiz_id
|
4876 |
+
)
|
4877 |
+
);
|
4878 |
|
4879 |
return $questions;
|
4880 |
}
|
4881 |
|
4882 |
/**
|
4883 |
* @param $question_id
|
4884 |
+
* @param bool $rand
|
4885 |
*
|
4886 |
* @return array|bool|null|object
|
4887 |
*
|
4892 |
public function get_answers_by_quiz_question( $question_id, $rand = false ) {
|
4893 |
global $wpdb;
|
4894 |
|
4895 |
+
$question = $wpdb->get_row(
|
4896 |
+
$wpdb->prepare(
|
4897 |
+
"SELECT *
|
4898 |
FROM {$wpdb->prefix}tutor_quiz_questions
|
4899 |
WHERE question_id = %d;
|
4900 |
",
|
4901 |
+
$question_id
|
4902 |
+
)
|
4903 |
+
);
|
4904 |
|
4905 |
if ( ! $question ) {
|
4906 |
return false;
|
4907 |
}
|
4908 |
|
4909 |
+
$order = ' answer_order ASC ';
|
4910 |
if ( $question->question_type === 'ordering' ) {
|
4911 |
+
$order = ' RAND() ';
|
4912 |
}
|
4913 |
|
4914 |
+
if ( $rand ) {
|
4915 |
+
$order = ' RAND() ';
|
4916 |
}
|
4917 |
|
4918 |
+
$answers = $wpdb->get_results(
|
4919 |
+
$wpdb->prepare(
|
4920 |
+
"SELECT *
|
4921 |
+
FROM {$wpdb->prefix}tutor_quiz_question_answers
|
4922 |
WHERE belongs_question_id = %d
|
4923 |
AND belongs_question_type = %s
|
4924 |
ORDER BY {$order}
|
4925 |
",
|
4926 |
+
$question_id,
|
4927 |
+
$question->question_type
|
4928 |
+
)
|
4929 |
+
);
|
4930 |
+
|
4931 |
return $answers;
|
4932 |
}
|
4933 |
|
4948 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4949 |
$user_id = $this->get_user_id( $user_id );
|
4950 |
|
4951 |
+
$attempts = $wpdb->get_results(
|
4952 |
+
$wpdb->prepare(
|
4953 |
+
"SELECT *
|
4954 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4955 |
WHERE quiz_id = %d
|
4956 |
AND user_id = %d
|
4957 |
+
ORDER BY attempt_id DESC
|
4958 |
",
|
4959 |
+
$quiz_id,
|
4960 |
+
$user_id
|
4961 |
+
)
|
4962 |
+
);
|
4963 |
|
4964 |
if ( is_array( $attempts ) && count( $attempts ) ) {
|
4965 |
return $attempts;
|
4984 |
$quiz_id = $this->get_post_id( $quiz_id );
|
4985 |
$user_id = $this->get_user_id( $user_id );
|
4986 |
|
4987 |
+
$attempts = $wpdb->get_results(
|
4988 |
+
$wpdb->prepare(
|
4989 |
+
"SELECT *
|
4990 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
4991 |
WHERE quiz_id = %d
|
4992 |
AND user_id = %d
|
4993 |
AND attempt_status != %s
|
4994 |
",
|
4995 |
+
$quiz_id,
|
4996 |
+
$user_id,
|
4997 |
+
'attempt_started'
|
4998 |
+
)
|
4999 |
+
);
|
5000 |
|
5001 |
if ( is_array( $attempts ) && count( $attempts ) ) {
|
5002 |
return $attempts;
|
5019 |
global $wpdb;
|
5020 |
|
5021 |
$user_id = $this->get_user_id( $user_id );
|
5022 |
+
$attempts = $wpdb->get_results(
|
5023 |
+
$wpdb->prepare(
|
5024 |
+
"SELECT *
|
5025 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
5026 |
WHERE user_id = %d
|
5027 |
ORDER BY attempt_id DESC
|
5028 |
",
|
5029 |
+
$user_id
|
5030 |
+
)
|
5031 |
+
);
|
5032 |
|
5033 |
if ( is_array( $attempts ) && count( $attempts ) ) {
|
5034 |
return $attempts;
|
5045 |
* Total number of quiz attempts
|
5046 |
*
|
5047 |
* @since v.1.0.0
|
5048 |
+
*
|
5049 |
* This method is not being in used
|
|
|
|
|
|
|
|
|
5050 |
*
|
5051 |
+
* to get total number of attempt get_quiz_attempts method is enough
|
5052 |
+
*
|
5053 |
+
* @since 1.9.5
|
5054 |
*/
|
5055 |
public function get_total_quiz_attempts( $search_term = '' ) {
|
5056 |
global $wpdb;
|
5057 |
|
5058 |
+
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
5059 |
|
5060 |
+
$count = $wpdb->get_var(
|
5061 |
+
$wpdb->prepare(
|
5062 |
+
"SELECT COUNT(attempt_id)
|
5063 |
FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
|
5064 |
INNER JOIN {$wpdb->posts} quiz
|
5065 |
ON quiz_attempts.quiz_id = quiz.ID
|
5068 |
WHERE attempt_status != %s
|
5069 |
AND ( user_email LIKE %s OR display_name LIKE %s OR post_title LIKE %s )
|
5070 |
",
|
5071 |
+
'attempt_started',
|
5072 |
+
$search_term,
|
5073 |
+
$search_term,
|
5074 |
+
$search_term
|
5075 |
+
)
|
5076 |
+
);
|
5077 |
|
5078 |
return (int) $count;
|
5079 |
}
|
5080 |
|
5081 |
/**
|
5082 |
+
* @param int $start
|
5083 |
+
* @param int $limit
|
5084 |
* @param string $search_term
|
5085 |
*
|
5086 |
* @return array|null|object
|
5089 |
* Get the all quiz attempts
|
5090 |
*
|
5091 |
* @since 1.0.0
|
5092 |
+
*
|
5093 |
+
* Sorting paramas added
|
5094 |
+
*
|
5095 |
* @since 1.9.5
|
5096 |
*/
|
5097 |
+
public function get_quiz_attempts( $start = 0, $limit = 10, $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '' ) {
|
5098 |
global $wpdb;
|
5099 |
|
5100 |
+
$search_filter = '%' . $wpdb->esc_like( $search_filter ) . '%';
|
5101 |
+
$course_filter = $course_filter != '' ? " AND quiz_attempts.course_id = $course_filter " : '';
|
5102 |
+
$date_filter = $date_filter != '' ? tutor_get_formated_date( 'Y-m-d', $date_filter ) : '';
|
5103 |
+
$date_filter = $date_filter != '' ? " AND DATE(quiz_attempts.attempt_started_at) = '$date_filter' " : '';
|
5104 |
|
5105 |
+
$query = $wpdb->get_results(
|
5106 |
+
$wpdb->prepare(
|
5107 |
+
"SELECT quiz_attempts.*, quiz.*, users.*
|
5108 |
FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
|
5109 |
INNER JOIN {$wpdb->posts} quiz
|
5110 |
ON quiz_attempts.quiz_id = quiz.ID
|
5116 |
AND ( users.user_email LIKE %s OR users.display_name LIKE %s OR quiz.post_title LIKE %s OR course.post_title LIKE %s )
|
5117 |
{$course_filter}
|
5118 |
{$date_filter}
|
5119 |
+
ORDER BY quiz_attempts.attempt_ended_at $order_filter
|
5120 |
LIMIT %d, %d;
|
5121 |
",
|
5122 |
+
'attempt_started',
|
5123 |
+
$search_filter,
|
5124 |
+
$search_filter,
|
5125 |
+
$search_filter,
|
5126 |
+
$search_filter,
|
5127 |
+
$start,
|
5128 |
+
$limit
|
5129 |
+
)
|
5130 |
+
);
|
5131 |
|
5132 |
return $query;
|
5133 |
}
|
5134 |
|
5135 |
/**
|
5136 |
* Delete quizattempt for user
|
5137 |
+
*
|
5138 |
* @since v1.9.5
|
5139 |
*/
|
5140 |
+
public function delete_quiz_attempt( $attempt_ids ) {
|
5141 |
global $wpdb;
|
5142 |
|
5143 |
// Singlular to array
|
5144 |
+
! is_array( $attempt_ids ) ? $attempt_ids = array( $attempt_ids ) : 0;
|
5145 |
|
5146 |
+
if ( count( $attempt_ids ) ) {
|
5147 |
+
$attempt_ids = implode( ',', $attempt_ids );
|
5148 |
|
5149 |
+
// Deleting attempt (comment), child attempt and attempt meta (comment meta)
|
5150 |
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_quiz_attempts WHERE attempt_id IN($attempt_ids)" );
|
5151 |
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_quiz_attempt_answers WHERE quiz_attempt_id IN($attempt_ids)" );
|
5152 |
}
|
5153 |
}
|
5154 |
|
5155 |
/**
|
5156 |
+
* Sorting params added on quiz attempt
|
5157 |
+
*
|
5158 |
* SQL query updated
|
5159 |
+
*
|
5160 |
* @since 1.9.5
|
5161 |
*/
|
5162 |
public function get_quiz_attempts_by_course_ids( $start = 0, $limit = 10, $course_ids = array(), $search_filter = '', $course_filter = '', $date_filter = '', $order_filter = '', $user_id = null ) {
|
5163 |
global $wpdb;
|
5164 |
|
5165 |
+
$course_ids = array_map(
|
5166 |
+
function( $id ) {
|
5167 |
+
return "'" . esc_sql( $id ) . "'";
|
5168 |
+
},
|
5169 |
+
$course_ids
|
5170 |
+
);
|
5171 |
|
5172 |
$course_ids_in = implode( ', ', $course_ids );
|
5173 |
|
5174 |
+
$search_filter = $search_filter ? '%' . $wpdb->esc_like( $search_filter ) . '%' : '';
|
5175 |
$search_filter = $search_filter ? "AND ( users.user_email LIKE {$search_filter} OR users.display_name LIKE {$search_filter} OR quiz.post_title LIKE {$search_filter} OR course.post_title LIKE {$search_filter} )" : '';
|
5176 |
|
5177 |
+
$course_filter = $course_filter != '' ? " AND quiz_attempts.course_id = $course_filter " : '';
|
5178 |
+
$date_filter = $date_filter != '' ? tutor_get_formated_date( 'Y-m-d', $date_filter ) : '';
|
5179 |
+
$date_filter = $date_filter != '' ? " AND DATE(quiz_attempts.attempt_started_at) = '$date_filter' " : '';
|
5180 |
|
5181 |
+
$query = $wpdb->get_results(
|
5182 |
+
$wpdb->prepare(
|
5183 |
+
"SELECT quiz_attempts.*, users.*, quiz.*
|
5184 |
+
FROM {$wpdb->prefix}tutor_quiz_attempts AS quiz_attempts
|
5185 |
INNER JOIN {$wpdb->posts} AS quiz
|
5186 |
+
ON quiz_attempts.quiz_id = quiz.ID
|
5187 |
INNER JOIN {$wpdb->users} AS users
|
5188 |
+
ON quiz_attempts.user_id = users.ID
|
5189 |
INNER JOIN {$wpdb->posts} AS course
|
5190 |
+
ON course.ID = quiz_attempts.course_id
|
5191 |
WHERE quiz_attempts.course_id IN (" . $course_ids_in . ")
|
5192 |
AND quiz_attempts.attempt_status != %s
|
5193 |
{$search_filter}
|
5194 |
{$course_filter}
|
5195 |
{$date_filter}
|
5196 |
+
" . ( $user_id ? ' AND user_id=\'' . esc_sql( $user_id ) . '\'' : '' ) . "
|
5197 |
ORDER BY quiz_attempts.attempt_id $order_filter
|
5198 |
LIMIT %d, %d;
|
5199 |
",
|
5200 |
+
'attempt_started',
|
5201 |
+
$start,
|
5202 |
+
$limit
|
5203 |
+
)
|
5204 |
+
);
|
5205 |
|
5206 |
return $query;
|
5207 |
}
|
5208 |
|
5209 |
/**
|
5210 |
* This method is not being in used
|
5211 |
+
*
|
5212 |
+
* to get total number of attempt above method is enough
|
5213 |
+
*
|
5214 |
* @since 1.9.5
|
5215 |
*/
|
5216 |
public function get_total_quiz_attempts_by_course_ids( $course_ids = array(), $search_term = '' ) {
|
5217 |
global $wpdb;
|
5218 |
+
|
5219 |
+
$course_ids = array_map(
|
5220 |
+
function( $id ) {
|
5221 |
+
return "'" . esc_sql( $id ) . "'";
|
5222 |
+
},
|
5223 |
+
$course_ids
|
5224 |
+
);
|
5225 |
|
5226 |
$course_ids_in = implode( ', ', $course_ids );
|
5227 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
5228 |
|
5229 |
+
$count = $wpdb->get_var(
|
5230 |
+
$wpdb->prepare(
|
5231 |
+
"SELECT COUNT(attempt_id)
|
5232 |
+
FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts
|
5233 |
INNER JOIN {$wpdb->posts} quiz
|
5234 |
+
ON quiz_attempts.quiz_id = quiz.ID
|
5235 |
INNER JOIN {$wpdb->users}
|
5236 |
+
ON quiz_attempts.user_id = {$wpdb->users}.ID
|
5237 |
+
WHERE quiz_attempts.course_id IN (" . $course_ids_in . ')
|
5238 |
+
AND attempt_status != %s
|
5239 |
AND ( user_email LIKE %s OR display_name LIKE %s OR post_title LIKE %s )
|
5240 |
+
',
|
5241 |
+
'attempt_started',
|
5242 |
+
$search_term,
|
5243 |
+
$search_term,
|
5244 |
+
$search_term
|
5245 |
+
)
|
5246 |
+
);
|
5247 |
+
|
5248 |
return (int) $count;
|
5249 |
}
|
5250 |
|
5260 |
public function get_quiz_answers_by_attempt_id( $attempt_id ) {
|
5261 |
global $wpdb;
|
5262 |
|
5263 |
+
$results = $wpdb->get_results(
|
5264 |
+
$wpdb->prepare(
|
5265 |
+
"SELECT answers.*,
|
5266 |
+
question.question_title,
|
5267 |
+
question.question_type
|
5268 |
+
FROM {$wpdb->prefix}tutor_quiz_attempt_answers answers
|
5269 |
LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question
|
5270 |
+
ON answers.question_id = question.question_id
|
5271 |
+
WHERE answers.quiz_attempt_id = %d
|
5272 |
ORDER BY attempt_answer_id ASC;
|
5273 |
",
|
5274 |
+
$attempt_id
|
5275 |
+
)
|
5276 |
+
);
|
5277 |
|
5278 |
return $results;
|
5279 |
}
|
5291 |
global $wpdb;
|
5292 |
|
5293 |
! is_array( $answer_id ) ? $answer_id = array( $answer_id ) : 0;
|
5294 |
+
|
5295 |
+
$answer_id = array_map(
|
5296 |
+
function( $id ) {
|
5297 |
+
return "'" . esc_sql( $id ) . "'";
|
5298 |
+
},
|
5299 |
+
$answer_id
|
5300 |
+
);
|
5301 |
|
5302 |
$in_ids_string = implode( ', ', $answer_id );
|
5303 |
+
|
5304 |
+
$answer = $wpdb->get_results(
|
5305 |
+
$wpdb->prepare(
|
5306 |
+
"SELECT answer.*,
|
5307 |
question.question_title,
|
5308 |
question.question_type
|
5309 |
FROM {$wpdb->prefix}tutor_quiz_question_answers answer
|
5310 |
LEFT JOIN {$wpdb->prefix}tutor_quiz_questions question
|
5311 |
ON answer.belongs_question_id = question.question_id
|
5312 |
+
WHERE answer.answer_id IN (" . $in_ids_string . ')
|
5313 |
AND 1 = %d;
|
5314 |
+
',
|
5315 |
+
1
|
5316 |
+
)
|
5317 |
+
);
|
5318 |
|
5319 |
return $answer;
|
5320 |
}
|
5335 |
return false;
|
5336 |
}
|
5337 |
|
5338 |
+
$in_ids = implode( ',', $ids );
|
5339 |
|
5340 |
global $wpdb;
|
5341 |
|
5342 |
+
$query = $wpdb->get_results(
|
5343 |
+
$wpdb->prepare(
|
5344 |
+
"SELECT comment_ID,
|
5345 |
comment_content
|
5346 |
FROM {$wpdb->comments}
|
5347 |
WHERE comment_type = %s
|
5348 |
AND comment_ID IN({$in_ids})
|
5349 |
",
|
5350 |
+
'quiz_answer_option'
|
5351 |
+
)
|
5352 |
+
);
|
5353 |
|
5354 |
if ( is_array( $query ) && count( $query ) ) {
|
5355 |
return $query;
|
5368 |
* @since v.1.0.0
|
5369 |
*/
|
5370 |
public function course_levels( $level = null ) {
|
5371 |
+
$levels = apply_filters(
|
5372 |
+
'tutor_course_level',
|
5373 |
+
array(
|
5374 |
+
'all_levels' => __( 'All Levels', 'tutor' ),
|
5375 |
+
'beginner' => __( 'Beginner', 'tutor' ),
|
5376 |
+
'intermediate' => __( 'Intermediate', 'tutor' ),
|
5377 |
+
'expert' => __( 'Expert', 'tutor' ),
|
5378 |
+
)
|
5379 |
+
);
|
5380 |
|
5381 |
if ( $level ) {
|
5382 |
if ( isset( $levels[ $level ] ) ) {
|
5398 |
*/
|
5399 |
public function user_profile_permalinks() {
|
5400 |
$permalinks = array(
|
5401 |
+
'courses_taken' => __( 'Courses Taken', 'tutor' ),
|
5402 |
);
|
5403 |
|
5404 |
$show_enrolled_course = tutor_utils()->get_option( 'show_courses_completed_by_student' );
|
5454 |
*
|
5455 |
* Get frontend dashboard URL
|
5456 |
*/
|
5457 |
+
public function tutor_dashboard_url( $sub_url = '' ) {
|
5458 |
$page_id = (int) tutor_utils()->get_option( 'tutor_dashboard_page_id' );
|
5459 |
$page_id = apply_filters( 'tutor_dashboard_page_id', $page_id );
|
5460 |
return trailingslashit( get_the_permalink( $page_id ) ) . $sub_url;
|
5464 |
* Get the tutor dashboard page ID
|
5465 |
*
|
5466 |
* @return int
|
|
|
5467 |
*/
|
5468 |
public function dashboard_page_id() {
|
5469 |
$page_id = (int) tutor_utils()->get_option( 'tutor_dashboard_page_id' );
|
5483 |
*/
|
5484 |
public function is_wishlisted( $course_id = 0, $user_id = 0 ) {
|
5485 |
$course_id = $this->get_post_id( $course_id );
|
5486 |
+
$user_id = $this->get_user_id( $user_id );
|
5487 |
if ( ! $user_id ) {
|
5488 |
return false;
|
5489 |
}
|
5490 |
|
5491 |
global $wpdb;
|
5492 |
+
$if_added_to_list = (bool) $wpdb->get_row(
|
5493 |
+
$wpdb->prepare(
|
5494 |
+
"SELECT *
|
5495 |
+
FROM {$wpdb->usermeta}
|
5496 |
WHERE user_id = %d
|
5497 |
AND meta_key = '_tutor_course_wishlist'
|
5498 |
AND meta_value = %d;
|
5499 |
",
|
5500 |
+
$user_id,
|
5501 |
+
$course_id
|
5502 |
+
)
|
5503 |
+
);
|
5504 |
|
5505 |
return $if_added_to_list;
|
5506 |
}
|
5520 |
$user_id = $this->get_user_id( $user_id );
|
5521 |
$course_post_type = tutor()->course_post_type;
|
5522 |
|
5523 |
+
$pageposts = $wpdb->get_results(
|
5524 |
+
$wpdb->prepare(
|
5525 |
+
"SELECT $wpdb->posts.*
|
5526 |
FROM $wpdb->posts
|
5527 |
LEFT JOIN $wpdb->usermeta
|
5528 |
ON ($wpdb->posts.ID = $wpdb->usermeta.meta_value)
|
5532 |
AND $wpdb->usermeta.user_id = %d
|
5533 |
ORDER BY $wpdb->usermeta.umeta_id DESC;
|
5534 |
",
|
5535 |
+
$course_post_type,
|
5536 |
+
'publish',
|
5537 |
+
'_tutor_course_wishlist',
|
5538 |
+
$user_id
|
5539 |
+
),
|
5540 |
+
OBJECT
|
5541 |
+
);
|
5542 |
|
5543 |
return $pageposts;
|
5544 |
}
|
5554 |
*/
|
5555 |
public function most_popular_courses( $limit = 10, $user_id = '' ) {
|
5556 |
global $wpdb;
|
5557 |
+
$limit = sanitize_text_field( $limit );
|
5558 |
+
$user_id = sanitize_text_field( $user_id );
|
5559 |
|
5560 |
$author_query = '';
|
5561 |
if ( '' !== $user_id ) {
|
5562 |
$author_query = "AND course.post_author = $user_id";
|
5563 |
}
|
5564 |
|
5565 |
+
$courses = $wpdb->get_results(
|
5566 |
+
$wpdb->prepare(
|
5567 |
+
"SELECT COUNT(enrolled.ID) AS total_enrolled,
|
5568 |
enrolled.post_parent as course_id,
|
5569 |
course.*
|
5570 |
FROM {$wpdb->posts} enrolled
|
5571 |
INNER JOIN {$wpdb->posts} course
|
5572 |
+
ON enrolled.post_parent = course.ID
|
5573 |
WHERE enrolled.post_type = %s
|
5574 |
AND enrolled.post_status = %s
|
5575 |
{$author_query}
|
5577 |
ORDER BY total_enrolled DESC
|
5578 |
LIMIT 0, %d;
|
5579 |
",
|
5580 |
+
'tutor_enrolled',
|
5581 |
+
'completed',
|
5582 |
+
$limit
|
5583 |
+
)
|
5584 |
+
);
|
5585 |
|
5586 |
return $courses;
|
5587 |
}
|
5598 |
public function most_rated_courses( $limit = 10 ) {
|
5599 |
global $wpdb;
|
5600 |
|
5601 |
+
$result = $wpdb->get_results(
|
5602 |
+
$wpdb->prepare(
|
5603 |
+
"SELECT COUNT(comment_ID) AS total_rating,
|
5604 |
comment_ID,
|
5605 |
comment_post_ID,
|
5606 |
course.*
|
5613 |
ORDER BY total_rating DESC
|
5614 |
LIMIT 0, %d
|
5615 |
;",
|
5616 |
+
'tutor_course_rating',
|
5617 |
+
'approved',
|
5618 |
+
$limit
|
5619 |
+
)
|
5620 |
+
);
|
5621 |
|
5622 |
if ( is_array( $result ) && count( $result ) ) {
|
5623 |
return $result;
|
5658 |
*/
|
5659 |
function get_ip() {
|
5660 |
$ipaddress = '';
|
5661 |
+
if ( getenv( 'HTTP_CLIENT_IP' ) ) {
|
5662 |
$ipaddress = getenv( 'HTTP_CLIENT_IP' );
|
5663 |
+
} elseif ( getenv( 'HTTP_X_FORWARDED_FOR' ) ) {
|
5664 |
$ipaddress = getenv( 'HTTP_X_FORWARDED_FOR' );
|
5665 |
+
} elseif ( getenv( 'HTTP_X_FORWARDED' ) ) {
|
5666 |
$ipaddress = getenv( 'HTTP_X_FORWARDED' );
|
5667 |
+
} elseif ( getenv( 'HTTP_FORWARDED_FOR' ) ) {
|
5668 |
$ipaddress = getenv( 'HTTP_FORWARDED_FOR' );
|
5669 |
+
} elseif ( getenv( 'HTTP_FORWARDED' ) ) {
|
5670 |
$ipaddress = getenv( 'HTTP_FORWARDED' );
|
5671 |
+
} elseif ( getenv( 'REMOTE_ADDR' ) ) {
|
5672 |
$ipaddress = getenv( 'REMOTE_ADDR' );
|
5673 |
+
} else {
|
5674 |
$ipaddress = 'UNKNOWN';
|
5675 |
+
}
|
5676 |
return $ipaddress;
|
5677 |
}
|
5678 |
|
5685 |
*/
|
5686 |
public function tutor_social_share_icons() {
|
5687 |
$icons = array(
|
5688 |
+
'facebook' => array(
|
5689 |
+
'share_class' => 's_facebook',
|
5690 |
+
'icon_html' => '<i class="tutor-icon-facebook"></i>',
|
5691 |
+
),
|
5692 |
+
'twitter' => array(
|
5693 |
+
'share_class' => 's_twitter',
|
5694 |
+
'icon_html' => '<i class="tutor-icon-twitter"></i>',
|
5695 |
+
),
|
5696 |
+
'linkedin' => array(
|
5697 |
+
'share_class' => 's_linkedin',
|
5698 |
+
'icon_html' => '<i class="tutor-icon-linkedin"></i>',
|
5699 |
+
),
|
5700 |
+
'tumblr' => array(
|
5701 |
+
'share_class' => 's_tumblr',
|
5702 |
+
'icon_html' => '<i class="tutor-icon-tumblr"></i>',
|
5703 |
+
),
|
5704 |
);
|
5705 |
|
5706 |
return apply_filters( 'tutor_social_share_icons', $icons );
|
5716 |
public function tutor_user_social_icons() {
|
5717 |
$icons = array(
|
5718 |
'_tutor_profile_website' => array(
|
5719 |
+
'label' => __( 'Website URL', 'tutor' ),
|
5720 |
'placeholder' => 'https://example.com/',
|
5721 |
+
'icon_classes' => 'tutor-icon-earth',
|
5722 |
),
|
5723 |
+
'_tutor_profile_github' => array(
|
5724 |
+
'label' => __( 'Github URL', 'tutor' ),
|
5725 |
'placeholder' => 'https://github.com/username',
|
5726 |
+
'icon_classes' => 'tutor-icon-github-logo',
|
5727 |
),
|
5728 |
+
'_tutor_profile_facebook' => array(
|
5729 |
+
'label' => __( 'Facebook URL', 'tutor' ),
|
5730 |
'placeholder' => 'https://facebook.com/username',
|
5731 |
+
'icon_classes' => 'tutor-icon-facebook',
|
5732 |
),
|
5733 |
'_tutor_profile_twitter' => array(
|
5734 |
+
'label' => __( 'Twitter URL', 'tutor' ),
|
5735 |
'placeholder' => 'https://twitter.com/username',
|
5736 |
+
'icon_classes' => 'tutor-icon-twitter',
|
5737 |
),
|
5738 |
+
'_tutor_profile_linkedin' => array(
|
5739 |
+
'label' => __( 'Linkedin URL', 'tutor' ),
|
5740 |
'placeholder' => 'https://linkedin.com/username',
|
5741 |
+
'icon_classes' => 'tutor-icon-linkedin',
|
5742 |
),
|
5743 |
);
|
5744 |
|
5771 |
*/
|
5772 |
public function tutor_get_screen_ids() {
|
5773 |
$screen_ids = array(
|
5774 |
+
'edit-course',
|
5775 |
+
'course',
|
5776 |
+
'edit-course-category',
|
5777 |
+
'edit-course-tag',
|
5778 |
+
'tutor-lms_page_tutor-students',
|
5779 |
+
'tutor-lms_page_tutor-instructors',
|
5780 |
+
'tutor-lms_page_question_answer',
|
5781 |
+
'tutor-lms_page_tutor_quiz_attempts',
|
5782 |
+
'tutor-lms_page_tutor-addons',
|
5783 |
+
'tutor-lms_page_tutor-status',
|
5784 |
+
'tutor-lms_page_tutor_report',
|
5785 |
+
'tutor-lms_page_tutor_settings',
|
5786 |
+
'tutor-lms_page_tutor_emails',
|
5787 |
);
|
5788 |
|
5789 |
return apply_filters( 'tutor_get_screen_ids', $screen_ids );
|
5799 |
public function get_earnings_completed_statuses() {
|
5800 |
return apply_filters(
|
5801 |
'tutor_get_earnings_completed_statuses',
|
5802 |
+
array(
|
5803 |
'wc-completed',
|
5804 |
'completed',
|
5805 |
'complete',
|
5808 |
}
|
5809 |
|
5810 |
/**
|
5811 |
+
* @param int $user_id
|
5812 |
* @param array $date_filter
|
5813 |
*
|
5814 |
* @return array|null|object
|
5820 |
public function get_earning_sum( $user_id = 0, $date_filter = array() ) {
|
5821 |
global $wpdb;
|
5822 |
|
5823 |
+
$user_id = $this->get_user_id( $user_id );
|
5824 |
$date_query = '';
|
5825 |
|
5826 |
if ( $this->count( $date_filter ) ) {
|
5841 |
$complete_status = tutor_utils()->get_earnings_completed_statuses();
|
5842 |
$complete_status = "'" . implode( "','", $complete_status ) . "'";
|
5843 |
|
5844 |
+
$earning_sum = $wpdb->get_row(
|
5845 |
+
$wpdb->prepare(
|
5846 |
+
"SELECT SUM(course_price_total) AS course_price_total,
|
5847 |
+
SUM(course_price_grand_total) AS course_price_grand_total,
|
5848 |
+
SUM(instructor_amount) AS instructor_amount,
|
5849 |
(SELECT SUM(amount)
|
5850 |
FROM {$wpdb->prefix}tutor_withdraws
|
5851 |
WHERE user_id = {$user_id}
|
5852 |
AND status != 'rejected'
|
5853 |
) AS withdraws_amount,
|
5854 |
+
SUM(admin_amount) AS admin_amount,
|
5855 |
SUM(deduct_fees_amount) AS deduct_fees_amount
|
5856 |
+
FROM {$wpdb->prefix}tutor_earnings
|
5857 |
WHERE user_id = %d
|
5858 |
AND order_status IN({$complete_status})
|
5859 |
{$date_query}
|
5860 |
",
|
5861 |
+
$user_id
|
5862 |
+
)
|
5863 |
+
);
|
5864 |
|
5865 |
+
// TODO: need to check
|
5866 |
// (SUM(instructor_amount) - (SELECT withdraws_amount) ) as balance,
|
5867 |
|
5868 |
if ( $earning_sum->course_price_total ) {
|
5869 |
$earning_sum->balance = $earning_sum->instructor_amount - $earning_sum->withdraws_amount;
|
5870 |
} else {
|
5871 |
$earning_sum = (object) array(
|
5872 |
+
'course_price_total' => 0,
|
5873 |
+
'course_price_grand_total' => 0,
|
5874 |
+
'instructor_amount' => 0,
|
5875 |
+
'withdraws_amount' => 0,
|
5876 |
+
'balance' => 0,
|
5877 |
+
'admin_amount' => 0,
|
5878 |
+
'deduct_fees_amount' => 0,
|
5879 |
);
|
5880 |
}
|
5881 |
|
5883 |
}
|
5884 |
|
5885 |
/**
|
5886 |
+
* @param int $user_id
|
5887 |
* @param array $date_filter
|
5888 |
*
|
5889 |
* @return array|null|object
|
5895 |
public function get_earning_statements( $user_id = 0, $filter_data = array() ) {
|
5896 |
global $wpdb;
|
5897 |
|
5898 |
+
$user_sql = '';
|
5899 |
+
if ( $user_id ) {
|
5900 |
$user_sql = " AND user_id='{$user_id}' ";
|
5901 |
}
|
5902 |
|
5903 |
+
$date_query = '';
|
5904 |
+
$query_by_status = '';
|
5905 |
$pagination_query = '';
|
5906 |
|
5907 |
/**
|
5938 |
}
|
5939 |
|
5940 |
if ( ! empty( $per_page ) ) {
|
5941 |
+
$offset = (int) ! empty( $offset ) ? $offset : 0;
|
5942 |
$pagination_query = " LIMIT {$offset}, {$per_page} ";
|
5943 |
}
|
5944 |
}
|
5945 |
|
|
|
5946 |
/**
|
5947 |
* Delete duplicated earning rows that were created due to not checking if already added while creating new.
|
5948 |
* New entries will check before insert.
|
5949 |
+
*
|
5950 |
* @since v1.9.7
|
5951 |
*/
|
5952 |
+
if ( ! get_option( 'tutor_duplicated_earning_deleted', false ) ) {
|
5953 |
|
5954 |
// Get the duplicated order IDs
|
5955 |
+
$del_rows = array();
|
5956 |
$order_ids = $wpdb->get_col(
|
5957 |
+
"SELECT order_id
|
5958 |
+
FROM (SELECT order_id, COUNT(order_id) AS cnt
|
5959 |
+
FROM {$wpdb->prefix}tutor_earnings
|
5960 |
+
GROUP BY order_id) t
|
5961 |
WHERE cnt>1"
|
5962 |
);
|
5963 |
|
5964 |
+
if ( is_array( $order_ids ) && count( $order_ids ) ) {
|
5965 |
+
$order_ids_string = implode( ',', $order_ids );
|
5966 |
+
$earnings = $wpdb->get_results(
|
5967 |
"SELECT earning_id, course_id FROM {$wpdb->prefix}tutor_earnings
|
5968 |
+
WHERE order_id IN ({$order_ids_string})
|
5969 |
+
ORDER BY earning_id ASC"
|
5970 |
+
);
|
5971 |
|
5972 |
$excluded_first = array();
|
5973 |
+
foreach ( $earnings as $earning ) {
|
5974 |
+
if ( ! in_array( $earning->course_id, $excluded_first ) ) {
|
5975 |
// Exclude first course ID from deletion
|
5976 |
$excluded_first[] = $earning->course_id;
|
5977 |
continue;
|
5981 |
}
|
5982 |
}
|
5983 |
|
5984 |
+
if ( count( $del_rows ) ) {
|
5985 |
+
$ids = implode( ',', $del_rows );
|
5986 |
+
$wpdb->query( "DELETE FROM {$wpdb->prefix}tutor_earnings WHERE earning_id IN ({$ids})" );
|
5987 |
}
|
5988 |
+
|
5989 |
update_option( 'tutor_duplicated_earning_deleted', true );
|
5990 |
}
|
5991 |
|
5992 |
+
$query = $wpdb->get_results(
|
5993 |
+
$wpdb->prepare(
|
5994 |
+
"SELECT earning_tbl.*,
|
5995 |
course.post_title AS course_title
|
5996 |
FROM {$wpdb->prefix}tutor_earnings earning_tbl
|
5997 |
LEFT JOIN {$wpdb->posts} course
|
5999 |
WHERE 1 = %d {$user_sql} {$date_query} {$query_by_status}
|
6000 |
ORDER BY created_at DESC {$pagination_query}
|
6001 |
",
|
6002 |
+
1
|
6003 |
+
)
|
6004 |
+
);
|
6005 |
|
6006 |
+
$query_count = (int) $wpdb->get_var(
|
6007 |
+
$wpdb->prepare(
|
6008 |
+
"SELECT COUNT(earning_tbl.earning_id)
|
6009 |
FROM {$wpdb->prefix}tutor_earnings earning_tbl
|
6010 |
WHERE 1 = %d {$user_sql} {$date_query} {$query_by_status}
|
6011 |
ORDER BY created_at DESC
|
6012 |
",
|
6013 |
+
1
|
6014 |
+
)
|
6015 |
+
);
|
6016 |
|
6017 |
return (object) array(
|
6018 |
'count' => $query_count,
|
6030 |
* @since v.1.1.2
|
6031 |
*/
|
6032 |
public function tutor_price( $price = 0 ) {
|
6033 |
+
if ( function_exists( 'wc_price' ) ) {
|
6034 |
return wc_price( $price );
|
6035 |
} elseif ( function_exists( 'edd_currency_filter' ) ) {
|
6036 |
return edd_currency_filter( edd_format_amount( $price ) );
|
6037 |
+
} else {
|
6038 |
return number_format_i18n( $price );
|
6039 |
}
|
6040 |
}
|
6048 |
*/
|
6049 |
public function currency_symbol() {
|
6050 |
$enable_tutor_edd = tutor_utils()->get_option( 'enable_tutor_edd' );
|
6051 |
+
$monetize_by = $this->get_option( 'monetize_by' );
|
6052 |
|
6053 |
$symbol = '$';
|
6054 |
if ( $enable_tutor_edd && function_exists( 'edd_currency_symbol' ) ) {
|
6081 |
}
|
6082 |
|
6083 |
/**
|
6084 |
+
* @param int $user_id
|
6085 |
* @param array $filter
|
6086 |
*
|
6087 |
* get withdrawal history
|
6092 |
global $wpdb;
|
6093 |
|
6094 |
$filter = (array) $filter;
|
6095 |
+
extract( $filter );
|
6096 |
|
6097 |
+
$query_by_status_sql = '';
|
6098 |
+
$query_by_user_sql = '';
|
6099 |
+
$query_by_pagination = '';
|
6100 |
|
6101 |
if ( ! empty( $status ) ) {
|
6102 |
$status = (array) $status;
|
6106 |
}
|
6107 |
|
6108 |
if ( ! empty( $per_page ) ) {
|
6109 |
+
if ( empty( $start ) ) {
|
6110 |
$start = 0;
|
6111 |
+
}
|
6112 |
|
6113 |
$query_by_pagination = " LIMIT {$start}, {$per_page} ";
|
6114 |
}
|
6117 |
$query_by_user_sql = " AND user_id = {$user_id} ";
|
6118 |
}
|
6119 |
|
6120 |
+
$count = (int) $wpdb->get_var(
|
6121 |
+
$wpdb->prepare(
|
6122 |
+
"SELECT COUNT(withdraw_id)
|
6123 |
FROM {$wpdb->prefix}tutor_withdraws
|
6124 |
WHERE 1 = %d
|
6125 |
{$query_by_user_sql}
|
6126 |
{$query_by_status_sql}
|
6127 |
",
|
6128 |
+
1
|
6129 |
+
)
|
6130 |
+
);
|
6131 |
+
|
6132 |
+
$results = $wpdb->get_results(
|
6133 |
+
$wpdb->prepare(
|
6134 |
+
"SELECT withdraw_tbl.*,
|
6135 |
+
user_tbl.display_name AS user_name,
|
6136 |
+
user_tbl.user_email
|
6137 |
+
FROM {$wpdb->prefix}tutor_withdraws withdraw_tbl
|
6138 |
INNER JOIN {$wpdb->users} user_tbl
|
6139 |
ON withdraw_tbl.user_id = user_tbl.ID
|
6140 |
WHERE 1 = %d
|
6141 |
+
{$query_by_user_sql}
|
6142 |
{$query_by_status_sql}
|
6143 |
ORDER BY created_at DESC
|
6144 |
{$query_by_pagination}
|
6145 |
",
|
6146 |
+
1
|
6147 |
+
)
|
6148 |
+
);
|
6149 |
|
6150 |
$withdraw_history = array(
|
6151 |
'count' => 0,
|
6213 |
public function set_flash_msg( $msg = '', $name = 'success' ) {
|
6214 |
global $wp_filesystem;
|
6215 |
if ( ! $wp_filesystem ) {
|
6216 |
+
require_once ABSPATH . 'wp-admin/includes/file.php';
|
6217 |
}
|
6218 |
|
6219 |
+
$filename = "tutor_flash_msg_{$name}.txt";
|
6220 |
$upload_dir = wp_upload_dir();
|
6221 |
+
$dir = trailingslashit( $upload_dir['basedir'] ) . 'tutor/';
|
6222 |
|
6223 |
WP_Filesystem( false, $upload_dir['basedir'], true );
|
6224 |
|
6243 |
|
6244 |
$upload_dir = wp_get_upload_dir();
|
6245 |
$upload_dir = trailingslashit( $upload_dir['basedir'] );
|
6246 |
+
$msg_name = 'tutor_flash_msg_' . $name;
|
6247 |
|
6248 |
+
$msg = '';
|
6249 |
+
$flash_msg_file_name = $upload_dir . "tutor/{$msg_name}.txt";
|
6250 |
if ( file_exists( $flash_msg_file_name ) ) {
|
6251 |
$msg = file_get_contents( $flash_msg_file_name );
|
6252 |
unlink( $flash_msg_file_name );
|
6268 |
$user_id = $this->get_user_id();
|
6269 |
$monetize_by = tutils()->get_option( 'monetize_by' );
|
6270 |
|
6271 |
+
$post_type = '';
|
6272 |
+
$user_meta = '';
|
6273 |
|
6274 |
if ( $monetize_by === 'wc' ) {
|
6275 |
+
$post_type = 'shop_order';
|
6276 |
+
$user_meta = '_customer_user';
|
6277 |
+
} elseif ( $monetize_by === 'edd' ) {
|
6278 |
+
$post_type = 'edd_payment';
|
6279 |
+
$user_meta = '_edd_payment_user_id';
|
6280 |
}
|
6281 |
|
6282 |
+
$orders = $wpdb->get_results(
|
6283 |
+
$wpdb->prepare(
|
6284 |
+
"SELECT {$wpdb->posts}.*
|
6285 |
FROM {$wpdb->posts}
|
6286 |
INNER JOIN {$wpdb->postmeta} customer
|
6287 |
ON id = customer.post_id
|
6290 |
ON id = tutor_order.post_id
|
6291 |
AND tutor_order.meta_key = '_is_tutor_order_for_course'
|
6292 |
WHERE post_type = %s
|
6293 |
+
AND customer.meta_value = %d
|
6294 |
ORDER BY {$wpdb->posts}.id DESC
|
6295 |
",
|
6296 |
+
$post_type,
|
6297 |
+
$user_id
|
6298 |
+
)
|
6299 |
+
);
|
6300 |
|
6301 |
return $orders;
|
6302 |
}
|
6314 |
$status = str_replace( 'wc-', '', $status );
|
6315 |
$status_name = ucwords( str_replace( '-', ' ', $status ) );
|
6316 |
|
6317 |
+
return '<span class="label-order-status label-status-' . $status . '">' . $status_name . '</span>';
|
6318 |
}
|
6319 |
|
6320 |
/**
|
6321 |
+
* Depricated since v1.9.8
|
6322 |
* This function is redundant and will be removed later
|
6323 |
*/
|
6324 |
public function get_course_id_by_assignment( $assignment_id = 0 ) {
|
6325 |
$assignment_id = $this->get_post_id( $assignment_id );
|
6326 |
+
return $this->get_course_id_by( 'assignment', $assignment_id );
|
6327 |
}
|
6328 |
|
6329 |
/**
|
6330 |
+
* @param int $assignment_id
|
6331 |
* @param string $option_key
|
6332 |
+
* @param bool $default
|
6333 |
*
|
6334 |
* @return array|bool|mixed
|
6335 |
*
|
6339 |
*/
|
6340 |
public function get_assignment_option( $assignment_id = 0, $option_key = '', $default = false ) {
|
6341 |
$assignment_id = $this->get_post_id( $assignment_id );
|
6342 |
+
$get_option_meta = maybe_unserialize( get_post_meta( $assignment_id, 'assignment_option', true ) );
|
6343 |
|
6344 |
if ( ! $option_key && ! empty( $get_option_meta ) ) {
|
6345 |
return $get_option_meta;
|
6368 |
global $wpdb;
|
6369 |
|
6370 |
$assignment_id = $this->get_post_id( $assignment_id );
|
6371 |
+
$user_id = $this->get_user_id( $user_id );
|
6372 |
|
6373 |
+
$is_running_submit = (int) $wpdb->get_var(
|
6374 |
+
$wpdb->prepare(
|
6375 |
+
"SELECT comment_ID
|
6376 |
FROM {$wpdb->comments}
|
6377 |
+
WHERE comment_type = %s
|
6378 |
+
AND comment_approved = %s
|
6379 |
AND user_id = %d
|
6380 |
AND comment_post_ID = %d;
|
6381 |
",
|
6382 |
+
'tutor_assignment',
|
6383 |
+
'submitting',
|
6384 |
+
$user_id,
|
6385 |
+
$assignment_id
|
6386 |
+
)
|
6387 |
+
);
|
6388 |
|
6389 |
return $is_running_submit;
|
6390 |
}
|
6405 |
$assignment_id = $this->get_post_id( $assignment_id );
|
6406 |
$user_id = $this->get_user_id( $user_id );
|
6407 |
|
6408 |
+
$has_submitted = $wpdb->get_row(
|
6409 |
+
$wpdb->prepare(
|
6410 |
+
"SELECT *
|
6411 |
FROM {$wpdb->comments}
|
6412 |
WHERE comment_type = %s
|
6413 |
AND comment_approved = %s
|
6414 |
AND user_id = %d
|
6415 |
AND comment_post_ID = %d;
|
6416 |
",
|
6417 |
+
'tutor_assignment',
|
6418 |
+
'submitted',
|
6419 |
+
$user_id,
|
6420 |
+
$assignment_id
|
6421 |
+
)
|
6422 |
+
);
|
6423 |
|
6424 |
return $has_submitted;
|
6425 |
}
|
6429 |
|
6430 |
$assignment_submitted_id = $this->get_post_id( $assignment_submitted_id );
|
6431 |
|
6432 |
+
$submitted_info = $wpdb->get_row(
|
6433 |
+
$wpdb->prepare(
|
6434 |
+
"SELECT *
|
6435 |
FROM {$wpdb->comments}
|
6436 |
WHERE comment_ID = %d
|
6437 |
AND comment_type = %s
|
6438 |
AND comment_approved = %s;
|
6439 |
",
|
6440 |
+
$assignment_submitted_id,
|
6441 |
+
'tutor_assignment',
|
6442 |
+
'submitted'
|
6443 |
+
)
|
6444 |
+
);
|
6445 |
|
6446 |
return $submitted_info;
|
6447 |
}
|
6453 |
public function get_total_assignments() {
|
6454 |
global $wpdb;
|
6455 |
|
6456 |
+
$count = $wpdb->get_var(
|
6457 |
+
$wpdb->prepare(
|
6458 |
+
"SELECT COUNT(comment_ID)
|
6459 |
FROM {$wpdb->comments}
|
6460 |
WHERE comment_type = %s
|
6461 |
AND comment_approved = %s;
|
6462 |
",
|
6463 |
+
'tutor_assignment',
|
6464 |
+
'submitted'
|
6465 |
+
)
|
6466 |
+
);
|
6467 |
|
6468 |
return (int) $count;
|
6469 |
}
|
6475 |
public function get_assignments() {
|
6476 |
global $wpdb;
|
6477 |
|
6478 |
+
$results = $wpdb->get_results(
|
6479 |
+
$wpdb->prepare(
|
6480 |
+
"SELECT *
|
6481 |
FROM {$wpdb->comments}
|
6482 |
WHERE comment_type = %s
|
6483 |
AND comment_approved = %s;
|
6484 |
",
|
6485 |
+
'tutor_assignment',
|
6486 |
+
'submitted'
|
6487 |
+
)
|
6488 |
+
);
|
6489 |
|
6490 |
return $results;
|
6491 |
}
|
6504 |
$user_id = $this->get_user_id( $user_id );
|
6505 |
$course_post_type = tutor()->course_post_type;
|
6506 |
|
6507 |
+
$get_assigned_courses_ids = $wpdb->get_col(
|
6508 |
+
$wpdb->prepare(
|
6509 |
+
"SELECT meta.meta_value
|
6510 |
+
FROM {$wpdb->usermeta} meta
|
6511 |
+
INNER JOIN {$wpdb->posts} course ON meta.meta_value=course.ID
|
6512 |
+
WHERE meta.meta_key = '_tutor_instructor_course_id'
|
6513 |
AND meta.user_id = %d GROUP BY meta_value",
|
6514 |
+
$user_id
|
6515 |
+
)
|
6516 |
+
);
|
6517 |
|
6518 |
return $get_assigned_courses_ids;
|
6519 |
}
|
6528 |
* @since v.1.3.4
|
6529 |
*/
|
6530 |
public function get_course_categories( $parent = 0 ) {
|
6531 |
+
$args = apply_filters(
|
6532 |
+
'tutor_get_course_categories_args',
|
6533 |
+
array(
|
6534 |
+
'taxonomy' => 'course-category',
|
6535 |
+
'hide_empty' => false,
|
6536 |
+
'parent' => $parent,
|
6537 |
+
)
|
6538 |
+
);
|
6539 |
|
6540 |
$terms = get_terms( $args );
|
6541 |
|
6542 |
$children = array();
|
6543 |
foreach ( $terms as $term ) {
|
6544 |
+
$term->children = $this->get_course_categories( $term->term_id );
|
6545 |
$children[ $term->term_id ] = $term;
|
6546 |
}
|
6547 |
|
6557 |
*
|
6558 |
* @since v.1.9.3
|
6559 |
*/
|
6560 |
+
public function get_course_tags() {
|
6561 |
+
$args = apply_filters(
|
6562 |
+
'tutor_get_course_tags_args',
|
6563 |
+
array(
|
6564 |
+
'taxonomy' => 'course-tag',
|
6565 |
+
'hide_empty' => false,
|
6566 |
+
)
|
6567 |
+
);
|
6568 |
|
6569 |
$terms = get_terms( $args );
|
6570 |
|
6571 |
$children = array();
|
6572 |
foreach ( $terms as $term ) {
|
6573 |
+
$term->children = array();
|
6574 |
$children[ $term->term_id ] = $term;
|
6575 |
}
|
6576 |
|
6587 |
* @since v.1.3.5
|
6588 |
*/
|
6589 |
public function get_course_categories_term( $parent_id = 0 ) {
|
6590 |
+
$args = apply_filters(
|
6591 |
+
'tutor_get_course_categories_terms_args',
|
6592 |
+
array(
|
6593 |
+
'taxonomy' => 'course-category',
|
6594 |
+
'parent' => $parent_id,
|
6595 |
+
'hide_empty' => false,
|
6596 |
+
)
|
6597 |
+
);
|
6598 |
|
6599 |
$terms = get_terms( $args );
|
6600 |
|
6624 |
public function course_edit_link( $course_id = 0 ) {
|
6625 |
$course_id = $this->get_post_id( $course_id );
|
6626 |
|
6627 |
+
$url = admin_url( "post.php?post={$course_id}&action=edit" );
|
6628 |
if ( tutor()->has_pro ) {
|
6629 |
+
$url = $this->tutor_dashboard_url( 'create-course/?course_ID=' . $course_id );
|
6630 |
}
|
6631 |
|
6632 |
return $url;
|
6642 |
$in_course_ids = implode( "','", $course_ids );
|
6643 |
|
6644 |
$pagination_query = $date_query = '';
|
6645 |
+
$sort_query = 'ORDER BY ID DESC';
|
6646 |
if ( $this->count( $filter_data ) ) {
|
6647 |
extract( $filter_data );
|
6648 |
|
6651 |
}
|
6652 |
if ( ! empty( $date_filter ) ) {
|
6653 |
$date_filter = tutor_get_formated_date( 'Y-m-d', $date_filter );
|
6654 |
+
$date_query = " AND DATE(post_date) = '{$date_filter}'";
|
6655 |
}
|
6656 |
if ( ! empty( $order_filter ) ) {
|
6657 |
$sort_query = " ORDER BY ID {$order_filter} ";
|
6662 |
}
|
6663 |
}
|
6664 |
|
6665 |
+
$count = (int) $wpdb->get_var(
|
6666 |
+
$wpdb->prepare(
|
6667 |
+
"SELECT COUNT(ID)
|
6668 |
FROM {$wpdb->postmeta} post_meta
|
6669 |
INNER JOIN {$wpdb->posts} assignment
|
6670 |
ON post_meta.post_id = assignment.ID
|
6673 |
AND post_meta.meta_value IN('$in_course_ids')
|
6674 |
{$date_query}
|
6675 |
",
|
6676 |
+
$assignment_post_type
|
6677 |
+
)
|
6678 |
+
);
|
6679 |
|
6680 |
+
$query = $wpdb->get_results(
|
6681 |
+
$wpdb->prepare(
|
6682 |
+
"SELECT *
|
6683 |
FROM {$wpdb->postmeta} post_meta
|
6684 |
INNER JOIN {$wpdb->posts} assignment
|
6685 |
ON post_meta.post_id = assignment.ID
|
6686 |
AND post_meta.meta_key = '_tutor_course_id_for_assignments'
|
6687 |
WHERE post_type = %s
|
6688 |
+
AND post_meta.meta_value IN('$in_course_ids')
|
6689 |
{$date_query}
|
6690 |
{$sort_query}
|
6691 |
{$pagination_query}
|
6692 |
",
|
6693 |
+
$assignment_post_type
|
6694 |
+
)
|
6695 |
+
);
|
6696 |
|
6697 |
+
return (object) array(
|
6698 |
+
'count' => $count,
|
6699 |
+
'results' => $query,
|
6700 |
+
);
|
6701 |
}
|
6702 |
|
6703 |
/**
|
6715 |
|
6716 |
$assignment_post_type = 'tutor_assignments';
|
6717 |
|
6718 |
+
$count = (int) $wpdb->get_var(
|
6719 |
+
$wpdb->prepare(
|
6720 |
+
"SELECT COUNT(ID)
|
6721 |
FROM {$wpdb->postmeta} post_meta
|
6722 |
INNER JOIN {$wpdb->posts} assignment
|
6723 |
ON post_meta.post_id = assignment.ID
|
6726 |
AND post_meta.meta_value = %d
|
6727 |
ORDER BY ID DESC;
|
6728 |
",
|
6729 |
+
$assignment_post_type,
|
6730 |
+
$course_id
|
6731 |
+
)
|
6732 |
+
);
|
6733 |
|
6734 |
+
$query = $wpdb->get_results(
|
6735 |
+
$wpdb->prepare(
|
6736 |
+
"SELECT *
|
6737 |
FROM {$wpdb->postmeta} post_meta
|
6738 |
INNER JOIN {$wpdb->posts} assignment
|
6739 |
ON post_meta.post_id = assignment.ID
|
6742 |
AND post_meta.meta_value = %d
|
6743 |
ORDER BY ID DESC;
|
6744 |
",
|
6745 |
+
$assignment_post_type,
|
6746 |
+
$course_id
|
6747 |
+
)
|
6748 |
+
);
|
6749 |
|
6750 |
+
return (object) array(
|
6751 |
+
'count' => $count,
|
6752 |
+
'results' => $query,
|
6753 |
+
);
|
6754 |
}
|
6755 |
|
6756 |
/**
|
6788 |
|
6789 |
/**
|
6790 |
* Get total Enrolments
|
6791 |
+
*
|
6792 |
* @since v.1.4.0
|
6793 |
*/
|
6794 |
public function get_total_enrolments( $search_term = '' ) {
|
6796 |
|
6797 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
6798 |
|
6799 |
+
$count = $wpdb->get_var(
|
6800 |
+
$wpdb->prepare(
|
6801 |
+
"SELECT COUNT(enrol.ID)
|
6802 |
FROM {$wpdb->posts} enrol
|
6803 |
INNER JOIN {$wpdb->posts} course
|
6804 |
ON enrol.post_parent = course.ID
|
6807 |
WHERE enrol.post_type = %s
|
6808 |
AND ( enrol.ID LIKE %s OR student.display_name LIKE %s OR student.user_email LIKE %s OR course.post_title LIKE %s );
|
6809 |
",
|
6810 |
+
'tutor_enrolled',
|
6811 |
+
$search_term,
|
6812 |
+
$search_term,
|
6813 |
+
$search_term,
|
6814 |
+
$search_term
|
6815 |
+
)
|
6816 |
+
);
|
6817 |
|
6818 |
return (int) $count;
|
6819 |
}
|
6823 |
|
6824 |
$search_term = '%' . $wpdb->esc_like( $search_term ) . '%';
|
6825 |
|
6826 |
+
$enrolments = $wpdb->get_results(
|
6827 |
+
$wpdb->prepare(
|
6828 |
+
"SELECT enrol.ID AS enrol_id,
|
6829 |
enrol.post_author AS student_id,
|
6830 |
enrol.post_date AS enrol_date,
|
6831 |
enrol.post_title AS enrol_title,
|
6842 |
ON enrol.post_author = student.ID
|
6843 |
WHERE enrol.post_type = %s
|
6844 |
AND ( enrol.ID LIKE %s OR student.display_name LIKE %s OR student.user_email LIKE %s OR course.post_title LIKE %s )
|
6845 |
+
ORDER BY enrol_id DESC
|
6846 |
LIMIT %d, %d;
|
6847 |
",
|
6848 |
+
'tutor_enrolled',
|
6849 |
+
$search_term,
|
6850 |
+
$search_term,
|
6851 |
+
$search_term,
|
6852 |
+
$search_term,
|
6853 |
+
$start,
|
6854 |
+
$limit
|
6855 |
+
)
|
6856 |
+
);
|
6857 |
|
6858 |
return $enrolments;
|
6859 |
}
|
6895 |
'review' => '',
|
6896 |
);
|
6897 |
|
6898 |
+
$rating = $wpdb->get_row(
|
6899 |
+
$wpdb->prepare(
|
6900 |
+
"SELECT meta_value AS rating,
|
6901 |
comment_content AS review
|
6902 |
FROM {$wpdb->comments}
|
6903 |
+
INNER JOIN {$wpdb->commentmeta}
|
6904 |
+
ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id
|
6905 |
WHERE {$wpdb->comments}.comment_ID = %d;
|
6906 |
+
",
|
6907 |
+
$rating_id
|
6908 |
+
)
|
6909 |
+
);
|
6910 |
|
6911 |
if ( $rating ) {
|
6912 |
$rating_format = number_format( $rating->rating, 2 );
|
6913 |
|
6914 |
$ratings = array(
|
6915 |
+
'rating' => $rating_format,
|
6916 |
+
'review' => $rating->review,
|
6917 |
);
|
6918 |
}
|
6919 |
return (object) $ratings;
|
6920 |
}
|
6921 |
|
6922 |
/**
|
6923 |
+
* @param int $course_id
|
6924 |
* @param null $key
|
6925 |
* @param bool $default
|
6926 |
*
|
6937 |
}
|
6938 |
|
6939 |
/**
|
6940 |
+
* @param int $lesson_id
|
6941 |
* @param null $key
|
6942 |
* @param bool $default
|
6943 |
*
|
6972 |
while ( $topics->have_posts() ) {
|
6973 |
$topics->the_post();
|
6974 |
$topic_id = get_the_ID();
|
6975 |
+
$lessons = tutor_utils()->get_course_contents_by_topic( $topic_id, -1 );
|
6976 |
if ( $lessons->have_posts() ) {
|
6977 |
while ( $lessons->have_posts() ) {
|
6978 |
$lessons->the_post();
|
6980 |
$contents[] = $post;
|
6981 |
}
|
6982 |
}
|
|
|
6983 |
}
|
6984 |
}
|
6985 |
|
6986 |
+
if ( tutils()->count( $contents ) ) {
|
6987 |
foreach ( $contents as $key => $content ) {
|
6988 |
if ( $current_item->ID == $content->ID ) {
|
6989 |
+
if ( ! empty( $contents[ $key - 1 ]->ID ) ) {
|
6990 |
+
return $contents[ $key - 1 ]->ID;
|
6991 |
}
|
6992 |
}
|
6993 |
}
|
7007 |
global $wpdb;
|
7008 |
$post = get_post( $post );
|
7009 |
|
7010 |
+
$course_id = $wpdb->get_var(
|
7011 |
+
$wpdb->prepare(
|
7012 |
+
"SELECT post_parent
|
7013 |
FROM {$wpdb->posts}
|
7014 |
WHERE ID = %d
|
7015 |
AND post_type = %s
|
7016 |
",
|
7017 |
+
$post->post_parent,
|
7018 |
+
'topics'
|
7019 |
+
)
|
7020 |
+
);
|
7021 |
|
7022 |
return (int) $course_id;
|
7023 |
}
|
7036 |
|
7037 |
$course_id = $this->get_post_id( $course_id );
|
7038 |
|
7039 |
+
$contents = $wpdb->get_results(
|
7040 |
+
$wpdb->prepare(
|
7041 |
+
"SELECT items.*
|
7042 |
FROM {$wpdb->posts} topic
|
7043 |
INNER JOIN {$wpdb->posts} items
|
7044 |
ON topic.ID = items.post_parent
|
7047 |
ORDER BY topic.menu_order ASC,
|
7048 |
items.menu_order ASC;
|
7049 |
",
|
7050 |
+
$course_id,
|
7051 |
+
'publish'
|
7052 |
+
)
|
7053 |
+
);
|
7054 |
|
7055 |
return $contents;
|
7056 |
}
|
7066 |
*/
|
7067 |
public function get_gradebooks() {
|
7068 |
global $wpdb;
|
7069 |
+
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->tutor_gradebooks} ORDER BY grade_point DESC " );
|
7070 |
return $results;
|
7071 |
}
|
7072 |
|
7090 |
$attempt = false;
|
7091 |
|
7092 |
$quiz_grade_method = get_tutor_option( 'quiz_grade_method', 'highest_grade' );
|
7093 |
+
$from_string = "FROM {$wpdb->tutor_quiz_attempts} WHERE quiz_id = %d AND user_id = %d AND attempt_status != 'attempt_started' ";
|
7094 |
|
7095 |
+
if ( $quiz_grade_method === 'highest_grade' ) {
|
7096 |
|
7097 |
$attempt = $wpdb->get_row( $wpdb->prepare( "SELECT * {$from_string} ORDER BY earned_marks DESC LIMIT 1; ", $quiz_id, $user_id ) );
|
7098 |
|
7099 |
+
} elseif ( $quiz_grade_method === 'average_grade' ) {
|
7100 |
|
7101 |
+
$attempt = $wpdb->get_row(
|
7102 |
+
$wpdb->prepare(
|
7103 |
+
"SELECT {$wpdb->tutor_quiz_attempts}.*,
|
7104 |
COUNT(attempt_id) AS attempt_count,
|
7105 |
AVG(total_marks) AS total_marks,
|
7106 |
AVG(earned_marks) AS earned_marks {$from_string}
|
7107 |
",
|
7108 |
+
$quiz_id,
|
7109 |
+
$user_id
|
7110 |
+
)
|
7111 |
+
);
|
7112 |
|
7113 |
} elseif ( $quiz_grade_method === 'first_attempt' ) {
|
7114 |
|
7139 |
|
7140 |
$html = '';
|
7141 |
if ( $is_completed ) {
|
7142 |
+
$html = '<span class="course-completion-status course-completed"><i class="tutor-icon-mark"></i> ' . __( 'Completed', 'tutor' ) . ' </span>';
|
7143 |
} else {
|
7144 |
$is_in_progress = tutor_utils()->get_completed_lesson_count_by_course( $course_id, $user_id );
|
7145 |
if ( $is_in_progress ) {
|
7146 |
+
$html = '<span class="course-completion-status course-inprogress"><i class="tutor-icon-refresh-button-1"></i> ' . __( 'In Progress', 'tutor' ) . ' </span>';
|
7147 |
} else {
|
7148 |
+
$html = '<span class="course-completion-status course-not-taken"><i class="tutor-icon-spinner"></i> ' . __( 'Not Taken', 'tutor' ) . ' </span>';
|
7149 |
}
|
7150 |
}
|
7151 |
return $html;
|
7179 |
* @since v.1.4.3
|
7180 |
*/
|
7181 |
public function tutor_pages() {
|
7182 |
+
$pages = apply_filters(
|
7183 |
+
'tutor_pages',
|
7184 |
+
array(
|
7185 |
+
'tutor_dashboard_page_id' => __( 'Dashboard Page', 'tutor' ),
|
7186 |
+
'instructor_register_page' => __( 'Instructor Registration Page', 'tutor' ),
|
7187 |
+
'student_register_page' => __( 'Student Registration Page', 'tutor' ),
|
7188 |
+
)
|
7189 |
+
);
|
7190 |
|
7191 |
$new_pages = array();
|
7192 |
foreach ( $pages as $key => $page ) {
|
7203 |
}
|
7204 |
|
7205 |
$new_pages[] = array(
|
7206 |
+
'option_key' => $key,
|
7207 |
+
'page_name' => $page,
|
7208 |
+
'wp_page_name' => $wp_page_name,
|
7209 |
+
'page_id' => $page_id,
|
7210 |
+
'page_exists' => $page_exists,
|
7211 |
+
'page_visible' => $page_visible,
|
7212 |
);
|
7213 |
}
|
7214 |
|
7226 |
*/
|
7227 |
public function get_course_prev_next_contents_by_id( $content_id = 0 ) {
|
7228 |
|
7229 |
+
$course_id = $this->get_course_id_by_content( $content_id );
|
7230 |
+
$course_contents = $this->get_course_contents_by_id( $course_id );
|
7231 |
$previous_id = 0;
|
7232 |
$next_id = 0;
|
7233 |
|
7234 |
if ( $this->count( $course_contents ) ) {
|
7235 |
$ids = wp_list_pluck( $course_contents, 'ID' );
|
7236 |
|
7237 |
+
$i = 0;
|
7238 |
foreach ( $ids as $key => $id ) {
|
7239 |
$previous_i = $key - 1;
|
7240 |
$next_i = $key + 1;
|
7251 |
}
|
7252 |
}
|
7253 |
|
7254 |
+
return (object) array(
|
7255 |
+
'previous_id' => $previous_id,
|
7256 |
+
'next_id' => $next_id,
|
7257 |
+
);
|
7258 |
}
|
7259 |
|
7260 |
/**
|
7261 |
* Get a subset of the items from the given array.
|
7262 |
*
|
7263 |
+
* @param array $array
|
7264 |
+
* @param array|string $keys
|
7265 |
*
|
7266 |
* @return array|bool
|
7267 |
*
|
7285 |
*
|
7286 |
* @since v.1.6.4
|
7287 |
*/
|
7288 |
+
public function is_instructor_of_this_course( $instructor_id = 0, $course_id = 0 ) {
|
7289 |
global $wpdb;
|
7290 |
|
7291 |
+
$instructor_id = $this->get_user_id( $instructor_id );
|
7292 |
+
$course_id = $this->get_post_id( $course_id );
|
7293 |
|
7294 |
if ( ! $instructor_id || ! $course_id ) {
|
7295 |
return false;
|
7296 |
}
|
7297 |
|
7298 |
+
$instructor = $wpdb->get_col(
|
7299 |
+
$wpdb->prepare(
|
7300 |
+
"SELECT umeta_id
|
7301 |
FROM {$wpdb->usermeta}
|
7302 |
WHERE user_id = %d
|
7303 |
AND meta_key = '_tutor_instructor_course_id'
|
7304 |
AND meta_value = %d
|
7305 |
",
|
7306 |
+
$instructor_id,
|
7307 |
+
$course_id
|
7308 |
+
)
|
7309 |
+
);
|
7310 |
+
|
7311 |
+
if ( is_array( $instructor ) && count( $instructor ) ) {
|
7312 |
return $instructor;
|
7313 |
}
|
7314 |
|
7325 |
* @since v.1.6.6
|
7326 |
*/
|
7327 |
public function user_profile_completion( $user_id = 0 ) {
|
7328 |
+
$user_id = $this->get_user_id( $user_id );
|
7329 |
+
$instructor = $this->is_instructor( $user_id );
|
7330 |
$instructor_status = get_user_meta( $user_id, '_tutor_instructor_status', true );
|
7331 |
|
7332 |
+
$required_fields = apply_filters(
|
7333 |
+
'tutor_profile_required_fields',
|
7334 |
+
array(
|
7335 |
+
'first_name' => __( 'First Name', 'tutor' ),
|
7336 |
+
'last_name' => __( 'Last Name', 'tutor' ),
|
7337 |
+
'_tutor_profile_photo' => __( 'Profile Photo', 'tutor' ),
|
7338 |
+
'_tutor_withdraw_method_data' => __( 'Withdraw Method', 'tutor' ),
|
7339 |
+
)
|
7340 |
+
);
|
7341 |
|
7342 |
+
if ( 'approved' !== $instructor_status && array_key_exists( '_tutor_withdraw_method_data', $required_fields ) ) {
|
7343 |
+
unset( $required_fields['_tutor_withdraw_method_data'] );
|
7344 |
}
|
7345 |
|
7346 |
$empty_fields = array();
|
7347 |
foreach ( $required_fields as $key => $field ) {
|
7348 |
$value = get_user_meta( $user_id, $key, true );
|
7349 |
+
if ( ! $value ) {
|
7350 |
array_push( $empty_fields, $field );
|
7351 |
}
|
7352 |
}
|
7353 |
+
|
7354 |
$total_empty_fields = count( $empty_fields );
|
7355 |
$total_required_fields = count( $required_fields );
|
7356 |
$signup_point = apply_filters( 'tutor_profile_completion_signup_point', 50 );
|
7358 |
if ( $total_empty_fields == 0 ) {
|
7359 |
$progress = 100;
|
7360 |
} else {
|
7361 |
+
$completed_field = $total_required_fields - $total_empty_fields;
|
7362 |
$per_field_point = $signup_point / $total_required_fields;
|
7363 |
+
$progress = $signup_point + ceil( $per_field_point * $completed_field );
|
7364 |
}
|
7365 |
|
7366 |
$return = array(
|
7383 |
public function get_enrolment_by_enrol_id( $enrol_id = 0 ) {
|
7384 |
global $wpdb;
|
7385 |
|
7386 |
+
$enrolment = $wpdb->get_row(
|
7387 |
+
$wpdb->prepare(
|
7388 |
+
"SELECT enrol.id AS enrol_id,
|
7389 |
enrol.post_author AS student_id,
|
7390 |
enrol.post_date AS enrol_date,
|
7391 |
enrol.post_title AS enrol_title,
|
7401 |
INNER JOIN {$wpdb->users} student
|
7402 |
ON enrol.post_author = student.id
|
7403 |
WHERE enrol.id = %d;
|
7404 |
+
",
|
7405 |
+
$enrol_id
|
7406 |
+
)
|
7407 |
+
);
|
7408 |
|
7409 |
if ( $enrolment ) {
|
7410 |
return $enrolment;
|
7418 |
global $wpdb;
|
7419 |
$course_id = $this->get_post_id( $course_id );
|
7420 |
|
7421 |
+
$student_data = $wpdb->get_results(
|
7422 |
+
$wpdb->prepare(
|
7423 |
+
"SELECT student.{$field_name}
|
7424 |
FROM {$wpdb->posts} enrol
|
7425 |
INNER JOIN {$wpdb->users} student
|
7426 |
ON enrol.post_author = student.id
|
7427 |
WHERE enrol.post_type = %s
|
7428 |
AND enrol.post_parent = %d
|
7429 |
+
AND enrol.post_status = %s;
|
7430 |
",
|
7431 |
+
'tutor_enrolled',
|
7432 |
+
$course_id,
|
7433 |
+
'completed'
|
7434 |
+
)
|
7435 |
+
);
|
7436 |
|
7437 |
return array_column( $student_data, $field_name );
|
7438 |
}
|
7441 |
* @param int $course_id
|
7442 |
*
|
7443 |
* @return array
|
7444 |
+
*
|
7445 |
* @since v1.6.9
|
7446 |
*
|
7447 |
* Get students email by course id
|
7454 |
*requie post id & user id
|
7455 |
*return single comment post
|
7456 |
*/
|
7457 |
+
public function get_single_comment_user_post_id( $post_id, $user_id ) {
|
7458 |
global $wpdb;
|
7459 |
+
$table = $wpdb->prefix . 'comments';
|
7460 |
+
$query = $wpdb->get_row(
|
7461 |
+
$wpdb->prepare(
|
7462 |
+
"SELECT *
|
7463 |
FROM $table
|
7464 |
WHERE comment_post_ID = %d
|
7465 |
AND user_id = %d
|
7466 |
LIMIT 1
|
7467 |
",
|
7468 |
+
$post_id,
|
7469 |
+
$user_id
|
7470 |
+
)
|
7471 |
+
);
|
7472 |
return $query ? $query : false;
|
7473 |
}
|
7474 |
+
|
7475 |
/**
|
7476 |
* @param int $course_id
|
7477 |
*
|
7478 |
* @return bool
|
7479 |
+
*
|
7480 |
* @since v1.7.5
|
7481 |
*
|
7482 |
* Check if course is in wc cart
|
7483 |
*/
|
7484 |
+
public function is_course_added_to_cart( $course_or_product_id = 0, $is_product_id = false ) {
|
7485 |
+
|
7486 |
+
switch ( $this->get_option( 'monetize_by' ) ) {
|
7487 |
case 'wc':
|
7488 |
global $woocommerce;
|
7489 |
$product_id = $is_product_id ? $course_or_product_id : $this->get_course_product_id( $course_or_product_id );
|
7490 |
+
|
7491 |
if ( $woocommerce->cart ) {
|
7492 |
foreach ( $woocommerce->cart->get_cart() as $key => $val ) {
|
7493 |
if ( $product_id == $val['product_id'] ) {
|
7503 |
* @param int $user_id
|
7504 |
*
|
7505 |
* @return bool
|
7506 |
+
*
|
7507 |
* @since v1.7.5
|
7508 |
*
|
7509 |
* Get profile pic url
|
7512 |
$cover_photo_src = tutor()->url . 'assets/images/cover-photo.jpg';
|
7513 |
$cover_photo_id = get_user_meta( $user_id, '_tutor_cover_photo', true );
|
7514 |
if ( $cover_photo_id ) {
|
7515 |
+
$url = wp_get_attachment_image_url( $cover_photo_id, 'full' );
|
7516 |
! empty( $url ) ? $cover_photo_src = $url : 0;
|
7517 |
}
|
7518 |
|
7521 |
|
7522 |
/**
|
7523 |
* @return int
|
7524 |
+
*
|
7525 |
* @since v1.7.9
|
7526 |
*
|
7527 |
* Return the course ID by lession, quiz, answer etc.
|
7531 |
$course_id = null;
|
7532 |
|
7533 |
switch ( $content ) {
|
7534 |
+
case 'course':
|
7535 |
$course_id = $object_id;
|
7536 |
break;
|
7537 |
|
7538 |
+
case 'topic':
|
7539 |
+
case 'announcement':
|
7540 |
+
$course_id = $wpdb->get_var(
|
7541 |
+
$wpdb->prepare(
|
7542 |
+
"SELECT post_parent
|
7543 |
+
FROM {$wpdb->posts}
|
7544 |
WHERE ID=%d
|
7545 |
LIMIT 1",
|
7546 |
+
$object_id
|
7547 |
+
)
|
7548 |
+
);
|
7549 |
break;
|
7550 |
+
|
7551 |
+
case 'lesson':
|
7552 |
+
case 'quiz':
|
7553 |
+
case 'assignment':
|
7554 |
+
$course_id = $wpdb->get_var(
|
7555 |
+
$wpdb->prepare(
|
7556 |
+
"SELECT post_parent
|
7557 |
+
FROM {$wpdb->posts}
|
7558 |
WHERE ID = (SELECT post_parent FROM {$wpdb->posts} WHERE ID = %d);
|
7559 |
",
|
7560 |
+
$object_id
|
7561 |
+
)
|
7562 |
+
);
|
7563 |
break;
|
7564 |
+
|
7565 |
+
case 'question':
|
7566 |
+
$course_id = $wpdb->get_var(
|
7567 |
+
$wpdb->prepare(
|
7568 |
+
"SELECT topic.post_parent
|
7569 |
FROM {$wpdb->posts} topic
|
7570 |
+
INNER JOIN {$wpdb->posts} quiz
|
7571 |
ON quiz.post_parent=topic.ID
|
7572 |
INNER JOIN {$wpdb->prefix}tutor_quiz_questions question
|
7573 |
ON question.quiz_id=quiz.ID
|
7574 |
WHERE question.question_id = %d;
|
7575 |
",
|
7576 |
+
$object_id
|
7577 |
+
)
|
7578 |
+
);
|
7579 |
break;
|
7580 |
+
|
7581 |
+
case 'quiz_answer':
|
7582 |
+
$course_id = $wpdb->get_var(
|
7583 |
+
$wpdb->prepare(
|
7584 |
+
"SELECT topic.post_parent
|
7585 |
FROM {$wpdb->posts} topic
|
7586 |
INNER JOIN {$wpdb->posts} quiz
|
7587 |
ON quiz.post_parent=topic.ID
|
7591 |
ON answer.belongs_question_id=question.question_id
|
7592 |
WHERE answer.answer_id = %d;
|
7593 |
",
|
7594 |
+
$object_id
|
7595 |
+
)
|
7596 |
+
);
|
7597 |
break;
|
7598 |
+
|
7599 |
+
case 'attempt':
|
7600 |
+
$course_id = $wpdb->get_var(
|
7601 |
+
$wpdb->prepare(
|
7602 |
+
"SELECT course_id
|
7603 |
FROM {$wpdb->prefix}tutor_quiz_attempts
|
7604 |
WHERE attempt_id=%d;
|
7605 |
",
|
7606 |
+
$object_id
|
7607 |
+
)
|
7608 |
+
);
|
7609 |
break;
|
7610 |
|
7611 |
+
case 'attempt_answer':
|
7612 |
+
$course_id = $wpdb->get_var(
|
7613 |
+
$wpdb->prepare(
|
7614 |
+
"SELECT course_id
|
7615 |
+
FROM {$wpdb->prefix}tutor_quiz_attempts
|
7616 |
WHERE attempt_id = (SELECT quiz_attempt_id FROM {$wpdb->prefix}tutor_quiz_attempt_answers WHERE attempt_answer_id=%d)
|
7617 |
",
|
7618 |
+
$object_id
|
7619 |
+
)
|
7620 |
+
);
|
7621 |
break;
|
7622 |
|
7623 |
+
case 'review':
|
7624 |
+
case 'qa_question':
|
7625 |
+
$course_id = $wpdb->get_var(
|
7626 |
+
$wpdb->prepare(
|
7627 |
+
"SELECT comment_post_ID
|
7628 |
FROM {$wpdb->comments}
|
7629 |
WHERE comment_ID = %d;
|
7630 |
",
|
7631 |
+
$object_id
|
7632 |
+
)
|
7633 |
+
);
|
7634 |
break;
|
7635 |
}
|
7636 |
|
7639 |
|
7640 |
/**
|
7641 |
* @return bool
|
7642 |
+
*
|
7643 |
* @since v1.7.7
|
7644 |
*
|
7645 |
+
* Check if user can create, edit, delete various tutor contents such as lesson, quiz, answer etc.
|
7646 |
*/
|
7647 |
+
public function can_user_manage( $content, $object_id, $user_id = 0, $allow_current_admin = true ) {
|
7648 |
+
|
7649 |
+
if ( $allow_current_admin && current_user_can( 'administrator' ) ) {
|
7650 |
// Admin has access to everything
|
7651 |
return true;
|
7652 |
}
|
7653 |
|
7654 |
$course_id = $this->get_course_id_by( $content, $object_id );
|
7655 |
|
7656 |
+
if ( $course_id ) {
|
7657 |
+
|
7658 |
$instructors = $this->get_instructors_by_course( $course_id );
|
7659 |
+
$instructor_ids = is_array( $instructors ) ? array_map(
|
7660 |
+
function( $instructor ) {
|
7661 |
+
return (int) $instructor->ID;
|
7662 |
+
},
|
7663 |
+
$instructors
|
7664 |
+
) : array();
|
7665 |
+
|
7666 |
+
$user_id = (int) $this->get_user_id( $user_id );
|
7667 |
$is_listed = in_array( $user_id, $instructor_ids );
|
7668 |
|
7669 |
return $is_listed;
|
7674 |
|
7675 |
/**
|
7676 |
* @return bool
|
7677 |
+
*
|
7678 |
* @since v1.7.9
|
7679 |
*
|
7680 |
* Check if user has access for content like lesson, quiz, assignment etc.
|
7681 |
*/
|
7682 |
+
public function has_enrolled_content_access( $content, $object_id = 0, $user_id = 0 ) {
|
7683 |
+
$user_id = $this->get_user_id( $user_id );
|
7684 |
+
$object_id = $this->get_post_id( $object_id );
|
7685 |
+
$course_id = $this->get_course_id_by( $content, $object_id );
|
7686 |
$course_content_access = (bool) get_tutor_option( 'course_content_access_for_ia' );
|
7687 |
|
7688 |
do_action( 'tutor_before_enrolment_check', $course_id, $user_id );
|
7693 |
if ( $course_content_access && ( current_user_can( 'administrator' ) || current_user_can( tutor()->instructor_role ) ) ) {
|
7694 |
return true;
|
7695 |
}
|
7696 |
+
// Check Lesson edit access to support page builders (eg: Oxygen)
|
7697 |
+
if ( current_user_can( tutor()->instructor_role ) && tutils()->has_lesson_edit_access() ) {
|
7698 |
return true;
|
7699 |
}
|
7700 |
|
7703 |
|
7704 |
/**
|
7705 |
* @return date
|
7706 |
+
*
|
7707 |
* @since v1.8.0
|
7708 |
*
|
7709 |
* Return the assignment deadline date based on duration and assignment creation date
|
7710 |
*/
|
7711 |
+
public function get_assignment_deadline_date( $assignment_id, $format = null, $fallback = null ) {
|
7712 |
+
|
7713 |
+
! $format ? $format = 'j F, Y, g:i a' : 0;
|
7714 |
|
7715 |
$value = $this->get_assignment_option( $assignment_id, 'time_duration.value' );
|
7716 |
$time = $this->get_assignment_option( $assignment_id, 'time_duration.time' );
|
7717 |
+
|
7718 |
+
if ( ! $value ) {
|
7719 |
return $fallback;
|
7720 |
}
|
7721 |
|
7729 |
|
7730 |
/**
|
7731 |
* @return array
|
7732 |
+
*
|
7733 |
* @since v1.8.2
|
7734 |
*
|
7735 |
* Get earning chart data
|
7747 |
|
7748 |
$datesPeriod = array();
|
7749 |
foreach ( $period as $dt ) {
|
7750 |
+
$datesPeriod[ $dt->format( 'Y-m-d' ) ] = 0;
|
7751 |
}
|
7752 |
|
7753 |
// Get statuses
|
7754 |
$complete_status = tutor_utils()->get_earnings_completed_statuses();
|
7755 |
$statuses = $complete_status;
|
7756 |
+
$complete_status = "'" . implode( "','", $complete_status ) . "'";
|
7757 |
+
|
7758 |
+
$salesQuery = $wpdb->get_results(
|
7759 |
+
$wpdb->prepare(
|
7760 |
+
"SELECT SUM(instructor_amount) AS total_earning,
|
7761 |
+
DATE(created_at) AS date_format
|
7762 |
+
FROM {$wpdb->prefix}tutor_earnings
|
7763 |
+
WHERE user_id = %d
|
7764 |
+
AND order_status IN({$complete_status})
|
7765 |
AND (created_at BETWEEN %s AND %s)
|
7766 |
GROUP BY date_format
|
7767 |
ORDER BY created_at ASC;
|
7768 |
+
",
|
7769 |
+
$user_id,
|
7770 |
+
$start_date,
|
7771 |
+
$end_date
|
7772 |
+
)
|
7773 |
+
);
|
7774 |
|
7775 |
$total_earning = wp_list_pluck( $salesQuery, 'total_earning' );
|
7776 |
$queried_date = wp_list_pluck( $salesQuery, 'date_format' );
|
7779 |
|
7780 |
foreach ( $chartData as $key => $salesCount ) {
|
7781 |
unset( $chartData[ $key ] );
|
7782 |
+
$formatDate = date( 'd M', strtotime( $key ) );
|
7783 |
$chartData[ $formatDate ] = $salesCount;
|
7784 |
}
|
7785 |
|
7786 |
+
$statements = tutor_utils()->get_earning_statements( $user_id, compact( 'start_date', 'end_date', 'statuses' ) );
|
7787 |
$earning_sum = tutor_utils()->get_earning_sum( $user_id, compact( 'start_date', 'end_date' ) );
|
7788 |
|
7789 |
return array(
|
7790 |
+
'chartData' => $chartData,
|
7791 |
'statements' => $statements,
|
7792 |
'statuses' => $statuses,
|
7793 |
'begin' => $begin,
|
7794 |
'end' => $end,
|
7795 |
'earning_sum' => $earning_sum,
|
7796 |
+
'datesPeriod' => $datesPeriod,
|
7797 |
);
|
7798 |
}
|
7799 |
|
7800 |
/**
|
7801 |
* @return array
|
7802 |
+
*
|
7803 |
* @since v1.8.2
|
7804 |
*
|
7805 |
* Get earning chart data yearly
|
7809 |
|
7810 |
$complete_status = tutor_utils()->get_earnings_completed_statuses();
|
7811 |
$statuses = $complete_status;
|
7812 |
+
$complete_status = "'" . implode( "','", $complete_status ) . "'";
|
7813 |
+
|
7814 |
+
$salesQuery = $wpdb->get_results(
|
7815 |
+
$wpdb->prepare(
|
7816 |
+
"SELECT SUM(instructor_amount) AS total_earning,
|
7817 |
+
MONTHNAME(created_at) AS month_name
|
7818 |
+
FROM {$wpdb->prefix}tutor_earnings
|
7819 |
+
WHERE user_id = %d
|
7820 |
+
AND order_status IN({$complete_status})
|
7821 |
+
AND YEAR(created_at) = %s
|
7822 |
+
GROUP BY MONTH (created_at)
|
7823 |
ORDER BY MONTH(created_at) ASC;
|
7824 |
+
",
|
7825 |
+
$user_id,
|
7826 |
+
$year
|
7827 |
+
)
|
7828 |
+
);
|
7829 |
|
7830 |
$total_earning = wp_list_pluck( $salesQuery, 'total_earning' );
|
7831 |
$months = wp_list_pluck( $salesQuery, 'month_name' );
|
7837 |
* Format yearly
|
7838 |
*/
|
7839 |
$emptyMonths = array();
|
7840 |
+
for ( $m = 1; $m <= 12; $m++ ) {
|
7841 |
+
$emptyMonths[ date( 'F', mktime( 0, 0, 0, $m, 1, date( 'Y' ) ) ) ] = 0;
|
7842 |
}
|
7843 |
|
7844 |
$chartData = array_merge( $emptyMonths, $monthWiseSales );
|
7845 |
+
$statements = tutor_utils()->get_earning_statements( $user_id, compact( 'year', 'dataFor', 'statuses' ) );
|
7846 |
$earning_sum = tutor_utils()->get_earning_sum( $user_id, compact( 'year', 'dataFor' ) );
|
7847 |
|
7848 |
+
return array(
|
7849 |
'chartData' => $chartData,
|
7850 |
'statements' => $statements,
|
7851 |
+
'earning_sum' => $earning_sum,
|
7852 |
+
);
|
7853 |
}
|
7854 |
|
7855 |
/**
|
7856 |
* @return object
|
7857 |
+
*
|
7858 |
* @since v1.8.4
|
7859 |
*
|
7860 |
* Return object from vendor package
|
7862 |
function get_package_object() {
|
7863 |
|
7864 |
$params = func_get_args();
|
7865 |
+
|
7866 |
+
$is_pro = $params[0];
|
7867 |
+
$class = $params[1];
|
7868 |
$class_args = array_slice( $params, 2 );
|
7869 |
+
$root_path = $is_pro ? tutor_pro()->path : tutor()->path;
|
7870 |
|
7871 |
require_once $root_path . '/vendor/autoload.php';
|
7872 |
+
|
7873 |
$reflector = new \ReflectionClass( $class );
|
7874 |
+
$object = $reflector->newInstanceArgs( $class_args );
|
7875 |
|
7876 |
return $object;
|
7877 |
}
|
7878 |
|
7879 |
/**
|
7880 |
* @return boolean
|
7881 |
+
*
|
7882 |
* @since v1.8.9
|
7883 |
+
*
|
7884 |
* Check if user has specific role
|
7885 |
*/
|
7886 |
+
public function has_user_role( $roles, $user_id = 0 ) {
|
7887 |
+
|
7888 |
+
! $user_id ? $user_id = get_current_user_id() : 0;
|
7889 |
+
! is_array( $roles ) ? $roles = array( $roles ) : 0;
|
|
|
|
|
|
|
7890 |
|
7891 |
+
$user = get_userdata( $user_id );
|
7892 |
+
$role_list = ( is_object( $user ) && is_array( $user->roles ) ) ? $user->roles : array();
|
7893 |
|
7894 |
+
$without_roles = array_diff( $roles, $role_list );
|
7895 |
+
|
7896 |
+
return count( $roles ) > count( $without_roles );
|
7897 |
}
|
7898 |
|
7899 |
/**
|
7900 |
* @return boolean
|
7901 |
+
*
|
7902 |
* @since v1.8.9
|
7903 |
+
*
|
7904 |
* Check if user can edit course
|
7905 |
*/
|
7906 |
+
public function can_user_edit_course( $user_id, $course_id ) {
|
7907 |
+
return $this->has_user_role( array( 'administrator', 'editor' ) ) || $this->is_instructor_of_this_course( $user_id, $course_id );
|
|
|
7908 |
}
|
7909 |
|
7910 |
+
|
7911 |
/**
|
7912 |
* @return boolean
|
7913 |
+
*
|
7914 |
* @since v1.9.0
|
7915 |
+
*
|
7916 |
* Check if course member limit full
|
7917 |
*/
|
7918 |
+
public function is_course_fully_booked( $course_id = 0 ) {
|
7919 |
+
|
7920 |
+
$total_enrolled = $this->count_enrolled_users_by_course( $course_id );
|
7921 |
+
$maximum_students = (int) $this->get_course_settings( $course_id, 'maximum_students' );
|
7922 |
|
|
|
|
|
|
|
7923 |
return $maximum_students && $maximum_students <= $total_enrolled;
|
7924 |
}
|
7925 |
|
7926 |
/**
|
7927 |
* @return boolean
|
7928 |
+
*
|
7929 |
* @since v1.9.2
|
7930 |
+
*
|
7931 |
* Check if current screen is under tutor dashboard
|
7932 |
*/
|
7933 |
+
public function is_tutor_dashboard( $subpage = null ) {
|
7934 |
|
7935 |
// To Do: Add subpage check later
|
7936 |
|
7937 |
+
if ( function_exists( 'is_admin' ) && is_admin() ) {
|
7938 |
$screen = get_current_screen();
|
7939 |
return is_object( $screen ) && $screen->parent_base == 'tutor';
|
7940 |
}
|
7941 |
+
|
7942 |
return false;
|
7943 |
}
|
7944 |
|
7945 |
/**
|
7946 |
* @return boolean
|
7947 |
+
*
|
7948 |
* @since v1.9.4
|
7949 |
+
*
|
7950 |
* Check if current screen tutor frontend dashboard
|
7951 |
*/
|
7952 |
+
public function is_tutor_frontend_dashboard( $subpage = null ) {
|
7953 |
|
7954 |
global $wp_query;
|
7955 |
+
if ( $wp_query->is_page ) {
|
7956 |
+
$dashboard_page = tutor_utils()->array_get( 'tutor_dashboard_page', $wp_query->query_vars );
|
7957 |
|
7958 |
+
if ( $subpage && $dashboard_page == $subpage ) {
|
7959 |
return true;
|
7960 |
}
|
7961 |
|
7962 |
+
if ( $wp_query->queried_object && $wp_query->queried_object->ID ) {
|
7963 |
+
return $wp_query->queried_object->ID == tutor_utils()->get_option( 'tutor_dashboard_page_id' );
|
7964 |
}
|
7965 |
}
|
7966 |
|
7967 |
return false;
|
7968 |
}
|
7969 |
|
7970 |
+
public function get_unique_slug( $slug, $post_type = null, $num_assigned = false ) {
|
7971 |
|
7972 |
global $wpdb;
|
7973 |
+
$existing_slug = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM {$wpdb->posts} WHERE post_name=%s" . ( $post_type ? " AND post_type='{$post_type}' LIMIT 1" : '' ), $slug ) );
|
7974 |
|
7975 |
+
if ( ! $existing_slug ) {
|
7976 |
return $slug;
|
7977 |
}
|
7978 |
|
7979 |
+
if ( ! $num_assigned ) {
|
7980 |
$new_slug = $slug . '-' . 2;
|
7981 |
} else {
|
7982 |
+
$new_slug = explode( '-', $slug );
|
7983 |
+
$number = end( $new_slug ) + 1;
|
|
|
|
|
7984 |
|
7985 |
+
array_pop( $new_slug );
|
7986 |
+
|
7987 |
+
$new_slug = implode( '-', $new_slug ) . '-' . $number;
|
7988 |
}
|
7989 |
|
7990 |
+
return $this->get_unique_slug( $new_slug, $post_type, true );
|
7991 |
}
|
7992 |
|
7993 |
+
public function get_course_content_ids_by( $content_type, $ancestor_type, $ancestor_ids ) {
|
7994 |
+
global $wpdb;
|
7995 |
$ids = array();
|
7996 |
|
7997 |
// Convert single id to array
|
7998 |
+
! is_array( $ancestor_ids ) ? $ancestor_ids = array( $ancestor_ids ) : 0;
|
7999 |
+
$ancestor_ids = implode( ',', $ancestor_ids );
|
8000 |
|
8001 |
+
switch ( $content_type ) {
|
8002 |
|
8003 |
// Get lesson, quiz, assignment IDs
|
8004 |
+
case tutor()->lesson_post_type:
|
8005 |
+
case 'tutor_quiz':
|
8006 |
+
case 'tutor_assignments':
|
8007 |
+
switch ( $ancestor_type ) {
|
8008 |
|
8009 |
// Get lesson, quiz, assignment IDs by course ID
|
8010 |
+
case tutor()->course_post_type:
|
8011 |
+
$content_ids = $wpdb->get_col(
|
8012 |
+
$wpdb->prepare(
|
8013 |
+
"SELECT content.ID FROM {$wpdb->posts} course
|
8014 |
+
INNER JOIN {$wpdb->posts} topic ON course.ID=topic.post_parent
|
8015 |
INNER JOIN {$wpdb->posts} content ON topic.ID=content.post_parent
|
8016 |
WHERE course.ID IN ({$ancestor_ids}) AND content.post_type=%s",
|
8017 |
+
$content_type
|
8018 |
+
)
|
8019 |
+
);
|
8020 |
|
8021 |
// Assign id array to the variable
|
8022 |
+
is_array( $content_ids ) ? $ids = $content_ids : 0;
|
8023 |
break 2;
|
8024 |
}
|
8025 |
}
|
8029 |
|
8030 |
/**
|
8031 |
* Custom Pagination for Tutor Shortcode
|
8032 |
+
*
|
8033 |
* @param int $total_num_pages
|
8034 |
+
*
|
8035 |
* @return void
|
8036 |
*/
|
8037 |
public function tutor_custom_pagination( $total_num_pages = 1 ) {
|
8038 |
|
8039 |
do_action( 'tutor_course/archive/pagination/before' ); ?>
|
8040 |
+
|
8041 |
<div class="tutor-pagination-wrap">
|
8042 |
<?php
|
8043 |
$big = 999999999; // need an unlikely integer
|
8044 |
+
|
8045 |
+
echo paginate_links(
|
8046 |
+
array(
|
8047 |
+
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
|
8048 |
+
'format' => '?paged=%#%',
|
8049 |
+
'current' => max( 1, get_query_var( 'paged' ) ),
|
8050 |
+
'total' => $total_num_pages,
|
8051 |
+
)
|
8052 |
+
);
|
8053 |
?>
|
8054 |
</div>
|
8055 |
+
|
8056 |
+
<?php
|
8057 |
+
do_action( 'tutor_course/archive/pagination/after' );
|
8058 |
}
|
8059 |
|
8060 |
/**
|
8061 |
* Get all courses along with topics & course materials for current student
|
8062 |
+
*
|
8063 |
* @since 1.9.10
|
8064 |
+
*
|
8065 |
* @return array
|
8066 |
*/
|
8067 |
public function course_with_materials(): array {
|
8068 |
+
$user_id = get_current_user_id();
|
8069 |
$enrolled_courses = $this->get_enrolled_courses_by_user( $user_id );
|
8070 |
|
8071 |
if ( false === $enrolled_courses ) {
|
8072 |
+
return array();
|
8073 |
}
|
8074 |
+
$data = array();
|
8075 |
foreach ( $enrolled_courses->posts as $key => $course ) {
|
8076 |
+
// push courses
|
8077 |
+
array_push( $data, array( 'course' => array( 'title' => $course->post_title ) ) );
|
8078 |
$topics = $this->get_topics( $course->ID );
|
8079 |
|
8080 |
+
if ( ! is_null( $topics ) || count( $topics->posts ) ) {
|
8081 |
foreach ( $topics->posts as $topic_key => $topic ) {
|
8082 |
$materials = $this->get_course_contents_by_topic( $topic->ID, -1 );
|
8083 |
+
if ( count( $materials->posts ) || ! is_null( $materials->posts ) ) {
|
8084 |
$topic->materials = $materials->posts;
|
8085 |
}
|
8086 |
+
// push topics
|
8087 |
+
array_push( $data[ $key ]['course'], array( 'topics' => $topic ) );
|
8088 |
}
|
8089 |
}
|
|
|
8090 |
}
|
8091 |
return $data;
|
8092 |
}
|
8093 |
|
8094 |
+
public function get_course_duration( $course_id, $return_array, $texts = array(
|
8095 |
+
'h' => 'hr',
|
8096 |
+
'm' => 'min',
|
8097 |
+
's' => 'sec',
|
8098 |
+
) ) {
|
8099 |
+
$duration = maybe_unserialize( get_post_meta( $course_id, '_course_duration', true ) );
|
8100 |
+
$durationHours = tutor_utils()->avalue_dot( 'hours', $duration );
|
8101 |
+
$durationMinutes = tutor_utils()->avalue_dot( 'minutes', $duration );
|
8102 |
+
$durationSeconds = tutor_utils()->avalue_dot( 'seconds', $duration );
|
8103 |
|
8104 |
+
if ( $return_array ) {
|
8105 |
return array(
|
8106 |
+
'duration' => $duration,
|
8107 |
+
'durationHours' => $durationHours,
|
8108 |
'durationMinutes' => $durationMinutes,
|
8109 |
'durationSeconds' => $durationSeconds,
|
8110 |
);
|
8111 |
}
|
8112 |
|
8113 |
+
if ( ! $durationHours && ! $durationMinutes && ! $durationSeconds ) {
|
8114 |
return '';
|
8115 |
}
|
8116 |
|
8118 |
$durationMinutes . $texts['m'] . ' ' .
|
8119 |
$durationSeconds . $texts['s'];
|
8120 |
}
|
8121 |
+
}
|
classes/Video_Stream.php
CHANGED
@@ -8,12 +8,14 @@
|
|
8 |
|
9 |
namespace TUTOR;
|
10 |
|
11 |
-
if ( ! defined( 'ABSPATH' ) )
|
12 |
exit;
|
|
|
13 |
|
14 |
|
15 |
/**
|
16 |
* Class Video_Stream
|
|
|
17 |
* @package TUTOR
|
18 |
*
|
19 |
* TUTOR Video Stream Class
|
@@ -22,8 +24,8 @@ if ( ! defined( 'ABSPATH' ) )
|
|
22 |
|
23 |
class Video_Stream {
|
24 |
|
25 |
-
private $path
|
26 |
-
private $stream =
|
27 |
private $buffer = 102400;
|
28 |
private $start = -1;
|
29 |
private $end = -1;
|
@@ -31,17 +33,24 @@ class Video_Stream {
|
|
31 |
|
32 |
private $videoFormats;
|
33 |
|
34 |
-
function __construct($filePath) {
|
35 |
-
$this->videoFormats = apply_filters(
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
* Open stream
|
41 |
*/
|
42 |
private function open() {
|
43 |
-
if (!($this->stream = fopen($this->path, 'rb'))) {
|
44 |
-
die('Could not open stream for reading');
|
45 |
}
|
46 |
}
|
47 |
|
@@ -51,43 +60,42 @@ class Video_Stream {
|
|
51 |
private function setHeader() {
|
52 |
ob_get_clean();
|
53 |
|
54 |
-
header(
|
55 |
-
header(
|
56 |
-
header(
|
57 |
-
header(
|
58 |
$this->start = 0;
|
59 |
-
$this->size = filesize($this->path);
|
60 |
$this->end = $this->size - 1;
|
61 |
-
header(
|
62 |
|
63 |
-
if (isset($_SERVER['HTTP_RANGE'])) {
|
64 |
-
$c_end
|
65 |
-
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
|
66 |
|
67 |
-
if ($range == '-') {
|
68 |
-
$c_start = $this->size - substr($range, 1);
|
69 |
-
}else{
|
70 |
-
$range
|
71 |
$c_start = $range[0];
|
72 |
|
73 |
-
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
|
74 |
}
|
75 |
-
$c_end = ($c_end > $this->end) ? $this->end : $c_end;
|
76 |
-
if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {
|
77 |
-
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
78 |
-
header("Content-Range: bytes $this->start-$this->end/$this->size");
|
79 |
exit;
|
80 |
}
|
81 |
$this->start = $c_start;
|
82 |
-
$this->end
|
83 |
-
$length
|
84 |
-
header('HTTP/1.1 206 Partial Content');
|
85 |
-
header(
|
86 |
-
header("Content-Range: bytes $this->start-$this->end/"
|
87 |
-
header(
|
88 |
-
}
|
89 |
-
|
90 |
-
header("Content-Length: ".$this->size);
|
91 |
}
|
92 |
|
93 |
}
|
@@ -96,7 +104,7 @@ class Video_Stream {
|
|
96 |
* close currently opened stream
|
97 |
*/
|
98 |
private function end() {
|
99 |
-
fclose($this->stream);
|
100 |
exit;
|
101 |
}
|
102 |
|
@@ -105,15 +113,15 @@ class Video_Stream {
|
|
105 |
*/
|
106 |
private function stream() {
|
107 |
$i = $this->start;
|
108 |
-
set_time_limit(0);
|
109 |
-
while(!feof($this->stream) && $i <= $this->end) {
|
110 |
$bytesToRead = $this->buffer;
|
111 |
-
if(($i
|
112 |
$bytesToRead = $this->end - $i + 1;
|
113 |
}
|
114 |
-
|
115 |
-
$data = @stream_get_contents($this->stream, $bytesToRead, $i);
|
116 |
-
echo $data;
|
117 |
flush();
|
118 |
$i += $bytesToRead;
|
119 |
}
|
@@ -128,4 +136,4 @@ class Video_Stream {
|
|
128 |
$this->stream();
|
129 |
$this->end();
|
130 |
}
|
131 |
-
}
|
8 |
|
9 |
namespace TUTOR;
|
10 |
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
exit;
|
13 |
+
}
|
14 |
|
15 |
|
16 |
/**
|
17 |
* Class Video_Stream
|
18 |
+
*
|
19 |
* @package TUTOR
|
20 |
*
|
21 |
* TUTOR Video Stream Class
|
24 |
|
25 |
class Video_Stream {
|
26 |
|
27 |
+
private $path = '';
|
28 |
+
private $stream = '';
|
29 |
private $buffer = 102400;
|
30 |
private $start = -1;
|
31 |
private $end = -1;
|
33 |
|
34 |
private $videoFormats;
|
35 |
|
36 |
+
function __construct( $filePath ) {
|
37 |
+
$this->videoFormats = apply_filters(
|
38 |
+
'tutor_video_types',
|
39 |
+
array(
|
40 |
+
'mp4' => 'video/mp4',
|
41 |
+
'webm' => 'video/webm',
|
42 |
+
'ogg' => 'video/ogg',
|
43 |
+
)
|
44 |
+
);
|
45 |
+
$this->path = $filePath;
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
* Open stream
|
50 |
*/
|
51 |
private function open() {
|
52 |
+
if ( ! ( $this->stream = fopen( $this->path, 'rb' ) ) ) {
|
53 |
+
die( 'Could not open stream for reading' );
|
54 |
}
|
55 |
}
|
56 |
|
60 |
private function setHeader() {
|
61 |
ob_get_clean();
|
62 |
|
63 |
+
header( 'Content-Type: ' . $this->videoFormats[ strtolower( pathinfo( $this->path, PATHINFO_EXTENSION ) ) ] );
|
64 |
+
header( 'Cache-Control: max-age=2592000, public' );
|
65 |
+
header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', tutor_time() + 2592000 ) . ' GMT' );
|
66 |
+
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', @filemtime( $this->path ) ) . ' GMT' );
|
67 |
$this->start = 0;
|
68 |
+
$this->size = filesize( $this->path );
|
69 |
$this->end = $this->size - 1;
|
70 |
+
header( 'Accept-Ranges: 0-' . $this->end );
|
71 |
|
72 |
+
if ( isset( $_SERVER['HTTP_RANGE'] ) ) {
|
73 |
+
$c_end = $this->end;
|
74 |
+
list(, $range) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
|
75 |
|
76 |
+
if ( $range == '-' ) {
|
77 |
+
$c_start = $this->size - substr( $range, 1 );
|
78 |
+
} else {
|
79 |
+
$range = explode( '-', $range );
|
80 |
$c_start = $range[0];
|
81 |
|
82 |
+
$c_end = ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? $range[1] : $c_end;
|
83 |
}
|
84 |
+
$c_end = ( $c_end > $this->end ) ? $this->end : $c_end;
|
85 |
+
if ( $c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size ) {
|
86 |
+
header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
|
87 |
+
header( "Content-Range: bytes $this->start-$this->end/$this->size" );
|
88 |
exit;
|
89 |
}
|
90 |
$this->start = $c_start;
|
91 |
+
$this->end = $c_end;
|
92 |
+
$length = $this->end - $this->start + 1;
|
93 |
+
header( 'HTTP/1.1 206 Partial Content' );
|
94 |
+
header( 'Content-Length: ' . $length );
|
95 |
+
header( "Content-Range: bytes $this->start-$this->end/" . $this->size );
|
96 |
+
header( 'Accept-Ranges: bytes' );
|
97 |
+
} else {
|
98 |
+
header( 'Content-Length: ' . $this->size );
|
|
|
99 |
}
|
100 |
|
101 |
}
|
104 |
* close currently opened stream
|
105 |
*/
|
106 |
private function end() {
|
107 |
+
fclose( $this->stream );
|
108 |
exit;
|
109 |
}
|
110 |
|
113 |
*/
|
114 |
private function stream() {
|
115 |
$i = $this->start;
|
116 |
+
set_time_limit( 0 );
|
117 |
+
while ( ! feof( $this->stream ) && $i <= $this->end ) {
|
118 |
$bytesToRead = $this->buffer;
|
119 |
+
if ( ( $i + $bytesToRead ) > $this->end ) {
|
120 |
$bytesToRead = $this->end - $i + 1;
|
121 |
}
|
122 |
+
// $data = fread($this->stream, $bytesToRead);
|
123 |
+
$data = @stream_get_contents( $this->stream, $bytesToRead, $i );
|
124 |
+
echo $data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
125 |
flush();
|
126 |
$i += $bytesToRead;
|
127 |
}
|
136 |
$this->stream();
|
137 |
$this->end();
|
138 |
}
|
139 |
+
}
|
classes/Withdraw.php
CHANGED
@@ -10,8 +10,9 @@
|
|
10 |
|
11 |
namespace TUTOR;
|
12 |
|
13 |
-
if ( ! defined( 'ABSPATH' ) )
|
14 |
exit;
|
|
|
15 |
|
16 |
class Withdraw {
|
17 |
|
@@ -20,79 +21,79 @@ class Withdraw {
|
|
20 |
public $withdraw_methods;
|
21 |
|
22 |
public function __construct() {
|
23 |
-
$this->get_options
|
24 |
-
$this->withdraw_methods
|
25 |
$this->available_withdraw_methods = $this->available_withdraw_methods();
|
26 |
|
27 |
-
add_action('tutor_options_tutor_withdraw_withdraw_methods_before', array($this, 'withdraw_admin_options'));
|
28 |
-
add_action('tutor_option_save_after', array($this, 'withdraw_option_save'));
|
29 |
|
30 |
-
add_action('wp_ajax_tutor_save_withdraw_account', array($this, 'tutor_save_withdraw_account'));
|
31 |
-
add_action('wp_ajax_tutor_make_an_withdraw', array($this, 'tutor_make_an_withdraw'));
|
32 |
}
|
33 |
|
34 |
-
public function withdraw_methods(){
|
35 |
$methods = array(
|
36 |
'bank_transfer_withdraw' => array(
|
37 |
-
'method_name'
|
38 |
-
'image'
|
39 |
-
'desc'
|
40 |
|
41 |
-
'admin_form_fields'
|
42 |
'instruction' => array(
|
43 |
-
'type'
|
44 |
-
'label'
|
45 |
-
'desc'
|
46 |
),
|
47 |
),
|
48 |
|
49 |
-
'form_fields'
|
50 |
-
'account_name'
|
51 |
-
'type'
|
52 |
-
'label'
|
53 |
),
|
54 |
|
55 |
'account_number' => array(
|
56 |
-
'type'
|
57 |
-
'label'
|
58 |
),
|
59 |
|
60 |
-
'bank_name'
|
61 |
-
'type'
|
62 |
-
'label'
|
63 |
),
|
64 |
-
'iban'
|
65 |
-
'type'
|
66 |
-
'label'
|
67 |
),
|
68 |
-
'swift'
|
69 |
-
'type'
|
70 |
-
'label'
|
71 |
),
|
72 |
|
73 |
),
|
74 |
),
|
75 |
|
76 |
-
'echeck_withdraw'
|
77 |
-
'method_name'
|
78 |
-
'image'
|
79 |
-
'form_fields'
|
80 |
'physical_address' => array(
|
81 |
-
'type'
|
82 |
-
'label'
|
83 |
-
'desc'
|
84 |
),
|
85 |
),
|
86 |
),
|
87 |
|
88 |
-
'paypal_withdraw'
|
89 |
-
'method_name'
|
90 |
-
'image'
|
91 |
-
'form_fields'
|
92 |
'paypal_email' => array(
|
93 |
-
'type'
|
94 |
-
'label'
|
95 |
-
'desc'
|
96 |
),
|
97 |
|
98 |
),
|
@@ -100,7 +101,7 @@ class Withdraw {
|
|
100 |
|
101 |
);
|
102 |
|
103 |
-
$withdraw_methods = apply_filters('tutor_withdraw_methods', $methods);
|
104 |
|
105 |
return $withdraw_methods;
|
106 |
}
|
@@ -110,27 +111,27 @@ class Withdraw {
|
|
110 |
*
|
111 |
* Return only enabled methods
|
112 |
*/
|
113 |
-
public function available_withdraw_methods(){
|
114 |
$withdraw_options = $this->get_options();
|
115 |
-
$methods
|
116 |
|
117 |
-
foreach ($methods as $method_id => $method){
|
118 |
-
$is_enable = (bool) tutor_utils()->avalue_dot($method_id.
|
119 |
|
120 |
-
if ( ! $is_enable){
|
121 |
-
unset($methods[$method_id]);
|
122 |
}
|
123 |
}
|
124 |
|
125 |
return $methods;
|
126 |
}
|
127 |
|
128 |
-
public function get_options(){
|
129 |
-
return (array) maybe_unserialize(get_option('tutor_withdraw_options'));
|
130 |
}
|
131 |
|
132 |
-
public function withdraw_admin_options(){
|
133 |
-
include tutor()->path.'views/options/withdraw/withdraw_admin_options_generator.php';
|
134 |
}
|
135 |
|
136 |
|
@@ -139,14 +140,14 @@ class Withdraw {
|
|
139 |
*
|
140 |
* @since v.1.2.0
|
141 |
*/
|
142 |
-
public function withdraw_option_save(){
|
143 |
-
do_action('tutor_withdraw_options_save_before');
|
144 |
|
145 |
-
$option = (array) isset($_POST['tutor_withdraw_options']) ? $_POST['tutor_withdraw_options'] : array();
|
146 |
-
$option = apply_filters('tutor_withdraw_options_input', $option);
|
147 |
-
update_option('tutor_withdraw_options', $option);
|
148 |
|
149 |
-
do_action('tutor_withdraw_options_save_after');
|
150 |
}
|
151 |
|
152 |
/**
|
@@ -155,106 +156,109 @@ class Withdraw {
|
|
155 |
* @since v.1.2.0
|
156 |
*/
|
157 |
|
158 |
-
public function tutor_save_withdraw_account(){
|
159 |
-
//Checking nonce
|
160 |
tutor_utils()->checking_nonce();
|
161 |
|
162 |
$user_id = get_current_user_id();
|
163 |
-
$post
|
164 |
|
165 |
-
$method = tutor_utils()->avalue_dot('tutor_selected_withdraw_method', $post);
|
166 |
-
if ( ! $method){
|
167 |
wp_send_json_error();
|
168 |
}
|
169 |
|
170 |
-
$method_data
|
171 |
$available_withdraw_method = tutor_withdrawal_methods();
|
172 |
|
173 |
-
if (tutor_utils()->count($method_data)){
|
174 |
-
$saved_data
|
175 |
-
$saved_data['withdraw_method_key']
|
176 |
-
$saved_data['withdraw_method_name'] = tutor_utils()->avalue_dot($method.
|
177 |
|
178 |
-
foreach ($method_data as $input_name => $value){
|
179 |
-
$saved_data[$input_name]['value'] = esc_sql( sanitize_text_field($value) )
|
180 |
-
$saved_data[$input_name]['label'] = tutor_utils()->avalue_dot($method.".form_fields.{$input_name}.label",
|
181 |
}
|
182 |
|
183 |
-
update_user_meta($user_id, '_tutor_withdraw_method_data', $saved_data);
|
184 |
}
|
185 |
|
186 |
-
$msg = apply_filters('tutor_withdraw_method_set_success_msg', __('Withdrawal account information saved successfully!', 'tutor'));
|
187 |
-
wp_send_json_success(array('msg' => $msg ));
|
188 |
}
|
189 |
|
190 |
-
public function tutor_make_an_withdraw(){
|
191 |
global $wpdb;
|
192 |
|
193 |
-
//Checking nonce
|
194 |
tutor_utils()->checking_nonce();
|
195 |
|
196 |
-
do_action('tutor_withdraw_before');
|
197 |
-
|
198 |
|
199 |
$user_id = get_current_user_id();
|
200 |
-
$post
|
201 |
-
|
202 |
-
$withdraw_amount = sanitize_text_field(tutor_utils()->avalue_dot('tutor_withdraw_amount', $post));
|
203 |
|
204 |
-
$
|
205 |
-
$min_withdraw = tutor_utils()->get_option('min_withdraw_amount');
|
206 |
|
207 |
-
$
|
208 |
-
$
|
209 |
-
$formatted_min_withdraw_amount = tutor_utils()->tutor_price($min_withdraw);
|
210 |
|
|
|
|
|
|
|
211 |
|
212 |
-
if ( ! tutor_utils()->count($saved_withdraw_account)){
|
213 |
-
$no_withdraw_method = apply_filters('tutor_no_withdraw_method_msg', __('Please save withdraw method ', 'tutor')
|
214 |
-
wp_send_json_error(array('msg' => $no_withdraw_method ));
|
215 |
}
|
216 |
|
217 |
-
if ((!is_numeric($withdraw_amount) && !is_float($withdraw_amount)) || $withdraw_amount < $min_withdraw){
|
218 |
-
$required_min_withdraw = apply_filters('tutor_required_min_amount_msg', sprintf(__('Minimum withdrawal amount is %s %s %s ', 'tutor')
|
219 |
-
wp_send_json_error(array('msg' => $required_min_withdraw ));
|
220 |
}
|
221 |
|
222 |
-
if ($earning_sum->balance < $withdraw_amount){
|
223 |
-
$insufficient_balence = apply_filters('tutor_withdraw_insufficient_balance_msg', __('Insufficient balance.', 'tutor'));
|
224 |
|
225 |
-
wp_send_json_error(array('msg' => $insufficient_balence ));
|
226 |
}
|
227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
|
229 |
-
|
230 |
-
|
231 |
-
$withdraw_data = apply_filters('tutor_pre_withdraw_data', array(
|
232 |
-
'user_id' => $user_id,
|
233 |
-
'amount' => $withdraw_amount,
|
234 |
-
'method_data' => maybe_serialize($saved_withdraw_account),
|
235 |
-
'status' => 'pending',
|
236 |
-
'created_at' => $date,
|
237 |
-
));
|
238 |
-
|
239 |
-
do_action('tutor_insert_withdraw_before', $withdraw_data);
|
240 |
|
241 |
-
$wpdb->insert($wpdb->prefix.
|
242 |
$withdraw_id = $wpdb->insert_id;
|
243 |
|
244 |
-
do_action('tutor_insert_withdraw_after', $withdraw_id, $withdraw_data);
|
245 |
-
|
246 |
|
247 |
/**
|
248 |
* Getting earning and balance data again
|
249 |
*/
|
250 |
-
$earning
|
251 |
-
$new_available_balance = tutor_utils()->tutor_price($earning->balance);
|
252 |
|
|
|
253 |
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
|
|
258 |
}
|
259 |
|
260 |
|
10 |
|
11 |
namespace TUTOR;
|
12 |
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
exit;
|
15 |
+
}
|
16 |
|
17 |
class Withdraw {
|
18 |
|
21 |
public $withdraw_methods;
|
22 |
|
23 |
public function __construct() {
|
24 |
+
$this->get_options = $this->get_options();
|
25 |
+
$this->withdraw_methods = $this->withdraw_methods();
|
26 |
$this->available_withdraw_methods = $this->available_withdraw_methods();
|
27 |
|
28 |
+
add_action( 'tutor_options_tutor_withdraw_withdraw_methods_before', array( $this, 'withdraw_admin_options' ) );
|
29 |
+
add_action( 'tutor_option_save_after', array( $this, 'withdraw_option_save' ) );
|
30 |
|
31 |
+
add_action( 'wp_ajax_tutor_save_withdraw_account', array( $this, 'tutor_save_withdraw_account' ) );
|
32 |
+
add_action( 'wp_ajax_tutor_make_an_withdraw', array( $this, 'tutor_make_an_withdraw' ) );
|
33 |
}
|
34 |
|
35 |
+
public function withdraw_methods() {
|
36 |
$methods = array(
|
37 |
'bank_transfer_withdraw' => array(
|
38 |
+
'method_name' => __( 'Bank Transfer', 'tutor' ),
|
39 |
+
'image' => tutor()->url . 'assets/images/payment-bank.png',
|
40 |
+
'desc' => __( 'Get your payment directly into your bank account', 'tutor' ),
|
41 |
|
42 |
+
'admin_form_fields' => array(
|
43 |
'instruction' => array(
|
44 |
+
'type' => 'textarea',
|
45 |
+
'label' => __( 'Instruction', 'tutor' ),
|
46 |
+
'desc' => __( 'Write instruction for the instructor to fill bank information', 'tutor' ),
|
47 |
),
|
48 |
),
|
49 |
|
50 |
+
'form_fields' => array(
|
51 |
+
'account_name' => array(
|
52 |
+
'type' => 'text',
|
53 |
+
'label' => __( 'Account Name', 'tutor' ),
|
54 |
),
|
55 |
|
56 |
'account_number' => array(
|
57 |
+
'type' => 'text',
|
58 |
+
'label' => __( 'Account Number', 'tutor' ),
|
59 |
),
|
60 |
|
61 |
+
'bank_name' => array(
|
62 |
+
'type' => 'text',
|
63 |
+
'label' => __( 'Bank Name', 'tutor' ),
|
64 |
),
|
65 |
+
'iban' => array(
|
66 |
+
'type' => 'text',
|
67 |
+
'label' => __( 'IBAN', 'tutor' ),
|
68 |
),
|
69 |
+
'swift' => array(
|
70 |
+
'type' => 'text',
|
71 |
+
'label' => __( 'BIC / SWIFT', 'tutor' ),
|
72 |
),
|
73 |
|
74 |
),
|
75 |
),
|
76 |
|
77 |
+
'echeck_withdraw' => array(
|
78 |
+
'method_name' => __( 'E-Check', 'tutor' ),
|
79 |
+
'image' => tutor()->url . 'assets/images/payment-echeck.png',
|
80 |
+
'form_fields' => array(
|
81 |
'physical_address' => array(
|
82 |
+
'type' => 'textarea',
|
83 |
+
'label' => __( 'Your Physical Address', 'tutor' ),
|
84 |
+
'desc' => __( 'We will send you an E-Check to this address directly.', 'tutor' ),
|
85 |
),
|
86 |
),
|
87 |
),
|
88 |
|
89 |
+
'paypal_withdraw' => array(
|
90 |
+
'method_name' => __( 'PayPal', 'tutor' ),
|
91 |
+
'image' => tutor()->url . 'assets/images/payment-paypal.png',
|
92 |
+
'form_fields' => array(
|
93 |
'paypal_email' => array(
|
94 |
+
'type' => 'email',
|
95 |
+
'label' => __( 'PayPal E-Mail Address', 'tutor' ),
|
96 |
+
'desc' => __( 'We will use this email address to send the money to your Paypal account', 'tutor' ),
|
97 |
),
|
98 |
|
99 |
),
|
101 |
|
102 |
);
|
103 |
|
104 |
+
$withdraw_methods = apply_filters( 'tutor_withdraw_methods', $methods );
|
105 |
|
106 |
return $withdraw_methods;
|
107 |
}
|
111 |
*
|
112 |
* Return only enabled methods
|
113 |
*/
|
114 |
+
public function available_withdraw_methods() {
|
115 |
$withdraw_options = $this->get_options();
|
116 |
+
$methods = $this->withdraw_methods();
|
117 |
|
118 |
+
foreach ( $methods as $method_id => $method ) {
|
119 |
+
$is_enable = (bool) tutor_utils()->avalue_dot( $method_id . '.enabled', $withdraw_options );
|
120 |
|
121 |
+
if ( ! $is_enable ) {
|
122 |
+
unset( $methods[ $method_id ] );
|
123 |
}
|
124 |
}
|
125 |
|
126 |
return $methods;
|
127 |
}
|
128 |
|
129 |
+
public function get_options() {
|
130 |
+
return (array) maybe_unserialize( get_option( 'tutor_withdraw_options' ) );
|
131 |
}
|
132 |
|
133 |
+
public function withdraw_admin_options() {
|
134 |
+
include tutor()->path . 'views/options/withdraw/withdraw_admin_options_generator.php';
|
135 |
}
|
136 |
|
137 |
|
140 |
*
|
141 |
* @since v.1.2.0
|
142 |
*/
|
143 |
+
public function withdraw_option_save() {
|
144 |
+
do_action( 'tutor_withdraw_options_save_before' );
|
145 |
|
146 |
+
$option = (array) isset( $_POST['tutor_withdraw_options'] ) ? tutor_sanitize_data($_POST['tutor_withdraw_options']) : array();
|
147 |
+
$option = apply_filters( 'tutor_withdraw_options_input', $option );
|
148 |
+
update_option( 'tutor_withdraw_options', $option );
|
149 |
|
150 |
+
do_action( 'tutor_withdraw_options_save_after' );
|
151 |
}
|
152 |
|
153 |
/**
|
156 |
* @since v.1.2.0
|
157 |
*/
|
158 |
|
159 |
+
public function tutor_save_withdraw_account() {
|
160 |
+
// Checking nonce
|
161 |
tutor_utils()->checking_nonce();
|
162 |
|
163 |
$user_id = get_current_user_id();
|
164 |
+
$post = tutor_sanitize_data($_POST);
|
165 |
|
166 |
+
$method = tutor_utils()->avalue_dot( 'tutor_selected_withdraw_method', $post );
|
167 |
+
if ( ! $method ) {
|
168 |
wp_send_json_error();
|
169 |
}
|
170 |
|
171 |
+
$method_data = tutor_utils()->avalue_dot( 'withdraw_method_field.' . $method, $post );
|
172 |
$available_withdraw_method = tutor_withdrawal_methods();
|
173 |
|
174 |
+
if ( tutor_utils()->count( $method_data ) ) {
|
175 |
+
$saved_data = array();
|
176 |
+
$saved_data['withdraw_method_key'] = $method;
|
177 |
+
$saved_data['withdraw_method_name'] = tutor_utils()->avalue_dot( $method . '.method_name', $available_withdraw_method );
|
178 |
|
179 |
+
foreach ( $method_data as $input_name => $value ) {
|
180 |
+
$saved_data[ $input_name ]['value'] = esc_sql( sanitize_text_field( $value ) );
|
181 |
+
$saved_data[ $input_name ]['label'] = tutor_utils()->avalue_dot( $method . ".form_fields.{$input_name}.label", $available_withdraw_method );
|
182 |
}
|
183 |
|
184 |
+
update_user_meta( $user_id, '_tutor_withdraw_method_data', $saved_data );
|
185 |
}
|
186 |
|
187 |
+
$msg = apply_filters( 'tutor_withdraw_method_set_success_msg', __( 'Withdrawal account information saved successfully!', 'tutor' ) );
|
188 |
+
wp_send_json_success( array( 'msg' => $msg ) );
|
189 |
}
|
190 |
|
191 |
+
public function tutor_make_an_withdraw() {
|
192 |
global $wpdb;
|
193 |
|
194 |
+
// Checking nonce
|
195 |
tutor_utils()->checking_nonce();
|
196 |
|
197 |
+
do_action( 'tutor_withdraw_before' );
|
|
|
198 |
|
199 |
$user_id = get_current_user_id();
|
200 |
+
$post = tutor_sanitize_data($_POST);
|
|
|
|
|
201 |
|
202 |
+
$withdraw_amount = sanitize_text_field( tutor_utils()->avalue_dot( 'tutor_withdraw_amount', $post ) );
|
|
|
203 |
|
204 |
+
$earning_sum = tutor_utils()->get_earning_sum();
|
205 |
+
$min_withdraw = tutor_utils()->get_option( 'min_withdraw_amount' );
|
|
|
206 |
|
207 |
+
$saved_withdraw_account = tutor_utils()->get_user_withdraw_method();
|
208 |
+
$formatted_balance = tutor_utils()->tutor_price( $earning_sum->balance );
|
209 |
+
$formatted_min_withdraw_amount = tutor_utils()->tutor_price( $min_withdraw );
|
210 |
|
211 |
+
if ( ! tutor_utils()->count( $saved_withdraw_account ) ) {
|
212 |
+
$no_withdraw_method = apply_filters( 'tutor_no_withdraw_method_msg', __( 'Please save withdraw method ', 'tutor' ) );
|
213 |
+
wp_send_json_error( array( 'msg' => $no_withdraw_method ) );
|
214 |
}
|
215 |
|
216 |
+
if ( ( ! is_numeric( $withdraw_amount ) && ! is_float( $withdraw_amount ) ) || $withdraw_amount < $min_withdraw ) {
|
217 |
+
$required_min_withdraw = apply_filters( 'tutor_required_min_amount_msg', sprintf( __( 'Minimum withdrawal amount is %1$s %2$s %3$s ', 'tutor' ), '<strong>', $formatted_min_withdraw_amount, '</strong>' ) );
|
218 |
+
wp_send_json_error( array( 'msg' => $required_min_withdraw ) );
|
219 |
}
|
220 |
|
221 |
+
if ( $earning_sum->balance < $withdraw_amount ) {
|
222 |
+
$insufficient_balence = apply_filters( 'tutor_withdraw_insufficient_balance_msg', __( 'Insufficient balance.', 'tutor' ) );
|
223 |
|
224 |
+
wp_send_json_error( array( 'msg' => $insufficient_balence ) );
|
225 |
}
|
226 |
|
227 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
228 |
+
|
229 |
+
$withdraw_data = apply_filters(
|
230 |
+
'tutor_pre_withdraw_data',
|
231 |
+
array(
|
232 |
+
'user_id' => $user_id,
|
233 |
+
'amount' => $withdraw_amount,
|
234 |
+
'method_data' => maybe_serialize( $saved_withdraw_account ),
|
235 |
+
'status' => 'pending',
|
236 |
+
'created_at' => $date,
|
237 |
+
)
|
238 |
+
);
|
239 |
|
240 |
+
do_action( 'tutor_insert_withdraw_before', $withdraw_data );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
|
242 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_withdraws', $withdraw_data );
|
243 |
$withdraw_id = $wpdb->insert_id;
|
244 |
|
245 |
+
do_action( 'tutor_insert_withdraw_after', $withdraw_id, $withdraw_data );
|
|
|
246 |
|
247 |
/**
|
248 |
* Getting earning and balance data again
|
249 |
*/
|
250 |
+
$earning = tutor_utils()->get_earning_sum();
|
251 |
+
$new_available_balance = tutor_utils()->tutor_price( $earning->balance );
|
252 |
|
253 |
+
do_action( 'tutor_withdraw_after' );
|
254 |
|
255 |
+
$withdraw_successfull_msg = apply_filters( 'tutor_withdraw_successful_msg', __( 'Withdrawal Request Sent!', 'tutor' ) );
|
256 |
+
wp_send_json_success(
|
257 |
+
array(
|
258 |
+
'msg' => $withdraw_successfull_msg,
|
259 |
+
'available_balance' => $new_available_balance,
|
260 |
+
)
|
261 |
+
);
|
262 |
}
|
263 |
|
264 |
|
classes/Withdraw_Requests_List.php
CHANGED
@@ -1,121 +1,127 @@
|
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
-
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit;
|
|
|
6 |
|
7 |
-
if (! class_exists('Tutor_List_Table')){
|
8 |
-
include_once tutor()->path.'classes/Tutor_List_Table.php';
|
9 |
}
|
10 |
|
11 |
class Withdraw_Requests_List extends \Tutor_List_Table {
|
12 |
|
13 |
const WITHDRAW_REQUEST_LIST_PAGE = 'tutor_withdraw_requests';
|
14 |
|
15 |
-
function __construct(){
|
16 |
global $status, $page;
|
17 |
|
18 |
-
//Set parent defaults
|
19 |
-
parent::__construct(
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
24 |
|
25 |
$this->process_bulk_action();
|
26 |
}
|
27 |
|
28 |
-
function column_default($item, $column_name){
|
29 |
-
switch($column_name){
|
30 |
case 'testing_col':
|
31 |
return $item->$column_name;
|
32 |
default:
|
33 |
-
return print_r($item,true); //Show the whole array for troubleshooting purposes
|
34 |
}
|
35 |
}
|
36 |
|
37 |
-
function column_cb($item){
|
38 |
return sprintf(
|
39 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
40 |
-
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label ("student")
|
41 |
-
/*$2%s*/ $item->withdraw_id //The value of the checkbox should be the record's id
|
42 |
);
|
43 |
}
|
44 |
|
45 |
-
function column_requested_user($item){
|
46 |
-
echo
|
47 |
|
48 |
$actions = array();
|
49 |
-
switch ($item->status){
|
50 |
case 'pending':
|
51 |
-
$actions['approved'] = sprintf(
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
54 |
break;
|
55 |
case 'approved':
|
56 |
-
$actions['rejected'] = sprintf('<a href="?page=%s&action=%s&withdraw_id=%s">'.__('Rejected', 'tutor').'</a>',self::WITHDRAW_REQUEST_LIST_PAGE,'rejected'
|
57 |
break;
|
58 |
case 'rejected':
|
59 |
-
$actions['approved'] = sprintf('<a href="?page=%s&action=%s&withdraw_id=%s">'.__('Approve', 'tutor').'</a>',self::WITHDRAW_REQUEST_LIST_PAGE,'approved'
|
60 |
break;
|
61 |
}
|
62 |
|
63 |
-
$actions['delete'] = sprintf('<a href="?page=%s&action=%s&withdraw_id=%s" onclick="return confirm(\'' . __('Are you Sure? It can not be undone.', 'tutor') . '\')">' . __('Delete', 'tutor') . '</a>', self::WITHDRAW_REQUEST_LIST_PAGE, 'delete', $item->withdraw_id);
|
64 |
|
65 |
-
return
|
66 |
}
|
67 |
-
function column_withdraw_method($item){
|
68 |
-
if ($item->method_data){
|
69 |
-
$data = maybe_unserialize($item->method_data);
|
70 |
|
71 |
-
$method_name = tutor_utils()->avalue_dot('withdraw_method_name', $data);
|
72 |
|
73 |
-
if ($method_name){
|
74 |
-
echo
|
75 |
}
|
76 |
|
77 |
-
unset($data['withdraw_method_key'], $data['withdraw_method_name']);
|
78 |
|
79 |
-
if (tutor_utils()->count($data)){
|
80 |
-
foreach ($data as $method_field){
|
81 |
-
$label = tutor_utils()->avalue_dot('label', $method_field);
|
82 |
-
$value = tutor_utils()->avalue_dot('value', $method_field);
|
83 |
-
echo
|
84 |
}
|
85 |
}
|
86 |
-
|
87 |
}
|
88 |
return '';
|
89 |
}
|
90 |
|
91 |
-
function column_requested_at($item){
|
92 |
-
echo
|
93 |
}
|
94 |
|
95 |
-
function column_amount($item){
|
96 |
$available_status = array(
|
97 |
-
'pending'
|
98 |
-
'approved'
|
99 |
-
'rejected'
|
100 |
);
|
101 |
-
echo
|
102 |
-
echo
|
103 |
}
|
104 |
|
105 |
-
function get_columns(){
|
106 |
$columns = array(
|
107 |
-
'cb'
|
108 |
-
'requested_user'
|
109 |
-
'amount'
|
110 |
-
'withdraw_method'
|
111 |
-
'requested_at'
|
112 |
);
|
113 |
return $columns;
|
114 |
}
|
115 |
|
116 |
function get_bulk_actions() {
|
117 |
$actions = array(
|
118 |
-
//'delete' => 'Delete'
|
119 |
);
|
120 |
return $actions;
|
121 |
}
|
@@ -123,45 +129,51 @@ class Withdraw_Requests_List extends \Tutor_List_Table {
|
|
123 |
function process_bulk_action() {
|
124 |
global $wpdb;
|
125 |
|
126 |
-
$withdraw_page_url = admin_url('admin.php?page=' . self::WITHDRAW_REQUEST_LIST_PAGE);
|
127 |
-
$date
|
128 |
-
$redirect
|
129 |
|
130 |
-
//Detect when a bulk action is being triggered...
|
131 |
-
if( 'delete'
|
132 |
-
$should_withdraw_delete = apply_filters('tutor_should_withdraw_delete', true);
|
133 |
|
134 |
-
if ($should_withdraw_delete){
|
135 |
-
$withdraw_id = (int) sanitize_text_field($_GET['withdraw_id']);
|
136 |
|
137 |
-
do_action('tutor_before_delete_withdraw', $withdraw_id);
|
138 |
|
139 |
-
$wpdb->delete($wpdb->prefix.
|
140 |
|
141 |
-
do_action('tutor_after_delete_withdraw', $withdraw_id);
|
142 |
|
143 |
$redirect = true;
|
144 |
-
}else{
|
145 |
-
wp_die('Items deleted (or they would be if we had items to delete)!');
|
146 |
}
|
147 |
}
|
148 |
|
149 |
-
|
150 |
/**
|
151 |
* Reject Withdraw
|
152 |
*/
|
153 |
-
if( 'approved' === $this->current_action() ) {
|
154 |
-
$withdraw_id = (int) sanitize_text_field($_GET['withdraw_id']);
|
155 |
-
$withdraw
|
156 |
-
if ( ! $withdraw || $withdraw->status === 'approved'){
|
157 |
return;
|
158 |
}
|
159 |
|
160 |
-
do_action('tutor_before_approved_withdraw', $withdraw_id);
|
161 |
|
162 |
-
$wpdb->update(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
|
164 |
-
do_action('tutor_after_approved_withdraw', $withdraw_id);
|
165 |
|
166 |
$redirect = true;
|
167 |
}
|
@@ -169,25 +181,32 @@ class Withdraw_Requests_List extends \Tutor_List_Table {
|
|
169 |
/**
|
170 |
* Rejected
|
171 |
*/
|
172 |
-
if( 'rejected' === $this->current_action() ) {
|
173 |
-
$withdraw_id = (int) sanitize_text_field($_GET['withdraw_id']);
|
174 |
-
$withdraw
|
175 |
-
if ( ! $withdraw || $withdraw->status === 'rejected'){
|
176 |
return;
|
177 |
}
|
178 |
|
179 |
-
do_action('tutor_before_rejected_withdraw', $withdraw_id);
|
180 |
|
181 |
-
$wpdb->update(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
-
do_action('tutor_after_rejected_withdraw', $withdraw_id);
|
184 |
|
185 |
$redirect = true;
|
186 |
}
|
187 |
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
}
|
192 |
}
|
193 |
|
@@ -195,25 +214,27 @@ class Withdraw_Requests_List extends \Tutor_List_Table {
|
|
195 |
$per_page = 20;
|
196 |
|
197 |
$search_term = '';
|
198 |
-
if (isset($_REQUEST['s'])){
|
199 |
-
$search_term = sanitize_text_field($_REQUEST['s']);
|
200 |
}
|
201 |
|
202 |
$columns = $this->get_columns();
|
203 |
-
$hidden
|
204 |
-
|
205 |
-
$this->_column_headers = array($columns, $hidden);
|
206 |
-
$current_page
|
207 |
-
|
208 |
-
$start
|
209 |
-
$withdraw_requests = tutor_utils()->get_withdrawals_history(null, compact('start', 'per_page', 'search_term') );
|
210 |
-
$this->items
|
211 |
-
$count_result
|
212 |
-
|
213 |
-
$this->set_pagination_args(
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
|
|
218 |
}
|
219 |
}
|
1 |
<?php
|
2 |
namespace TUTOR;
|
3 |
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
+
}
|
7 |
|
8 |
+
if ( ! class_exists( 'Tutor_List_Table' ) ) {
|
9 |
+
include_once tutor()->path . 'classes/Tutor_List_Table.php';
|
10 |
}
|
11 |
|
12 |
class Withdraw_Requests_List extends \Tutor_List_Table {
|
13 |
|
14 |
const WITHDRAW_REQUEST_LIST_PAGE = 'tutor_withdraw_requests';
|
15 |
|
16 |
+
function __construct() {
|
17 |
global $status, $page;
|
18 |
|
19 |
+
// Set parent defaults
|
20 |
+
parent::__construct(
|
21 |
+
array(
|
22 |
+
'singular' => 'withdraw', // singular name of the listed records
|
23 |
+
'plural' => 'withdraw', // plural name of the listed records
|
24 |
+
'ajax' => false, // does this table support ajax?
|
25 |
+
)
|
26 |
+
);
|
27 |
|
28 |
$this->process_bulk_action();
|
29 |
}
|
30 |
|
31 |
+
function column_default( $item, $column_name ) {
|
32 |
+
switch ( $column_name ) {
|
33 |
case 'testing_col':
|
34 |
return $item->$column_name;
|
35 |
default:
|
36 |
+
return print_r( $item, true ); // Show the whole array for troubleshooting purposes
|
37 |
}
|
38 |
}
|
39 |
|
40 |
+
function column_cb( $item ) {
|
41 |
return sprintf(
|
42 |
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
43 |
+
/*$1%s*/ $this->_args['singular'], // Let's simply repurpose the table's singular label ("student")
|
44 |
+
/*$2%s*/ $item->withdraw_id // The value of the checkbox should be the record's id
|
45 |
);
|
46 |
}
|
47 |
|
48 |
+
function column_requested_user( $item ) {
|
49 |
+
echo '<p>' . $item->user_name . '</p><p>' . $item->user_email . '</p>';
|
50 |
|
51 |
$actions = array();
|
52 |
+
switch ( $item->status ) {
|
53 |
case 'pending':
|
54 |
+
$actions['approved'] = sprintf(
|
55 |
+
'<a href="?page=%s&action=%s&withdraw_id=%s">' . __( 'Approve', 'tutor' ) . '</a>',
|
56 |
+
self::WITHDRAW_REQUEST_LIST_PAGE,
|
57 |
+
'approved',
|
58 |
+
$item->withdraw_id
|
59 |
+
);
|
60 |
+
$actions['rejected'] = sprintf( '<a href="?page=%s&action=%s&withdraw_id=%s">' . __( 'Rejected', 'tutor' ) . '</a>', self::WITHDRAW_REQUEST_LIST_PAGE, 'rejected', $item->withdraw_id );
|
61 |
break;
|
62 |
case 'approved':
|
63 |
+
$actions['rejected'] = sprintf( '<a href="?page=%s&action=%s&withdraw_id=%s">' . __( 'Rejected', 'tutor' ) . '</a>', self::WITHDRAW_REQUEST_LIST_PAGE, 'rejected', $item->withdraw_id );
|
64 |
break;
|
65 |
case 'rejected':
|
66 |
+
$actions['approved'] = sprintf( '<a href="?page=%s&action=%s&withdraw_id=%s">' . __( 'Approve', 'tutor' ) . '</a>', self::WITHDRAW_REQUEST_LIST_PAGE, 'approved', $item->withdraw_id );
|
67 |
break;
|
68 |
}
|
69 |
|
70 |
+
$actions['delete'] = sprintf( '<a href="?page=%s&action=%s&withdraw_id=%s" onclick="return confirm(\'' . __( 'Are you Sure? It can not be undone.', 'tutor' ) . '\')">' . __( 'Delete', 'tutor' ) . '</a>', self::WITHDRAW_REQUEST_LIST_PAGE, 'delete', $item->withdraw_id );
|
71 |
|
72 |
+
return '<div class="withdraw-list-row-actions">' . $this->row_actions( $actions ) . '</div>';
|
73 |
}
|
74 |
+
function column_withdraw_method( $item ) {
|
75 |
+
if ( $item->method_data ) {
|
76 |
+
$data = maybe_unserialize( $item->method_data );
|
77 |
|
78 |
+
$method_name = tutor_utils()->avalue_dot( 'withdraw_method_name', $data );
|
79 |
|
80 |
+
if ( $method_name ) {
|
81 |
+
echo '<p><strong>' . $method_name . '</strong></p>';
|
82 |
}
|
83 |
|
84 |
+
unset( $data['withdraw_method_key'], $data['withdraw_method_name'] );
|
85 |
|
86 |
+
if ( tutor_utils()->count( $data ) ) {
|
87 |
+
foreach ( $data as $method_field ) {
|
88 |
+
$label = tutor_utils()->avalue_dot( 'label', $method_field );
|
89 |
+
$value = tutor_utils()->avalue_dot( 'value', $method_field );
|
90 |
+
echo '<p class="withdraw-method-data-row"> <span class="withdraw-method-label">' . $label . '</span> : <span class="withdraw-method-value">' . $value . '</span> </p>';
|
91 |
}
|
92 |
}
|
|
|
93 |
}
|
94 |
return '';
|
95 |
}
|
96 |
|
97 |
+
function column_requested_at( $item ) {
|
98 |
+
echo '<p>' . date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $item->created_at ) ) . '</p>';
|
99 |
}
|
100 |
|
101 |
+
function column_amount( $item ) {
|
102 |
$available_status = array(
|
103 |
+
'pending' => __( 'pending', 'tutor' ),
|
104 |
+
'approved' => __( 'approved', 'tutor' ),
|
105 |
+
'rejected' => __( 'rejected', 'tutor' ),
|
106 |
);
|
107 |
+
echo '<p>' . tutor_utils()->tutor_price( $item->amount ) . '</p>';
|
108 |
+
echo '<p="withdraw-status withdraw-status-' . $item->status . '">' . __( isset( $available_status[ $item->status ] ) ? $available_status[ $item->status ] : $item->status, 'tutor' ) . '</span></p>';
|
109 |
}
|
110 |
|
111 |
+
function get_columns() {
|
112 |
$columns = array(
|
113 |
+
'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
|
114 |
+
'requested_user' => __( 'Requested By', 'tutor' ),
|
115 |
+
'amount' => __( 'Amount', 'tutor' ),
|
116 |
+
'withdraw_method' => __( 'Withdrawal Method', 'tutor' ),
|
117 |
+
'requested_at' => __( 'Requested Time', 'tutor' ),
|
118 |
);
|
119 |
return $columns;
|
120 |
}
|
121 |
|
122 |
function get_bulk_actions() {
|
123 |
$actions = array(
|
124 |
+
// 'delete' => 'Delete'
|
125 |
);
|
126 |
return $actions;
|
127 |
}
|
129 |
function process_bulk_action() {
|
130 |
global $wpdb;
|
131 |
|
132 |
+
$withdraw_page_url = admin_url( 'admin.php?page=' . self::WITHDRAW_REQUEST_LIST_PAGE );
|
133 |
+
$date = date( 'Y-m-d H:i:s', tutor_time() );
|
134 |
+
$redirect = false;
|
135 |
|
136 |
+
// Detect when a bulk action is being triggered...
|
137 |
+
if ( 'delete' === $this->current_action() ) {
|
138 |
+
$should_withdraw_delete = apply_filters( 'tutor_should_withdraw_delete', true );
|
139 |
|
140 |
+
if ( $should_withdraw_delete ) {
|
141 |
+
$withdraw_id = (int) sanitize_text_field( $_GET['withdraw_id'] );
|
142 |
|
143 |
+
do_action( 'tutor_before_delete_withdraw', $withdraw_id );
|
144 |
|
145 |
+
$wpdb->delete( $wpdb->prefix . 'tutor_withdraws', array( 'withdraw_id' => $withdraw_id ) );
|
146 |
|
147 |
+
do_action( 'tutor_after_delete_withdraw', $withdraw_id );
|
148 |
|
149 |
$redirect = true;
|
150 |
+
} else {
|
151 |
+
wp_die( 'Items deleted (or they would be if we had items to delete)!' );
|
152 |
}
|
153 |
}
|
154 |
|
|
|
155 |
/**
|
156 |
* Reject Withdraw
|
157 |
*/
|
158 |
+
if ( 'approved' === $this->current_action() ) {
|
159 |
+
$withdraw_id = (int) sanitize_text_field( $_GET['withdraw_id'] );
|
160 |
+
$withdraw = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_withdraws WHERE withdraw_id = %d ", $withdraw_id ) );
|
161 |
+
if ( ! $withdraw || $withdraw->status === 'approved' ) {
|
162 |
return;
|
163 |
}
|
164 |
|
165 |
+
do_action( 'tutor_before_approved_withdraw', $withdraw_id );
|
166 |
|
167 |
+
$wpdb->update(
|
168 |
+
$wpdb->prefix . 'tutor_withdraws',
|
169 |
+
array(
|
170 |
+
'status' => 'approved',
|
171 |
+
'updated_at' => $date,
|
172 |
+
),
|
173 |
+
array( 'withdraw_id' => $withdraw_id )
|
174 |
+
);
|
175 |
|
176 |
+
do_action( 'tutor_after_approved_withdraw', $withdraw_id );
|
177 |
|
178 |
$redirect = true;
|
179 |
}
|
181 |
/**
|
182 |
* Rejected
|
183 |
*/
|
184 |
+
if ( 'rejected' === $this->current_action() ) {
|
185 |
+
$withdraw_id = (int) sanitize_text_field( $_GET['withdraw_id'] );
|
186 |
+
$withdraw = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}tutor_withdraws WHERE withdraw_id = %d ", $withdraw_id ) );
|
187 |
+
if ( ! $withdraw || $withdraw->status === 'rejected' ) {
|
188 |
return;
|
189 |
}
|
190 |
|
191 |
+
do_action( 'tutor_before_rejected_withdraw', $withdraw_id );
|
192 |
|
193 |
+
$wpdb->update(
|
194 |
+
$wpdb->prefix . 'tutor_withdraws',
|
195 |
+
array(
|
196 |
+
'status' => 'rejected',
|
197 |
+
'updated_at' => $date,
|
198 |
+
),
|
199 |
+
array( 'withdraw_id' => $withdraw_id )
|
200 |
+
);
|
201 |
|
202 |
+
do_action( 'tutor_after_rejected_withdraw', $withdraw_id );
|
203 |
|
204 |
$redirect = true;
|
205 |
}
|
206 |
|
207 |
+
if($this->current_action()) {
|
208 |
+
wp_redirect( $withdraw_page_url );
|
209 |
+
exit;
|
210 |
}
|
211 |
}
|
212 |
|
214 |
$per_page = 20;
|
215 |
|
216 |
$search_term = '';
|
217 |
+
if ( isset( $_REQUEST['s'] ) ) {
|
218 |
+
$search_term = sanitize_text_field( $_REQUEST['s'] );
|
219 |
}
|
220 |
|
221 |
$columns = $this->get_columns();
|
222 |
+
$hidden = array();
|
223 |
+
|
224 |
+
$this->_column_headers = array( $columns, $hidden );
|
225 |
+
$current_page = $this->get_pagenum();
|
226 |
+
|
227 |
+
$start = ( $current_page - 1 ) * $per_page;
|
228 |
+
$withdraw_requests = tutor_utils()->get_withdrawals_history( null, compact( 'start', 'per_page', 'search_term' ) );
|
229 |
+
$this->items = $withdraw_requests->results;
|
230 |
+
$count_result = $withdraw_requests->count;
|
231 |
+
|
232 |
+
$this->set_pagination_args(
|
233 |
+
array(
|
234 |
+
'total_items' => $count_result,
|
235 |
+
'per_page' => $per_page,
|
236 |
+
'total_pages' => ceil( $count_result / $per_page ),
|
237 |
+
)
|
238 |
+
);
|
239 |
}
|
240 |
}
|
classes/WooCommerce.php
CHANGED
@@ -9,81 +9,85 @@
|
|
9 |
|
10 |
namespace TUTOR;
|
11 |
|
12 |
-
if (!defined('ABSPATH'))
|
13 |
exit;
|
|
|
14 |
|
15 |
class WooCommerce extends Tutor_Base {
|
16 |
|
17 |
public function __construct() {
|
18 |
parent::__construct();
|
19 |
|
20 |
-
add_action('tutor_options_before_woocommerce', array($this, 'notice_before_option'));
|
21 |
|
22 |
-
//Add option settings
|
23 |
-
add_filter('tutor_monetization_options', array($this, 'tutor_monetization_options'));
|
24 |
-
add_filter('tutor/options/attr', array($this, 'add_options'));
|
25 |
|
26 |
-
$monetize_by = tutils()->get_option('monetize_by');
|
27 |
-
if ($monetize_by !== 'wc') {
|
28 |
return;
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
* Is Course Purchasable
|
33 |
*/
|
34 |
-
add_filter('is_course_purchasable', array($this, 'is_course_purchasable'), 10, 2);
|
35 |
-
add_filter('get_tutor_course_price', array($this, 'get_tutor_course_price'), 10, 2);
|
36 |
-
add_filter('tutor_course_sell_by', array($this, 'tutor_course_sell_by'));
|
37 |
|
38 |
-
add_filter('product_type_options', array($this, 'add_tutor_type_in_wc_product'));
|
39 |
|
40 |
-
add_action('add_meta_boxes', array($this, 'register_meta_box'));
|
41 |
-
add_action('save_post_' . $this->course_post_type, array($this, 'save_course_meta'));
|
42 |
-
add_action('save_post_product', array($this, 'save_wc_product_meta'));
|
43 |
|
44 |
-
add_action('tutor_course/single/before/enroll', 'wc_print_notices');
|
45 |
|
46 |
/**
|
47 |
* After place new order
|
48 |
*/
|
49 |
-
add_action('woocommerce_new_order', array($this, 'course_placing_order_from_admin'), 10, 3);
|
50 |
-
add_action('woocommerce_new_order_item', array($this, 'course_placing_order_from_customer'), 10, 3);
|
51 |
|
52 |
/**
|
53 |
* Order Status Hook
|
54 |
*
|
55 |
* Remove course from active courses if an order is cancelled or refunded
|
56 |
*/
|
57 |
-
add_action('woocommerce_order_status_changed', array($this, 'enrolled_courses_status_change'), 10, 3);
|
58 |
|
59 |
/**
|
60 |
* Add Earning Data
|
61 |
*/
|
62 |
-
add_action('woocommerce_new_order_item', array($this, 'add_earning_data'), 10, 3);
|
63 |
-
add_action('woocommerce_order_status_changed', array($this, 'add_earning_data_status_change'), 10, 3);
|
64 |
|
65 |
/**
|
66 |
* WC Print Notices After Enroll
|
|
|
67 |
* @since v.1.3.5
|
68 |
*/
|
69 |
-
if (tutils()->has_wc()) {
|
70 |
-
add_action('tutor_course/single/before/inner-wrap', 'wc_print_notices', 10);
|
71 |
-
add_action('tutor_course/single/enrolled/before/inner-wrap', 'wc_print_notices', 10);
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
* Manage WooCommerce plugin dependency
|
|
|
76 |
* @since v.1.7.8
|
77 |
*/
|
78 |
-
$woocommerce_path = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR .
|
79 |
-
register_deactivation_hook( $woocommerce_path, array($this, 'disable_tutor_monetization') );
|
80 |
/**
|
81 |
-
* Redirect student on enrolled courses after course
|
82 |
* enrollment complete
|
|
|
83 |
* @since 1.9.0
|
84 |
-
*/
|
85 |
-
add_action( 'woocommerce_thankyou', array($this, 'redirect_to_enrolled_courses') );
|
86 |
-
|
87 |
/**
|
88 |
* Change woo commerce cart product link if it is tutor product
|
89 |
*/
|
@@ -92,7 +96,7 @@ class WooCommerce extends Tutor_Base {
|
|
92 |
|
93 |
public function notice_before_option() {
|
94 |
$has_wc = tutor_utils()->has_wc();
|
95 |
-
if ($has_wc) {
|
96 |
return;
|
97 |
}
|
98 |
|
@@ -100,42 +104,47 @@ class WooCommerce extends Tutor_Base {
|
|
100 |
?>
|
101 |
<div class="tutor-notice-warning">
|
102 |
<p>
|
103 |
-
<?php
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
106 |
</p>
|
107 |
-
<p><?php _e('This notice will disappear after activating <strong>WooCommerce</strong>', 'tutor'); ?></p>
|
108 |
</div>
|
109 |
<?php
|
110 |
echo ob_get_clean();
|
111 |
}
|
112 |
|
113 |
-
public function is_course_purchasable($bool, $course_id) {
|
114 |
-
if (!tutor_utils()->has_wc()) {
|
115 |
return false;
|
116 |
}
|
117 |
|
118 |
-
$course_id
|
119 |
-
$has_product_id = get_post_meta($course_id, '_tutor_course_product_id', true);
|
120 |
-
if ($has_product_id) {
|
121 |
return true;
|
122 |
}
|
123 |
return false;
|
124 |
}
|
125 |
|
126 |
-
public function get_tutor_course_price($price, $course_id) {
|
127 |
$price = null;
|
128 |
|
129 |
-
if (tutor_utils()->is_course_purchasable($course_id)) {
|
130 |
-
if (tutor_utils()->has_wc()) {
|
131 |
-
$product_id = tutor_utils()->get_course_product_id($course_id);
|
132 |
-
$product = wc_get_product($product_id);
|
133 |
|
134 |
-
if ($product) {
|
135 |
ob_start();
|
136 |
?>
|
137 |
<div class="price">
|
138 |
-
<?php echo $product->get_price_html(); ?>
|
139 |
</div>
|
140 |
<?php
|
141 |
return ob_get_clean();
|
@@ -150,12 +159,12 @@ class WooCommerce extends Tutor_Base {
|
|
150 |
return 'woocommerce';
|
151 |
}
|
152 |
|
153 |
-
public function add_tutor_type_in_wc_product($types) {
|
154 |
-
$types['tutor_product'] =
|
155 |
'id' => '_tutor_product',
|
156 |
'wrapper_class' => 'show_if_simple',
|
157 |
-
'label' => __('For Tutor', 'tutor'),
|
158 |
-
'description' => __('This checkmark ensure that you will sell a specif course via this product.', 'tutor'),
|
159 |
'default' => 'no',
|
160 |
);
|
161 |
|
@@ -163,11 +172,11 @@ class WooCommerce extends Tutor_Base {
|
|
163 |
}
|
164 |
|
165 |
public function register_meta_box() {
|
166 |
-
add_meta_box('tutor-attach-product', __('Add Product', 'tutor'), array($this, 'course_add_product_metabox'), $this->course_post_type, 'advanced', 'high');
|
167 |
}
|
168 |
|
169 |
public function course_add_product_metabox() {
|
170 |
-
include
|
171 |
}
|
172 |
|
173 |
/**
|
@@ -175,25 +184,25 @@ class WooCommerce extends Tutor_Base {
|
|
175 |
*
|
176 |
* Save course meta for attaching product
|
177 |
*/
|
178 |
-
public function save_course_meta($post_ID) {
|
179 |
-
$product_id = (int)sanitize_text_field( tutor_utils()->avalue_dot('_tutor_course_product_id', $_POST, 0) )
|
180 |
-
|
181 |
-
if ($product_id === -1) {
|
182 |
-
delete_post_meta($post_ID, '_tutor_course_product_id');
|
183 |
-
}
|
184 |
-
update_post_meta($post_ID, '_tutor_course_product_id', $product_id);
|
185 |
-
//Mark product for woocommerce
|
186 |
-
update_post_meta($product_id, '_virtual', 'yes');
|
187 |
-
update_post_meta($product_id, '_tutor_product', 'yes');
|
188 |
}
|
189 |
}
|
190 |
|
191 |
-
public function save_wc_product_meta($post_ID) {
|
192 |
-
$is_tutor_product = sanitize_text_field( tutor_utils()->avalue_dot('_tutor_product', $_POST) );
|
193 |
-
if ($is_tutor_product === 'on') {
|
194 |
-
update_post_meta($post_ID, '_tutor_product', 'yes');
|
195 |
} else {
|
196 |
-
delete_post_meta($post_ID, '_tutor_product');
|
197 |
}
|
198 |
}
|
199 |
|
@@ -201,27 +210,27 @@ class WooCommerce extends Tutor_Base {
|
|
201 |
*
|
202 |
* Take enrolled course action based on order status change
|
203 |
*/
|
204 |
-
public function enrolled_courses_status_change($order_id, $status_from, $status_to) {
|
205 |
-
if (!tutor_utils()->is_tutor_order($order_id)) {
|
206 |
return;
|
207 |
}
|
208 |
global $wpdb;
|
209 |
|
210 |
-
$enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id($order_id);
|
211 |
|
212 |
-
if ($enrolled_ids_with_course) {
|
213 |
-
$enrolled_ids = wp_list_pluck($enrolled_ids_with_course, 'enrolled_id');
|
214 |
|
215 |
-
if (is_array($enrolled_ids) && count($enrolled_ids)) {
|
216 |
-
foreach ($enrolled_ids as $enrolled_id) {
|
217 |
|
218 |
-
tutils()->course_enrol_status_change($enrolled_id, $status_to);
|
219 |
|
220 |
// Invoke enrolled hook
|
221 |
-
if($status_to == 'completed'){
|
222 |
-
$user_id
|
223 |
-
$course_id = get_post_field('post_parent', $enrolled_id);
|
224 |
-
do_action('tutor_after_enrolled', $course_id, $user_id, $enrolled_id);
|
225 |
}
|
226 |
}
|
227 |
}
|
@@ -233,18 +242,22 @@ class WooCommerce extends Tutor_Base {
|
|
233 |
*
|
234 |
* @return array|bool
|
235 |
*/
|
236 |
-
public function get_course_enrolled_ids_by_order_id($order_id) {
|
237 |
global $wpdb;
|
238 |
-
//Getting all of courses ids within this order
|
239 |
|
240 |
-
$courses_ids = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key LIKE '_tutor_order_for_course_id_%' ", $order_id));
|
241 |
|
242 |
-
if (is_array($courses_ids) && count($courses_ids)) {
|
243 |
$course_enrolled_by_order = array();
|
244 |
-
foreach ($courses_ids as $courses_id) {
|
245 |
-
$course_id = str_replace('_tutor_order_for_course_id_', '', $courses_id->meta_key);
|
246 |
-
//array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id, 'order_id' => $courses_id->post_id))
|
247 |
-
$course_enrolled_by_order[] = array(
|
|
|
|
|
|
|
|
|
248 |
}
|
249 |
return $course_enrolled_by_order;
|
250 |
}
|
@@ -256,11 +269,11 @@ class WooCommerce extends Tutor_Base {
|
|
256 |
*
|
257 |
* TODO: right now it's unused
|
258 |
*/
|
259 |
-
public function remove_active_course($order_id) {
|
260 |
global $wpdb;
|
261 |
-
//Getting all of courses ids within this order
|
262 |
|
263 |
-
$courses_ids = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d meta_key LIKE '_tutor_order_for_course_id_%' ", $order_id));
|
264 |
}
|
265 |
|
266 |
|
@@ -271,27 +284,28 @@ class WooCommerce extends Tutor_Base {
|
|
271 |
*
|
272 |
* Add option for WooCommerce settings
|
273 |
*/
|
274 |
-
public function add_options($attr) {
|
275 |
|
276 |
$attr['woocommerce'] = array(
|
277 |
-
'label'
|
278 |
|
279 |
-
'sections'
|
280 |
'general' => array(
|
281 |
-
'label'
|
282 |
-
'desc'
|
283 |
'fields' => array(
|
284 |
-
/*
|
|
|
285 |
'type' => 'checkbox',
|
286 |
'label' => __('Enable / Disable', 'tutor'),
|
287 |
'label_title' => __('Enable WooComerce to sell course', 'tutor'),
|
288 |
'desc' => __('By integrating WooCommerce, you can sell your course', 'tutor'),
|
289 |
),*/
|
290 |
'enable_guest_course_cart' => array(
|
291 |
-
'type'
|
292 |
-
'label'
|
293 |
-
'label_title'
|
294 |
-
'desc'
|
295 |
),
|
296 |
),
|
297 |
),
|
@@ -310,10 +324,10 @@ class WooCommerce extends Tutor_Base {
|
|
310 |
*
|
311 |
* @since v.1.3.5
|
312 |
*/
|
313 |
-
public function tutor_monetization_options($arr) {
|
314 |
$has_wc = tutils()->has_wc();
|
315 |
-
if ($has_wc) {
|
316 |
-
$arr['wc'] = __('WooCommerce', 'tutor');
|
317 |
}
|
318 |
return $arr;
|
319 |
}
|
@@ -327,59 +341,62 @@ class WooCommerce extends Tutor_Base {
|
|
327 |
*
|
328 |
* @since v.1.1.2
|
329 |
*/
|
330 |
-
public function add_earning_data($item_id, $item, $order_id) {
|
331 |
global $wpdb;
|
332 |
-
$item = new \WC_Order_Item_Product($item);
|
333 |
|
334 |
-
$product_id
|
335 |
-
$if_has_course = tutor_utils()->product_belongs_with_course($product_id);
|
336 |
|
337 |
-
if ($if_has_course) {
|
338 |
|
339 |
-
$enable_tutor_earning = tutor_utils()->get_option('enable_tutor_earning');
|
340 |
-
if (
|
341 |
return;
|
342 |
}
|
343 |
|
344 |
-
$course_id
|
345 |
-
$user_id
|
346 |
-
$order_status = $wpdb->get_var($wpdb->prepare("SELECT post_status from {$wpdb->posts} where ID = %d ", $order_id));
|
347 |
|
348 |
/**
|
349 |
* Return here if already added this product from this order
|
|
|
350 |
* @since v1.9.7
|
351 |
*/
|
352 |
-
$exist_count = (int)$wpdb->get_var(
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
|
|
357 |
AND user_id=%d",
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
|
|
362 |
|
363 |
-
if($exist_count>0) {
|
364 |
return;
|
365 |
}
|
366 |
|
367 |
$total_price = $item->get_total();
|
368 |
|
369 |
-
$fees_deduct_data
|
370 |
-
$tutor_earning_fees
|
371 |
-
$enable_fees_deducting = tutor_utils()->avalue_dot('enable_fees_deducting', $tutor_earning_fees);
|
372 |
|
373 |
$course_price_grand_total = $total_price;
|
374 |
|
375 |
-
if ($enable_fees_deducting) {
|
376 |
-
$fees_name
|
377 |
-
$fees_amount = (int) tutor_utils()->avalue_dot('fees_amount', $tutor_earning_fees);
|
378 |
-
$fees_type
|
379 |
|
380 |
-
if ($fees_amount > 0) {
|
381 |
-
if ($fees_type === 'percent') {
|
382 |
-
$fees_amount = ($total_price * $fees_amount) / 100;
|
383 |
}
|
384 |
|
385 |
/*
|
@@ -391,23 +408,23 @@ class WooCommerce extends Tutor_Base {
|
|
391 |
}
|
392 |
|
393 |
$fees_deduct_data = array(
|
394 |
-
'deduct_fees_amount'
|
395 |
-
'deduct_fees_name'
|
396 |
-
'deduct_fees_type'
|
397 |
);
|
398 |
}
|
399 |
|
400 |
-
$instructor_rate = tutor_utils()->get_option('earning_instructor_commission');
|
401 |
-
$admin_rate
|
402 |
|
403 |
$instructor_amount = 0;
|
404 |
-
if ($instructor_rate > 0) {
|
405 |
-
$instructor_amount = ($course_price_grand_total * $instructor_rate) / 100;
|
406 |
}
|
407 |
|
408 |
$admin_amount = 0;
|
409 |
-
if ($admin_rate > 0) {
|
410 |
-
$admin_amount = ($course_price_grand_total * $admin_rate) / 100;
|
411 |
}
|
412 |
|
413 |
$commission_type = 'percent';
|
@@ -415,39 +432,39 @@ class WooCommerce extends Tutor_Base {
|
|
415 |
// (Use Pro Filter - Start)
|
416 |
// The response must be same array structure.
|
417 |
// Do not change used variable names here, or change in both of here and pro plugin
|
418 |
-
$pro_arg
|
419 |
-
'user_id'
|
420 |
-
'instructor_rate'
|
421 |
-
'admin_rate'
|
422 |
-
'instructor_amount'
|
423 |
-
'admin_amount'
|
424 |
-
'course_price_grand_total'
|
425 |
-
'commission_type'
|
426 |
-
|
427 |
-
$pro_calculation = apply_filters('tutor_pro_earning_calculator', $pro_arg);
|
428 |
-
extract($pro_calculation);
|
429 |
-
// (Use Pro Filter - End)
|
430 |
|
431 |
$earning_data = array(
|
432 |
-
'user_id'
|
433 |
-
'course_id'
|
434 |
-
'order_id'
|
435 |
-
'order_status'
|
436 |
-
'course_price_total'
|
437 |
-
'course_price_grand_total'
|
438 |
-
|
439 |
-
'instructor_amount'
|
440 |
-
'instructor_rate'
|
441 |
-
'admin_amount'
|
442 |
-
'admin_rate'
|
443 |
-
|
444 |
-
'commission_type'
|
445 |
-
'process_by'
|
446 |
-
'created_at'
|
447 |
);
|
448 |
-
$earning_data = apply_filters('tutor_new_earning_data', array_merge($earning_data, $fees_deduct_data));
|
449 |
|
450 |
-
$wpdb->insert($wpdb->prefix . 'tutor_earnings', $earning_data);
|
451 |
}
|
452 |
}
|
453 |
|
@@ -460,37 +477,37 @@ class WooCommerce extends Tutor_Base {
|
|
460 |
*
|
461 |
* @since v.1.1.2
|
462 |
*/
|
463 |
-
public function add_earning_data_status_change($order_id, $status_from, $status_to) {
|
464 |
-
if (!tutor_utils()->is_tutor_order($order_id)) {
|
465 |
return;
|
466 |
}
|
467 |
global $wpdb;
|
468 |
|
469 |
-
$is_earning_data = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(earning_id) FROM {$wpdb->prefix}tutor_earnings WHERE order_id = %d ", $order_id));
|
470 |
-
if ($is_earning_data) {
|
471 |
-
$wpdb->update($wpdb->prefix . 'tutor_earnings', array('order_status' => $status_to), array('order_id' => $order_id));
|
472 |
}
|
473 |
}
|
474 |
|
475 |
/**
|
476 |
* Course placing order from admin
|
477 |
-
*
|
478 |
* @param $order_id
|
479 |
* @since v.1.6.7
|
480 |
*/
|
481 |
-
public function course_placing_order_from_admin($order_id) {
|
482 |
-
if (!is_admin()) {
|
483 |
return;
|
484 |
}
|
485 |
-
|
486 |
$order = wc_get_order( $order_id );
|
487 |
-
foreach ($order->get_items() as $item) {
|
488 |
-
$product_id
|
489 |
-
$if_has_course = tutor_utils()->product_belongs_with_course($product_id);
|
490 |
-
if ($if_has_course) {
|
491 |
-
$course_id
|
492 |
$customer_id = $order->get_customer_id();
|
493 |
-
tutor_utils()->do_enroll($course_id, $order_id, $customer_id);
|
494 |
}
|
495 |
}
|
496 |
}
|
@@ -501,92 +518,97 @@ class WooCommerce extends Tutor_Base {
|
|
501 |
* @param $order_id
|
502 |
* @since v.1.6.7
|
503 |
*/
|
504 |
-
public function course_placing_order_from_customer($item_id, $item, $order_id) {
|
505 |
-
if (is_admin()) {
|
506 |
return;
|
507 |
}
|
508 |
|
509 |
-
$item
|
510 |
-
$product_id
|
511 |
-
$if_has_course = tutor_utils()->product_belongs_with_course($product_id);
|
512 |
|
513 |
-
if ($if_has_course){
|
514 |
$course_id = $if_has_course->post_id;
|
515 |
-
tutor_utils()->do_enroll($course_id, $order_id);
|
516 |
}
|
517 |
}
|
518 |
|
519 |
/**
|
520 |
* Disable course monetization on woocommerce deactivation
|
|
|
521 |
* @since v.1.7.8
|
522 |
*/
|
523 |
public function disable_tutor_monetization() {
|
524 |
-
tutils()->update_option('monetize_by', 'free');
|
525 |
-
update_option('tutor_show_woocommerce_notice', true);
|
526 |
}
|
527 |
|
528 |
/**
|
529 |
-
* Redirect student on enrolled courses after course
|
530 |
* enrollment complete if course is purchasable
|
|
|
531 |
* @param $order_id | int
|
532 |
* @since 1.9.0
|
533 |
-
|
534 |
public function redirect_to_enrolled_courses( $order_id ) {
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
|
540 |
-
//get woo order details
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
}
|
551 |
}
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
|
|
557 |
}
|
558 |
|
559 |
/**
|
560 |
* Change product url on cart page if product is tutor course
|
561 |
-
*
|
562 |
* @since 1.9.8
|
563 |
*/
|
564 |
function tutor_update_product_url( $permalink, $cart_item ) {
|
565 |
|
566 |
-
$woo_product_id = $cart_item['product_id'];
|
567 |
-
$product_meta
|
568 |
|
569 |
-
if( isset( $product_meta['_tutor_product'] ) && $product_meta['_tutor_product'][0] ) {
|
570 |
|
571 |
-
global $wpdb;
|
572 |
-
$table
|
573 |
-
$post_id
|
574 |
|
575 |
-
if( $post_id ) {
|
576 |
-
$data =
|
577 |
-
return $data;
|
578 |
}
|
579 |
}
|
580 |
}
|
581 |
}
|
582 |
|
583 |
|
584 |
-
add_action(
|
|
|
|
|
585 |
|
586 |
-
|
587 |
|
588 |
-
|
589 |
-
|
590 |
-
|
|
|
591 |
}
|
592 |
-
|
9 |
|
10 |
namespace TUTOR;
|
11 |
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
|
16 |
class WooCommerce extends Tutor_Base {
|
17 |
|
18 |
public function __construct() {
|
19 |
parent::__construct();
|
20 |
|
21 |
+
add_action( 'tutor_options_before_woocommerce', array( $this, 'notice_before_option' ) );
|
22 |
|
23 |
+
// Add option settings
|
24 |
+
add_filter( 'tutor_monetization_options', array( $this, 'tutor_monetization_options' ) );
|
25 |
+
add_filter( 'tutor/options/attr', array( $this, 'add_options' ) );
|
26 |
|
27 |
+
$monetize_by = tutils()->get_option( 'monetize_by' );
|
28 |
+
if ( $monetize_by !== 'wc' ) {
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
* Is Course Purchasable
|
34 |
*/
|
35 |
+
add_filter( 'is_course_purchasable', array( $this, 'is_course_purchasable' ), 10, 2 );
|
36 |
+
add_filter( 'get_tutor_course_price', array( $this, 'get_tutor_course_price' ), 10, 2 );
|
37 |
+
add_filter( 'tutor_course_sell_by', array( $this, 'tutor_course_sell_by' ) );
|
38 |
|
39 |
+
add_filter( 'product_type_options', array( $this, 'add_tutor_type_in_wc_product' ) );
|
40 |
|
41 |
+
add_action( 'add_meta_boxes', array( $this, 'register_meta_box' ) );
|
42 |
+
add_action( 'save_post_' . $this->course_post_type, array( $this, 'save_course_meta' ) );
|
43 |
+
add_action( 'save_post_product', array( $this, 'save_wc_product_meta' ) );
|
44 |
|
45 |
+
add_action( 'tutor_course/single/before/enroll', 'wc_print_notices' );
|
46 |
|
47 |
/**
|
48 |
* After place new order
|
49 |
*/
|
50 |
+
add_action( 'woocommerce_new_order', array( $this, 'course_placing_order_from_admin' ), 10, 3 );
|
51 |
+
add_action( 'woocommerce_new_order_item', array( $this, 'course_placing_order_from_customer' ), 10, 3 );
|
52 |
|
53 |
/**
|
54 |
* Order Status Hook
|
55 |
*
|
56 |
* Remove course from active courses if an order is cancelled or refunded
|
57 |
*/
|
58 |
+
add_action( 'woocommerce_order_status_changed', array( $this, 'enrolled_courses_status_change' ), 10, 3 );
|
59 |
|
60 |
/**
|
61 |
* Add Earning Data
|
62 |
*/
|
63 |
+
add_action( 'woocommerce_new_order_item', array( $this, 'add_earning_data' ), 10, 3 );
|
64 |
+
add_action( 'woocommerce_order_status_changed', array( $this, 'add_earning_data_status_change' ), 10, 3 );
|
65 |
|
66 |
/**
|
67 |
* WC Print Notices After Enroll
|
68 |
+
*
|
69 |
* @since v.1.3.5
|
70 |
*/
|
71 |
+
if ( tutils()->has_wc() ) {
|
72 |
+
add_action( 'tutor_course/single/before/inner-wrap', 'wc_print_notices', 10 );
|
73 |
+
add_action( 'tutor_course/single/enrolled/before/inner-wrap', 'wc_print_notices', 10 );
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
* Manage WooCommerce plugin dependency
|
78 |
+
*
|
79 |
* @since v.1.7.8
|
80 |
*/
|
81 |
+
$woocommerce_path = dirname( dirname( __DIR__ ) ) . DIRECTORY_SEPARATOR . 'woocommerce' . DIRECTORY_SEPARATOR . 'woocommerce.php';
|
82 |
+
register_deactivation_hook( $woocommerce_path, array( $this, 'disable_tutor_monetization' ) );
|
83 |
/**
|
84 |
+
* Redirect student on enrolled courses after course
|
85 |
* enrollment complete
|
86 |
+
*
|
87 |
* @since 1.9.0
|
88 |
+
*/
|
89 |
+
add_action( 'woocommerce_thankyou', array( $this, 'redirect_to_enrolled_courses' ) );
|
90 |
+
|
91 |
/**
|
92 |
* Change woo commerce cart product link if it is tutor product
|
93 |
*/
|
96 |
|
97 |
public function notice_before_option() {
|
98 |
$has_wc = tutor_utils()->has_wc();
|
99 |
+
if ( $has_wc ) {
|
100 |
return;
|
101 |
}
|
102 |
|
104 |
?>
|
105 |
<div class="tutor-notice-warning">
|
106 |
<p>
|
107 |
+
<?php
|
108 |
+
_e(
|
109 |
+
' Seems like you don’t have WooCommerce plugin installed on your site. In order to use this functionality, you need to have the
|
110 |
+
WooCommerce plugin installed. Get back on this page after installing the plugin and enable the following feature to start selling
|
111 |
+
courses with Tutor.',
|
112 |
+
'tutor'
|
113 |
+
);
|
114 |
+
?>
|
115 |
</p>
|
116 |
+
<p><?php _e( 'This notice will disappear after activating <strong>WooCommerce</strong>', 'tutor' ); ?></p>
|
117 |
</div>
|
118 |
<?php
|
119 |
echo ob_get_clean();
|
120 |
}
|
121 |
|
122 |
+
public function is_course_purchasable( $bool, $course_id ) {
|
123 |
+
if ( ! tutor_utils()->has_wc() ) {
|
124 |
return false;
|
125 |
}
|
126 |
|
127 |
+
$course_id = tutor_utils()->get_post_id( $course_id );
|
128 |
+
$has_product_id = get_post_meta( $course_id, '_tutor_course_product_id', true );
|
129 |
+
if ( $has_product_id ) {
|
130 |
return true;
|
131 |
}
|
132 |
return false;
|
133 |
}
|
134 |
|
135 |
+
public function get_tutor_course_price( $price, $course_id ) {
|
136 |
$price = null;
|
137 |
|
138 |
+
if ( tutor_utils()->is_course_purchasable( $course_id ) ) {
|
139 |
+
if ( tutor_utils()->has_wc() ) {
|
140 |
+
$product_id = tutor_utils()->get_course_product_id( $course_id );
|
141 |
+
$product = wc_get_product( $product_id );
|
142 |
|
143 |
+
if ( $product ) {
|
144 |
ob_start();
|
145 |
?>
|
146 |
<div class="price">
|
147 |
+
<?php echo $product->get_price_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
148 |
</div>
|
149 |
<?php
|
150 |
return ob_get_clean();
|
159 |
return 'woocommerce';
|
160 |
}
|
161 |
|
162 |
+
public function add_tutor_type_in_wc_product( $types ) {
|
163 |
+
$types['tutor_product'] = array(
|
164 |
'id' => '_tutor_product',
|
165 |
'wrapper_class' => 'show_if_simple',
|
166 |
+
'label' => __( 'For Tutor', 'tutor' ),
|
167 |
+
'description' => __( 'This checkmark ensure that you will sell a specif course via this product.', 'tutor' ),
|
168 |
'default' => 'no',
|
169 |
);
|
170 |
|
172 |
}
|
173 |
|
174 |
public function register_meta_box() {
|
175 |
+
add_meta_box( 'tutor-attach-product', __( 'Add Product', 'tutor' ), array( $this, 'course_add_product_metabox' ), $this->course_post_type, 'advanced', 'high' );
|
176 |
}
|
177 |
|
178 |
public function course_add_product_metabox() {
|
179 |
+
include tutor()->path . 'views/metabox/course-add-product-metabox.php';
|
180 |
}
|
181 |
|
182 |
/**
|
184 |
*
|
185 |
* Save course meta for attaching product
|
186 |
*/
|
187 |
+
public function save_course_meta( $post_ID ) {
|
188 |
+
$product_id = (int) sanitize_text_field( tutor_utils()->avalue_dot( '_tutor_course_product_id', $_POST, 0 ) );
|
189 |
+
|
190 |
+
if ( $product_id === -1 ) {
|
191 |
+
delete_post_meta( $post_ID, '_tutor_course_product_id' );
|
192 |
+
} elseif ( $product_id ) {
|
193 |
+
update_post_meta( $post_ID, '_tutor_course_product_id', $product_id );
|
194 |
+
// Mark product for woocommerce
|
195 |
+
update_post_meta( $product_id, '_virtual', 'yes' );
|
196 |
+
update_post_meta( $product_id, '_tutor_product', 'yes' );
|
197 |
}
|
198 |
}
|
199 |
|
200 |
+
public function save_wc_product_meta( $post_ID ) {
|
201 |
+
$is_tutor_product = sanitize_text_field( tutor_utils()->avalue_dot( '_tutor_product', $_POST ) );
|
202 |
+
if ( $is_tutor_product === 'on' ) {
|
203 |
+
update_post_meta( $post_ID, '_tutor_product', 'yes' );
|
204 |
} else {
|
205 |
+
delete_post_meta( $post_ID, '_tutor_product' );
|
206 |
}
|
207 |
}
|
208 |
|
210 |
*
|
211 |
* Take enrolled course action based on order status change
|
212 |
*/
|
213 |
+
public function enrolled_courses_status_change( $order_id, $status_from, $status_to ) {
|
214 |
+
if ( ! tutor_utils()->is_tutor_order( $order_id ) ) {
|
215 |
return;
|
216 |
}
|
217 |
global $wpdb;
|
218 |
|
219 |
+
$enrolled_ids_with_course = $this->get_course_enrolled_ids_by_order_id( $order_id );
|
220 |
|
221 |
+
if ( $enrolled_ids_with_course ) {
|
222 |
+
$enrolled_ids = wp_list_pluck( $enrolled_ids_with_course, 'enrolled_id' );
|
223 |
|
224 |
+
if ( is_array( $enrolled_ids ) && count( $enrolled_ids ) ) {
|
225 |
+
foreach ( $enrolled_ids as $enrolled_id ) {
|
226 |
|
227 |
+
tutils()->course_enrol_status_change( $enrolled_id, $status_to );
|
228 |
|
229 |
// Invoke enrolled hook
|
230 |
+
if ( $status_to == 'completed' ) {
|
231 |
+
$user_id = get_post_field( 'post_author', $enrolled_id );
|
232 |
+
$course_id = get_post_field( 'post_parent', $enrolled_id );
|
233 |
+
do_action( 'tutor_after_enrolled', $course_id, $user_id, $enrolled_id );
|
234 |
}
|
235 |
}
|
236 |
}
|
242 |
*
|
243 |
* @return array|bool
|
244 |
*/
|
245 |
+
public function get_course_enrolled_ids_by_order_id( $order_id ) {
|
246 |
global $wpdb;
|
247 |
+
// Getting all of courses ids within this order
|
248 |
|
249 |
+
$courses_ids = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key LIKE '_tutor_order_for_course_id_%' ", $order_id ) );
|
250 |
|
251 |
+
if ( is_array( $courses_ids ) && count( $courses_ids ) ) {
|
252 |
$course_enrolled_by_order = array();
|
253 |
+
foreach ( $courses_ids as $courses_id ) {
|
254 |
+
$course_id = str_replace( '_tutor_order_for_course_id_', '', $courses_id->meta_key );
|
255 |
+
// array(order_id => array('course_id' => $course_id, 'enrolled_id' => enrolled_id, 'order_id' => $courses_id->post_id))
|
256 |
+
$course_enrolled_by_order[] = array(
|
257 |
+
'course_id' => $course_id,
|
258 |
+
'enrolled_id' => $courses_id->meta_value,
|
259 |
+
'order_id' => $courses_id->post_id,
|
260 |
+
);
|
261 |
}
|
262 |
return $course_enrolled_by_order;
|
263 |
}
|
269 |
*
|
270 |
* TODO: right now it's unused
|
271 |
*/
|
272 |
+
public function remove_active_course( $order_id ) {
|
273 |
global $wpdb;
|
274 |
+
// Getting all of courses ids within this order
|
275 |
|
276 |
+
$courses_ids = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->postmeta} WHERE post_id = %d meta_key LIKE '_tutor_order_for_course_id_%' ", $order_id ) );
|
277 |
}
|
278 |
|
279 |
|
284 |
*
|
285 |
* Add option for WooCommerce settings
|
286 |
*/
|
287 |
+
public function add_options( $attr ) {
|
288 |
|
289 |
$attr['woocommerce'] = array(
|
290 |
+
'label' => __( 'WooCommerce', 'tutor' ),
|
291 |
|
292 |
+
'sections' => array(
|
293 |
'general' => array(
|
294 |
+
'label' => __( 'General', 'tutor' ),
|
295 |
+
'desc' => __( 'WooCommerce Settings', 'tutor' ),
|
296 |
'fields' => array(
|
297 |
+
/*
|
298 |
+
'enable_course_sell_by_woocommerce' => array(
|
299 |
'type' => 'checkbox',
|
300 |
'label' => __('Enable / Disable', 'tutor'),
|
301 |
'label_title' => __('Enable WooComerce to sell course', 'tutor'),
|
302 |
'desc' => __('By integrating WooCommerce, you can sell your course', 'tutor'),
|
303 |
),*/
|
304 |
'enable_guest_course_cart' => array(
|
305 |
+
'type' => 'checkbox',
|
306 |
+
'label' => __( 'Enable / Disable', 'tutor' ),
|
307 |
+
'label_title' => __( 'Enable add to cart feature for guest users', 'tutor' ),
|
308 |
+
'desc' => __( 'Enabling this will let an unregistered user purchase any course from the Course Details page. Head over to Documentation to know how to configure this setting.', 'tutor' ),
|
309 |
),
|
310 |
),
|
311 |
),
|
324 |
*
|
325 |
* @since v.1.3.5
|
326 |
*/
|
327 |
+
public function tutor_monetization_options( $arr ) {
|
328 |
$has_wc = tutils()->has_wc();
|
329 |
+
if ( $has_wc ) {
|
330 |
+
$arr['wc'] = __( 'WooCommerce', 'tutor' );
|
331 |
}
|
332 |
return $arr;
|
333 |
}
|
341 |
*
|
342 |
* @since v.1.1.2
|
343 |
*/
|
344 |
+
public function add_earning_data( $item_id, $item, $order_id ) {
|
345 |
global $wpdb;
|
346 |
+
$item = new \WC_Order_Item_Product( $item );
|
347 |
|
348 |
+
$product_id = $item->get_product_id();
|
349 |
+
$if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
|
350 |
|
351 |
+
if ( $if_has_course ) {
|
352 |
|
353 |
+
$enable_tutor_earning = tutor_utils()->get_option( 'enable_tutor_earning' );
|
354 |
+
if ( ! $enable_tutor_earning ) {
|
355 |
return;
|
356 |
}
|
357 |
|
358 |
+
$course_id = $if_has_course->post_id;
|
359 |
+
$user_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_author FROM {$wpdb->posts} WHERE ID = %d ", $course_id ) );
|
360 |
+
$order_status = $wpdb->get_var( $wpdb->prepare( "SELECT post_status from {$wpdb->posts} where ID = %d ", $order_id ) );
|
361 |
|
362 |
/**
|
363 |
* Return here if already added this product from this order
|
364 |
+
*
|
365 |
* @since v1.9.7
|
366 |
*/
|
367 |
+
$exist_count = (int) $wpdb->get_var(
|
368 |
+
$wpdb->prepare(
|
369 |
+
"SELECT COUNT(earning_id)
|
370 |
+
FROM {$wpdb->prefix}tutor_earnings
|
371 |
+
WHERE course_id=%d
|
372 |
+
AND order_id=%d
|
373 |
AND user_id=%d",
|
374 |
+
$course_id,
|
375 |
+
$order_id,
|
376 |
+
$user_id
|
377 |
+
)
|
378 |
+
);
|
379 |
|
380 |
+
if ( $exist_count > 0 ) {
|
381 |
return;
|
382 |
}
|
383 |
|
384 |
$total_price = $item->get_total();
|
385 |
|
386 |
+
$fees_deduct_data = array();
|
387 |
+
$tutor_earning_fees = tutor_utils()->get_option( 'tutor_earning_fees' );
|
388 |
+
$enable_fees_deducting = tutor_utils()->avalue_dot( 'enable_fees_deducting', $tutor_earning_fees );
|
389 |
|
390 |
$course_price_grand_total = $total_price;
|
391 |
|
392 |
+
if ( $enable_fees_deducting ) {
|
393 |
+
$fees_name = tutor_utils()->avalue_dot( 'fees_name', $tutor_earning_fees );
|
394 |
+
$fees_amount = (int) tutor_utils()->avalue_dot( 'fees_amount', $tutor_earning_fees );
|
395 |
+
$fees_type = tutor_utils()->avalue_dot( 'fees_type', $tutor_earning_fees );
|
396 |
|
397 |
+
if ( $fees_amount > 0 ) {
|
398 |
+
if ( $fees_type === 'percent' ) {
|
399 |
+
$fees_amount = ( $total_price * $fees_amount ) / 100;
|
400 |
}
|
401 |
|
402 |
/*
|
408 |
}
|
409 |
|
410 |
$fees_deduct_data = array(
|
411 |
+
'deduct_fees_amount' => $fees_amount,
|
412 |
+
'deduct_fees_name' => $fees_name,
|
413 |
+
'deduct_fees_type' => $fees_type,
|
414 |
);
|
415 |
}
|
416 |
|
417 |
+
$instructor_rate = tutor_utils()->get_option( 'earning_instructor_commission' );
|
418 |
+
$admin_rate = tutor_utils()->get_option( 'earning_admin_commission' );
|
419 |
|
420 |
$instructor_amount = 0;
|
421 |
+
if ( $instructor_rate > 0 ) {
|
422 |
+
$instructor_amount = ( $course_price_grand_total * $instructor_rate ) / 100;
|
423 |
}
|
424 |
|
425 |
$admin_amount = 0;
|
426 |
+
if ( $admin_rate > 0 ) {
|
427 |
+
$admin_amount = ( $course_price_grand_total * $admin_rate ) / 100;
|
428 |
}
|
429 |
|
430 |
$commission_type = 'percent';
|
432 |
// (Use Pro Filter - Start)
|
433 |
// The response must be same array structure.
|
434 |
// Do not change used variable names here, or change in both of here and pro plugin
|
435 |
+
$pro_arg = array(
|
436 |
+
'user_id' => $user_id,
|
437 |
+
'instructor_rate' => $instructor_rate,
|
438 |
+
'admin_rate' => $admin_rate,
|
439 |
+
'instructor_amount' => $instructor_amount,
|
440 |
+
'admin_amount' => $admin_amount,
|
441 |
+
'course_price_grand_total' => $course_price_grand_total,
|
442 |
+
'commission_type' => $commission_type,
|
443 |
+
);
|
444 |
+
$pro_calculation = apply_filters( 'tutor_pro_earning_calculator', $pro_arg );
|
445 |
+
extract( $pro_calculation );
|
446 |
+
// (Use Pro Filter - End)
|
447 |
|
448 |
$earning_data = array(
|
449 |
+
'user_id' => $user_id,
|
450 |
+
'course_id' => $course_id,
|
451 |
+
'order_id' => $order_id,
|
452 |
+
'order_status' => $order_status,
|
453 |
+
'course_price_total' => $total_price,
|
454 |
+
'course_price_grand_total' => $course_price_grand_total,
|
455 |
+
|
456 |
+
'instructor_amount' => $instructor_amount,
|
457 |
+
'instructor_rate' => $instructor_rate,
|
458 |
+
'admin_amount' => $admin_amount,
|
459 |
+
'admin_rate' => $admin_rate,
|
460 |
+
|
461 |
+
'commission_type' => $commission_type,
|
462 |
+
'process_by' => 'woocommerce',
|
463 |
+
'created_at' => date( 'Y-m-d H:i:s', tutor_time() ),
|
464 |
);
|
465 |
+
$earning_data = apply_filters( 'tutor_new_earning_data', array_merge( $earning_data, $fees_deduct_data ) );
|
466 |
|
467 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_earnings', $earning_data );
|
468 |
}
|
469 |
}
|
470 |
|
477 |
*
|
478 |
* @since v.1.1.2
|
479 |
*/
|
480 |
+
public function add_earning_data_status_change( $order_id, $status_from, $status_to ) {
|
481 |
+
if ( ! tutor_utils()->is_tutor_order( $order_id ) ) {
|
482 |
return;
|
483 |
}
|
484 |
global $wpdb;
|
485 |
|
486 |
+
$is_earning_data = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(earning_id) FROM {$wpdb->prefix}tutor_earnings WHERE order_id = %d ", $order_id ) );
|
487 |
+
if ( $is_earning_data ) {
|
488 |
+
$wpdb->update( $wpdb->prefix . 'tutor_earnings', array( 'order_status' => $status_to ), array( 'order_id' => $order_id ) );
|
489 |
}
|
490 |
}
|
491 |
|
492 |
/**
|
493 |
* Course placing order from admin
|
494 |
+
*
|
495 |
* @param $order_id
|
496 |
* @since v.1.6.7
|
497 |
*/
|
498 |
+
public function course_placing_order_from_admin( $order_id ) {
|
499 |
+
if ( ! is_admin() ) {
|
500 |
return;
|
501 |
}
|
502 |
+
|
503 |
$order = wc_get_order( $order_id );
|
504 |
+
foreach ( $order->get_items() as $item ) {
|
505 |
+
$product_id = $item->get_product_id();
|
506 |
+
$if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
|
507 |
+
if ( $if_has_course ) {
|
508 |
+
$course_id = $if_has_course->post_id;
|
509 |
$customer_id = $order->get_customer_id();
|
510 |
+
tutor_utils()->do_enroll( $course_id, $order_id, $customer_id );
|
511 |
}
|
512 |
}
|
513 |
}
|
518 |
* @param $order_id
|
519 |
* @since v.1.6.7
|
520 |
*/
|
521 |
+
public function course_placing_order_from_customer( $item_id, $item, $order_id ) {
|
522 |
+
if ( is_admin() ) {
|
523 |
return;
|
524 |
}
|
525 |
|
526 |
+
$item = new \WC_Order_Item_Product( $item );
|
527 |
+
$product_id = $item->get_product_id();
|
528 |
+
$if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
|
529 |
|
530 |
+
if ( $if_has_course ) {
|
531 |
$course_id = $if_has_course->post_id;
|
532 |
+
tutor_utils()->do_enroll( $course_id, $order_id );
|
533 |
}
|
534 |
}
|
535 |
|
536 |
/**
|
537 |
* Disable course monetization on woocommerce deactivation
|
538 |
+
*
|
539 |
* @since v.1.7.8
|
540 |
*/
|
541 |
public function disable_tutor_monetization() {
|
542 |
+
tutils()->update_option( 'monetize_by', 'free' );
|
543 |
+
update_option( 'tutor_show_woocommerce_notice', true );
|
544 |
}
|
545 |
|
546 |
/**
|
547 |
+
* Redirect student on enrolled courses after course
|
548 |
* enrollment complete if course is purchasable
|
549 |
+
*
|
550 |
* @param $order_id | int
|
551 |
* @since 1.9.0
|
552 |
+
*/
|
553 |
public function redirect_to_enrolled_courses( $order_id ) {
|
554 |
+
if ( ! tutils()->get_option( 'wc_automatic_order_complete_redirect_to_courses' ) ) {
|
555 |
+
// Since 1.9.1
|
556 |
+
return;
|
557 |
+
}
|
558 |
|
559 |
+
// get woo order details
|
560 |
+
$order = wc_get_order( $order_id );
|
561 |
+
$tutor_product = false;
|
562 |
+
$url = tutor_utils()->tutor_dashboard_url() . 'enrolled-courses/';
|
563 |
+
foreach ( $order->get_items() as $item ) {
|
564 |
+
$product_id = $item->get_product_id();
|
565 |
+
// check if product associated with tutor course
|
566 |
+
$if_has_course = tutor_utils()->product_belongs_with_course( $product_id );
|
567 |
+
if ( $if_has_course ) {
|
568 |
+
$tutor_product = true;
|
|
|
569 |
}
|
570 |
+
}
|
571 |
+
// if tutor product & order status completed
|
572 |
+
if ( $order->has_status( 'completed' ) && $tutor_product ) {
|
573 |
+
wp_safe_redirect( $url );
|
574 |
+
exit;
|
575 |
+
}
|
576 |
}
|
577 |
|
578 |
/**
|
579 |
* Change product url on cart page if product is tutor course
|
580 |
+
*
|
581 |
* @since 1.9.8
|
582 |
*/
|
583 |
function tutor_update_product_url( $permalink, $cart_item ) {
|
584 |
|
585 |
+
$woo_product_id = $cart_item['product_id'];
|
586 |
+
$product_meta = get_post_meta( $woo_product_id );
|
587 |
|
588 |
+
if ( isset( $product_meta['_tutor_product'] ) && $product_meta['_tutor_product'][0] ) {
|
589 |
|
590 |
+
global $wpdb;
|
591 |
+
$table = $wpdb->base_prefix . 'postmeta';
|
592 |
+
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$table} WHERE meta_key = '_tutor_course_product_id' AND meta_value = %d ", $woo_product_id ) );
|
593 |
|
594 |
+
if ( $post_id ) {
|
595 |
+
$data = get_post_permalink( $post_id );
|
596 |
+
return $data;
|
597 |
}
|
598 |
}
|
599 |
}
|
600 |
}
|
601 |
|
602 |
|
603 |
+
add_action(
|
604 |
+
'admin_notices',
|
605 |
+
function() {
|
606 |
|
607 |
+
$show = get_option( 'tutor_show_woocommerce_notice' ) && tutils()->get_option( 'monetize_by', 'free' ) == 'free';
|
608 |
|
609 |
+
if ( $show ) {
|
610 |
+
$message = __( 'Since WooCommerce is disabled, your monetized courses have been set to free. Please make sure to enable Tutor LMS monetization if you decide to re-enable WooCommerce.', 'tutor' );
|
611 |
+
echo '<div class="notice notice-error"><p>' . $message . '</p></div>';
|
612 |
+
}
|
613 |
}
|
614 |
+
);
|
includes/tinymce_translate.php
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Add translation support for external tinyMCE button
|
4 |
-
*
|
5 |
* Containing all translate able strings
|
6 |
-
*
|
7 |
* @since 1.9.7
|
8 |
*/
|
9 |
if ( ! defined( 'ABSPATH' ) )
|
@@ -33,4 +33,5 @@ function tutor_tinymce_plugin_translation() {
|
|
33 |
return $translated;
|
34 |
}
|
35 |
|
36 |
-
$strings = tutor_tinymce_plugin_translation();
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Add translation support for external tinyMCE button
|
4 |
+
*
|
5 |
* Containing all translate able strings
|
6 |
+
*
|
7 |
* @since 1.9.7
|
8 |
*/
|
9 |
if ( ! defined( 'ABSPATH' ) )
|
33 |
return $translated;
|
34 |
}
|
35 |
|
36 |
+
$strings = tutor_tinymce_plugin_translation();
|
37 |
+
|
includes/tutor-general-functions.php
CHANGED
@@ -1,12 +1,71 @@
|
|
1 |
<?php
|
2 |
-
if (!defined('ABSPATH'))
|
3 |
exit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
/**
|
6 |
* Tutor general Functions
|
7 |
*/
|
8 |
|
9 |
-
if (!function_exists('tutor_withdrawal_methods')) {
|
10 |
function tutor_withdrawal_methods() {
|
11 |
$withdraw = new \TUTOR\Withdraw();
|
12 |
|
@@ -22,7 +81,7 @@ if (!function_exists('tutor_withdrawal_methods')) {
|
|
22 |
* @since v.1.5.7
|
23 |
*/
|
24 |
|
25 |
-
if (!function_exists('get_tutor_all_withdrawal_methods')) {
|
26 |
function get_tutor_all_withdrawal_methods() {
|
27 |
$withdraw = new \TUTOR\Withdraw();
|
28 |
|
@@ -30,10 +89,10 @@ if (!function_exists('get_tutor_all_withdrawal_methods')) {
|
|
30 |
}
|
31 |
}
|
32 |
|
33 |
-
if (!function_exists('tutor_placeholder_img_src')) {
|
34 |
function tutor_placeholder_img_src() {
|
35 |
$src = tutor()->url . 'assets/images/placeholder.jpg';
|
36 |
-
return apply_filters('tutor_placeholder_img_src', $src);
|
37 |
}
|
38 |
}
|
39 |
|
@@ -45,38 +104,38 @@ if (!function_exists('tutor_placeholder_img_src')) {
|
|
45 |
* @since v.1.3.4
|
46 |
*/
|
47 |
|
48 |
-
if (!function_exists('tutor_course_categories_dropdown')) {
|
49 |
-
function tutor_course_categories_dropdown($post_ID = 0, $args = array()) {
|
50 |
|
51 |
$default = array(
|
52 |
'classes' => '',
|
53 |
-
'name'
|
54 |
'multiple' => true,
|
55 |
);
|
56 |
|
57 |
-
$args = apply_filters('tutor_course_categories_dropdown_args', array_merge($default, $args));
|
58 |
|
59 |
$multiple_select = '';
|
60 |
|
61 |
-
if (tutor_utils()->array_get('multiple', $args)) {
|
62 |
-
if (isset($args['name'])) {
|
63 |
$args['name'] = $args['name'] . '[]';
|
64 |
}
|
65 |
$multiple_select = "multiple='multiple'";
|
66 |
}
|
67 |
|
68 |
-
extract($args);
|
69 |
|
70 |
$classes = (array) $classes;
|
71 |
-
$classes = implode(' ', $classes);
|
72 |
|
73 |
$categories = tutor_utils()->get_course_categories();
|
74 |
|
75 |
-
$output
|
76 |
-
$output .=
|
77 |
-
$output .=
|
78 |
-
$output .= _generate_categories_dropdown_option($post_ID, $categories, $args);
|
79 |
-
$output .=
|
80 |
|
81 |
return $output;
|
82 |
}
|
@@ -90,38 +149,38 @@ if (!function_exists('tutor_course_categories_dropdown')) {
|
|
90 |
* @since v.1.3.4
|
91 |
*/
|
92 |
|
93 |
-
if (!function_exists('tutor_course_tags_dropdown')) {
|
94 |
-
function tutor_course_tags_dropdown($post_ID = 0, $args = array()) {
|
95 |
|
96 |
$default = array(
|
97 |
'classes' => '',
|
98 |
-
'name'
|
99 |
'multiple' => true,
|
100 |
);
|
101 |
|
102 |
-
$args = apply_filters('tutor_course_tags_dropdown_args', array_merge($default, $args));
|
103 |
|
104 |
$multiple_select = '';
|
105 |
|
106 |
-
if (tutor_utils()->array_get('multiple', $args)) {
|
107 |
-
if (isset($args['name'])) {
|
108 |
$args['name'] = $args['name'] . '[]';
|
109 |
}
|
110 |
$multiple_select = "multiple='multiple'";
|
111 |
}
|
112 |
|
113 |
-
extract($args);
|
114 |
|
115 |
$classes = (array) $classes;
|
116 |
-
$classes = implode(' ', $classes);
|
117 |
|
118 |
$tags = tutor_utils()->get_course_tags();
|
119 |
|
120 |
-
$output
|
121 |
-
$output .=
|
122 |
-
$output .=
|
123 |
-
$output .= _generate_tags_dropdown_option($post_ID, $tags, $args);
|
124 |
-
$output .=
|
125 |
|
126 |
return $output;
|
127 |
}
|
@@ -138,32 +197,38 @@ if (!function_exists('tutor_course_tags_dropdown')) {
|
|
138 |
* @since v.1.3.4
|
139 |
*/
|
140 |
|
141 |
-
if (!function_exists('_generate_categories_dropdown_option')) {
|
142 |
-
function _generate_categories_dropdown_option($post_ID = 0, $categories = array(), $args = array(), $depth = 0) {
|
143 |
$output = '';
|
144 |
|
145 |
-
if (!tutor_utils()->count($categories))
|
|
|
|
|
146 |
|
147 |
-
if (!is_numeric($post_ID) || $post_ID < 1)
|
|
|
|
|
148 |
|
149 |
-
foreach ($categories as $category_id => $category) {
|
150 |
-
if (
|
|
|
|
|
151 |
|
152 |
-
$childrens
|
153 |
-
$has_in_term = has_term($category->term_id, 'course-category', $post_ID);
|
154 |
|
155 |
$depth_seperator = '';
|
156 |
-
if ($depth) {
|
157 |
-
for ($depth_i = 0; $depth_i < $depth; $depth_i++) {
|
158 |
$depth_seperator .= '-';
|
159 |
}
|
160 |
}
|
161 |
|
162 |
-
$output .=
|
163 |
|
164 |
-
if (tutor_utils()->count($childrens)) {
|
165 |
$depth++;
|
166 |
-
$output .= _generate_categories_dropdown_option($post_ID, $childrens, $args, $depth);
|
167 |
}
|
168 |
}
|
169 |
|
@@ -181,19 +246,23 @@ if (!function_exists('_generate_categories_dropdown_option')) {
|
|
181 |
* @since v.1.3.4
|
182 |
*/
|
183 |
|
184 |
-
if (!function_exists('_generate_tags_dropdown_option')) {
|
185 |
-
function _generate_tags_dropdown_option($post_ID = 0, $tags = array(), $args = array(), $depth = 0) {
|
186 |
$output = '';
|
187 |
|
188 |
-
if (!tutor_utils()->count($tags))
|
|
|
|
|
189 |
|
190 |
-
if (!is_numeric($post_ID) || $post_ID < 1)
|
|
|
|
|
191 |
|
192 |
-
foreach ($tags as $tag) {
|
193 |
|
194 |
-
$has_in_term = has_term($tag->term_id, 'course-tag', $post_ID);
|
195 |
|
196 |
-
$output .=
|
197 |
|
198 |
}
|
199 |
|
@@ -207,26 +276,26 @@ if (!function_exists('_generate_tags_dropdown_option')) {
|
|
207 |
* @return string
|
208 |
*
|
209 |
* Generate course categories checkbox
|
210 |
-
* @since
|
211 |
*/
|
212 |
|
213 |
-
if (!function_exists('tutor_course_categories_checkbox')) {
|
214 |
-
function tutor_course_categories_checkbox($post_ID = 0, $args = array()) {
|
215 |
$default = array(
|
216 |
-
'name'
|
217 |
);
|
218 |
|
219 |
-
$args = apply_filters('tutor_course_categories_checkbox_args', array_merge($default, $args));
|
220 |
|
221 |
-
if (isset($args['name'])) {
|
222 |
$args['name'] = $args['name'] . '[]';
|
223 |
}
|
224 |
|
225 |
-
extract($args);
|
226 |
|
227 |
$categories = tutor_utils()->get_course_categories();
|
228 |
-
$output
|
229 |
-
$output
|
230 |
|
231 |
return $output;
|
232 |
}
|
@@ -238,26 +307,26 @@ if (!function_exists('tutor_course_categories_checkbox')) {
|
|
238 |
* @return string
|
239 |
*
|
240 |
* Generate course tags checkbox
|
241 |
-
* @since
|
242 |
*/
|
243 |
|
244 |
-
if (!function_exists('tutor_course_tags_checkbox')) {
|
245 |
-
function tutor_course_tags_checkbox($post_ID = 0, $args = array()) {
|
246 |
$default = array(
|
247 |
-
'name'
|
248 |
);
|
249 |
|
250 |
-
$args = apply_filters('tutor_course_tags_checkbox_args', array_merge($default, $args));
|
251 |
|
252 |
-
if (isset($args['name'])) {
|
253 |
$args['name'] = $args['name'] . '[]';
|
254 |
}
|
255 |
|
256 |
-
extract($args);
|
257 |
|
258 |
-
$tags
|
259 |
-
$output
|
260 |
-
$output .= __tutor_generate_tags_checkbox($post_ID, $tags, $args);
|
261 |
|
262 |
return $output;
|
263 |
}
|
@@ -274,28 +343,28 @@ if (!function_exists('tutor_course_tags_checkbox')) {
|
|
274 |
*
|
275 |
* @since v.1.3.4
|
276 |
*/
|
277 |
-
if ( ! function_exists('__tutor_generate_categories_checkbox')){
|
278 |
-
function __tutor_generate_categories_checkbox($post_ID = 0, $categories=array(), $args = array()){
|
279 |
-
|
280 |
-
$output = '';
|
281 |
-
$input_name = tutor_utils()->array_get('name', $args);
|
282 |
|
283 |
-
|
284 |
-
|
285 |
-
foreach ($categories as $category_id => $category) {
|
286 |
-
$childrens = tutor_utils()->array_get('children', $category);
|
287 |
-
$has_in_term = has_term($category->term_id, 'course-category', $post_ID);
|
288 |
|
289 |
-
|
|
|
|
|
|
|
|
|
290 |
|
291 |
-
|
292 |
-
|
|
|
|
|
293 |
}
|
294 |
-
$output .=
|
295 |
}
|
296 |
-
$output .=
|
297 |
}
|
298 |
-
|
299 |
return $output;
|
300 |
|
301 |
}
|
@@ -311,22 +380,22 @@ if ( ! function_exists('__tutor_generate_categories_checkbox')){
|
|
311 |
*
|
312 |
* @since v.1.3.4
|
313 |
*/
|
314 |
-
if (!function_exists('__tutor_generate_tags_checkbox')) {
|
315 |
-
function __tutor_generate_tags_checkbox($post_ID = 0, $tags = array(), $args = array()) {
|
316 |
|
317 |
-
$output
|
318 |
-
$input_name = tutor_utils()->array_get('name', $args);
|
319 |
|
320 |
-
if (tutor_utils()->count($tags)) {
|
321 |
-
$output .=
|
322 |
-
foreach ($tags as $tag) {
|
323 |
-
$has_in_term = has_term($tag->term_id, 'course-tag', $post_ID);
|
324 |
|
325 |
-
$output .=
|
326 |
|
327 |
-
$output .=
|
328 |
}
|
329 |
-
$output .=
|
330 |
}
|
331 |
|
332 |
return $output;
|
@@ -344,23 +413,23 @@ if (!function_exists('__tutor_generate_tags_checkbox')) {
|
|
344 |
* @since v.1.3.4
|
345 |
*/
|
346 |
|
347 |
-
if (!function_exists('course_builder_section_wrap')) {
|
348 |
-
function course_builder_section_wrap($content = '', $title = '', $echo = true) {
|
349 |
ob_start();
|
350 |
-
?>
|
351 |
<div class="tutor-course-builder-section">
|
352 |
<div class="tutor-course-builder-section-title">
|
353 |
<h3><i class="tutor-icon-down"></i> <span><?php echo $title; ?></span></h3>
|
354 |
</div>
|
355 |
<div class="tutor-course-builder-section-content">
|
356 |
-
<?php echo $content; ?>
|
357 |
</div>
|
358 |
</div>
|
359 |
<?php
|
360 |
$html = ob_get_clean();
|
361 |
|
362 |
-
if ($echo) {
|
363 |
-
echo $html;
|
364 |
} else {
|
365 |
return $html;
|
366 |
}
|
@@ -368,48 +437,48 @@ if (!function_exists('course_builder_section_wrap')) {
|
|
368 |
}
|
369 |
|
370 |
|
371 |
-
if (!function_exists('get_tutor_header')) {
|
372 |
-
function get_tutor_header($fullScreen = false) {
|
373 |
-
$enable_spotlight_mode = tutor_utils()->get_option('enable_spotlight_mode');
|
374 |
|
375 |
-
if ($enable_spotlight_mode || $fullScreen) {
|
376 |
-
|
377 |
<!doctype html>
|
378 |
<html <?php language_attributes(); ?>>
|
379 |
|
380 |
<head>
|
381 |
-
<meta charset="<?php bloginfo('charset'); ?>" />
|
382 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
383 |
<link rel="profile" href="https://gmpg.org/xfn/11" />
|
384 |
-
|
385 |
</head>
|
386 |
|
387 |
<body <?php body_class(); ?>>
|
388 |
<div id="tutor-page-wrap" class="tutor-site-wrap site">
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
}
|
393 |
}
|
394 |
}
|
|
|
395 |
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
</div>
|
402 |
-
|
403 |
|
404 |
</body>
|
405 |
|
406 |
</html>
|
407 |
-
<?php
|
408 |
-
|
409 |
-
|
410 |
-
}
|
411 |
}
|
412 |
}
|
|
|
413 |
|
414 |
/**
|
415 |
* @param null $key
|
@@ -421,11 +490,11 @@ if (!function_exists('get_tutor_header')) {
|
|
421 |
*
|
422 |
* @since v.1.3.6
|
423 |
*/
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
}
|
428 |
}
|
|
|
429 |
|
430 |
/**
|
431 |
* @param null $key
|
@@ -435,11 +504,11 @@ if (!function_exists('get_tutor_header')) {
|
|
435 |
*
|
436 |
* @since v.1.3.6
|
437 |
*/
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
}
|
442 |
}
|
|
|
443 |
/**
|
444 |
* @param int $course_id
|
445 |
* @param null $key
|
@@ -451,11 +520,11 @@ if (!function_exists('get_tutor_header')) {
|
|
451 |
*
|
452 |
* @since v.1.4.1
|
453 |
*/
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
}
|
458 |
}
|
|
|
459 |
|
460 |
/**
|
461 |
* @param int $lesson_id
|
@@ -467,11 +536,11 @@ if (!function_exists('get_tutor_header')) {
|
|
467 |
* Get lesson content drip settings
|
468 |
*/
|
469 |
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
}
|
474 |
}
|
|
|
475 |
|
476 |
/**
|
477 |
* @param null $msg
|
@@ -484,38 +553,39 @@ if (!function_exists('get_tutor_header')) {
|
|
484 |
*
|
485 |
* @since v.1.4.1
|
486 |
*/
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
}
|
496 |
-
if (!$msg) {
|
497 |
-
$type = 'danger';
|
498 |
-
$msg = tutor_flash_get($type);
|
499 |
-
}
|
500 |
-
if (!$msg) {
|
501 |
-
$type = 'success';
|
502 |
-
$msg = tutor_flash_get($type);
|
503 |
-
}
|
504 |
-
} else {
|
505 |
-
$msg = tutor_flash_get($type);
|
506 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
}
|
508 |
-
|
509 |
-
|
510 |
-
|
|
|
511 |
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
return $html;
|
517 |
}
|
|
|
518 |
}
|
|
|
519 |
|
520 |
|
521 |
/**
|
@@ -526,11 +596,11 @@ if (!function_exists('get_tutor_header')) {
|
|
526 |
* @since v.1.4.2
|
527 |
*/
|
528 |
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
}
|
533 |
}
|
|
|
534 |
|
535 |
/**
|
536 |
* @param null $key
|
@@ -539,18 +609,18 @@ if (!function_exists('get_tutor_header')) {
|
|
539 |
* Set Flash Message
|
540 |
*/
|
541 |
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
}
|
551 |
-
$_SESSION[$key] = $message;
|
552 |
}
|
|
|
553 |
}
|
|
|
554 |
|
555 |
/**
|
556 |
* @param null $key
|
@@ -562,42 +632,42 @@ if (!function_exists('get_tutor_header')) {
|
|
562 |
* Get flash message
|
563 |
*/
|
564 |
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
}
|
575 |
-
$message = tutils()->array_get($key, $_SESSION);
|
576 |
-
if ($message) {
|
577 |
-
unset($_SESSION[$key]);
|
578 |
-
}
|
579 |
-
return $message;
|
580 |
}
|
581 |
-
|
|
|
|
|
|
|
|
|
582 |
}
|
|
|
583 |
}
|
|
|
584 |
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
}
|
597 |
-
wp_safe_redirect($url);
|
598 |
-
exit();
|
599 |
}
|
|
|
|
|
600 |
}
|
|
|
601 |
|
602 |
/**
|
603 |
* @param string $action
|
@@ -608,35 +678,35 @@ if (!function_exists('get_tutor_header')) {
|
|
608 |
* @since v.1.4.3
|
609 |
*/
|
610 |
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
}
|
623 |
}
|
624 |
}
|
|
|
625 |
|
626 |
/**
|
627 |
* @return int|string
|
628 |
*
|
629 |
-
* Return current Time from
|
630 |
*
|
631 |
* @since v.1.4.3
|
632 |
*/
|
633 |
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
}
|
639 |
}
|
|
|
640 |
|
641 |
/**
|
642 |
* Toggle maintenance mode for the site.
|
@@ -649,23 +719,23 @@ if (!function_exists('get_tutor_header')) {
|
|
649 |
*
|
650 |
* @param bool $enable True to enable maintenance mode, false to disable.
|
651 |
*/
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
}
|
666 |
}
|
667 |
}
|
668 |
}
|
|
|
669 |
|
670 |
/**
|
671 |
* @return bool
|
@@ -675,41 +745,41 @@ if (!function_exists('get_tutor_header')) {
|
|
675 |
* @since v.1.6.0
|
676 |
*/
|
677 |
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
|
683 |
-
|
684 |
-
|
685 |
-
}
|
686 |
-
return false;
|
687 |
}
|
|
|
688 |
}
|
|
|
689 |
|
690 |
/**
|
691 |
-
* Require wp_date form return js date format
|
692 |
-
*
|
693 |
* this is helpfull for date picker
|
694 |
-
*
|
695 |
* @return string
|
696 |
-
*
|
697 |
* @since 1.9.7
|
698 |
*/
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
}
|
712 |
}
|
|
|
713 |
|
714 |
/**
|
715 |
* Convert date to desire format
|
@@ -720,10 +790,10 @@ if (!function_exists('get_tutor_header')) {
|
|
720 |
*
|
721 |
* @return string ( date )
|
722 |
*/
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
}
|
727 |
}
|
|
|
|
|
728 |
|
729 |
-
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
+
}
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Tutor input sanitization
|
8 |
+
*/
|
9 |
+
|
10 |
+
if ( ! function_exists( 'tutor_sanitize_data' ) ) {
|
11 |
+
/**
|
12 |
+
* Escaping for Sanitize data.
|
13 |
+
*
|
14 |
+
* @since 1.9.13
|
15 |
+
*
|
16 |
+
* @param string $input.
|
17 |
+
* @param string $type.
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
function tutor_sanitize_data( $input = null, $type = null ) {
|
21 |
+
$array = array();
|
22 |
+
$object = new stdClass();
|
23 |
+
|
24 |
+
if ( is_string( $input ) ) {
|
25 |
+
|
26 |
+
if ( 'textarea' == $type ) {
|
27 |
+
$input = sanitize_textarea_field( $input );
|
28 |
+
} elseif ( 'kses' == $type ) {
|
29 |
+
$input = wp_kses_post( $input );
|
30 |
+
} else {
|
31 |
+
$input = sanitize_text_field( $input );
|
32 |
+
}
|
33 |
+
|
34 |
+
return $input;
|
35 |
+
|
36 |
+
} elseif ( is_object( $input ) && count( get_object_vars( $input ) ) ) {
|
37 |
+
|
38 |
+
foreach ( $input as $key => $value ) {
|
39 |
+
if ( is_object( $value ) ) {
|
40 |
+
$object->$key = tutor_sanitize_data( $value );
|
41 |
+
} else {
|
42 |
+
$key = sanitize_text_field( $key );
|
43 |
+
$value = sanitize_text_field( $value );
|
44 |
+
$object->$key = $value;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
return $object;
|
48 |
+
} elseif ( is_array( $input ) && count( $input ) ) {
|
49 |
+
foreach ( $input as $key => $value ) {
|
50 |
+
if ( is_array( $value ) ) {
|
51 |
+
$array[ $key ] = tutor_sanitize_data( $value );
|
52 |
+
} else {
|
53 |
+
$key = sanitize_text_field( $key );
|
54 |
+
$value = sanitize_text_field( $value );
|
55 |
+
$array[ $key ] = $value;
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
return $array;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
|
64 |
/**
|
65 |
* Tutor general Functions
|
66 |
*/
|
67 |
|
68 |
+
if ( ! function_exists( 'tutor_withdrawal_methods' ) ) {
|
69 |
function tutor_withdrawal_methods() {
|
70 |
$withdraw = new \TUTOR\Withdraw();
|
71 |
|
81 |
* @since v.1.5.7
|
82 |
*/
|
83 |
|
84 |
+
if ( ! function_exists( 'get_tutor_all_withdrawal_methods' ) ) {
|
85 |
function get_tutor_all_withdrawal_methods() {
|
86 |
$withdraw = new \TUTOR\Withdraw();
|
87 |
|
89 |
}
|
90 |
}
|
91 |
|
92 |
+
if ( ! function_exists( 'tutor_placeholder_img_src' ) ) {
|
93 |
function tutor_placeholder_img_src() {
|
94 |
$src = tutor()->url . 'assets/images/placeholder.jpg';
|
95 |
+
return apply_filters( 'tutor_placeholder_img_src', $src );
|
96 |
}
|
97 |
}
|
98 |
|
104 |
* @since v.1.3.4
|
105 |
*/
|
106 |
|
107 |
+
if ( ! function_exists( 'tutor_course_categories_dropdown' ) ) {
|
108 |
+
function tutor_course_categories_dropdown( $post_ID = 0, $args = array() ) {
|
109 |
|
110 |
$default = array(
|
111 |
'classes' => '',
|
112 |
+
'name' => 'tax_input[course-category]',
|
113 |
'multiple' => true,
|
114 |
);
|
115 |
|
116 |
+
$args = apply_filters( 'tutor_course_categories_dropdown_args', array_merge( $default, $args ) );
|
117 |
|
118 |
$multiple_select = '';
|
119 |
|
120 |
+
if ( tutor_utils()->array_get( 'multiple', $args ) ) {
|
121 |
+
if ( isset( $args['name'] ) ) {
|
122 |
$args['name'] = $args['name'] . '[]';
|
123 |
}
|
124 |
$multiple_select = "multiple='multiple'";
|
125 |
}
|
126 |
|
127 |
+
extract( $args );
|
128 |
|
129 |
$classes = (array) $classes;
|
130 |
+
$classes = implode( ' ', $classes );
|
131 |
|
132 |
$categories = tutor_utils()->get_course_categories();
|
133 |
|
134 |
+
$output = '';
|
135 |
+
$output .= '<select name="' . $name . '" ' . $multiple_select . ' class="' . $classes . '" data-placeholder="' . __( 'Search Course Category. ex. Design, Development, Business', 'tutor' ) . '">';
|
136 |
+
$output .= '<option value="">' . __( 'Select a category', 'tutor' ) . '</option>';
|
137 |
+
$output .= _generate_categories_dropdown_option( $post_ID, $categories, $args );
|
138 |
+
$output .= '</select>';
|
139 |
|
140 |
return $output;
|
141 |
}
|
149 |
* @since v.1.3.4
|
150 |
*/
|
151 |
|
152 |
+
if ( ! function_exists( 'tutor_course_tags_dropdown' ) ) {
|
153 |
+
function tutor_course_tags_dropdown( $post_ID = 0, $args = array() ) {
|
154 |
|
155 |
$default = array(
|
156 |
'classes' => '',
|
157 |
+
'name' => 'tax_input[course-tag]',
|
158 |
'multiple' => true,
|
159 |
);
|
160 |
|
161 |
+
$args = apply_filters( 'tutor_course_tags_dropdown_args', array_merge( $default, $args ) );
|
162 |
|
163 |
$multiple_select = '';
|
164 |
|
165 |
+
if ( tutor_utils()->array_get( 'multiple', $args ) ) {
|
166 |
+
if ( isset( $args['name'] ) ) {
|
167 |
$args['name'] = $args['name'] . '[]';
|
168 |
}
|
169 |
$multiple_select = "multiple='multiple'";
|
170 |
}
|
171 |
|
172 |
+
extract( $args );
|
173 |
|
174 |
$classes = (array) $classes;
|
175 |
+
$classes = implode( ' ', $classes );
|
176 |
|
177 |
$tags = tutor_utils()->get_course_tags();
|
178 |
|
179 |
+
$output = '';
|
180 |
+
$output .= '<select name=' . $name . ' ' . $multiple_select . ' class="' . $classes . '" data-placeholder="' . __( 'Search Course Tags. ex. Design, Development, Business', 'tutor' ) . '">';
|
181 |
+
$output .= '<option value="">' . __( 'Select a tag', 'tutor' ) . '</option>';
|
182 |
+
$output .= _generate_tags_dropdown_option( $post_ID, $tags, $args );
|
183 |
+
$output .= '</select>';
|
184 |
|
185 |
return $output;
|
186 |
}
|
197 |
* @since v.1.3.4
|
198 |
*/
|
199 |
|
200 |
+
if ( ! function_exists( '_generate_categories_dropdown_option' ) ) {
|
201 |
+
function _generate_categories_dropdown_option( $post_ID = 0, $categories = array(), $args = array(), $depth = 0 ) {
|
202 |
$output = '';
|
203 |
|
204 |
+
if ( ! tutor_utils()->count( $categories ) ) {
|
205 |
+
return $output;
|
206 |
+
}
|
207 |
|
208 |
+
if ( ! is_numeric( $post_ID ) || $post_ID < 1 ) {
|
209 |
+
return $output;
|
210 |
+
}
|
211 |
|
212 |
+
foreach ( $categories as $category_id => $category ) {
|
213 |
+
if ( ! $category->parent ) {
|
214 |
+
$depth = 0;
|
215 |
+
}
|
216 |
|
217 |
+
$childrens = tutor_utils()->array_get( 'children', $category );
|
218 |
+
$has_in_term = has_term( $category->term_id, 'course-category', $post_ID );
|
219 |
|
220 |
$depth_seperator = '';
|
221 |
+
if ( $depth ) {
|
222 |
+
for ( $depth_i = 0; $depth_i < $depth; $depth_i++ ) {
|
223 |
$depth_seperator .= '-';
|
224 |
}
|
225 |
}
|
226 |
|
227 |
+
$output .= '<option value="' . $category->term_id . '" ' . selected( $has_in_term, true, false ) . '> ' . $depth_seperator . ' ' . $category->name . '</option>';
|
228 |
|
229 |
+
if ( tutor_utils()->count( $childrens ) ) {
|
230 |
$depth++;
|
231 |
+
$output .= _generate_categories_dropdown_option( $post_ID, $childrens, $args, $depth );
|
232 |
}
|
233 |
}
|
234 |
|
246 |
* @since v.1.3.4
|
247 |
*/
|
248 |
|
249 |
+
if ( ! function_exists( '_generate_tags_dropdown_option' ) ) {
|
250 |
+
function _generate_tags_dropdown_option( $post_ID = 0, $tags = array(), $args = array(), $depth = 0 ) {
|
251 |
$output = '';
|
252 |
|
253 |
+
if ( ! tutor_utils()->count( $tags ) ) {
|
254 |
+
return $output;
|
255 |
+
}
|
256 |
|
257 |
+
if ( ! is_numeric( $post_ID ) || $post_ID < 1 ) {
|
258 |
+
return $output;
|
259 |
+
}
|
260 |
|
261 |
+
foreach ( $tags as $tag ) {
|
262 |
|
263 |
+
$has_in_term = has_term( $tag->term_id, 'course-tag', $post_ID );
|
264 |
|
265 |
+
$output .= '<option value="' . $tag->name . '" ' . selected( $has_in_term, true, false ) . '>' . $tag->name . '</option>';
|
266 |
|
267 |
}
|
268 |
|
276 |
* @return string
|
277 |
*
|
278 |
* Generate course categories checkbox
|
279 |
+
* @since v.1.3.4
|
280 |
*/
|
281 |
|
282 |
+
if ( ! function_exists( 'tutor_course_categories_checkbox' ) ) {
|
283 |
+
function tutor_course_categories_checkbox( $post_ID = 0, $args = array() ) {
|
284 |
$default = array(
|
285 |
+
'name' => 'tax_input[course-category]',
|
286 |
);
|
287 |
|
288 |
+
$args = apply_filters( 'tutor_course_categories_checkbox_args', array_merge( $default, $args ) );
|
289 |
|
290 |
+
if ( isset( $args['name'] ) ) {
|
291 |
$args['name'] = $args['name'] . '[]';
|
292 |
}
|
293 |
|
294 |
+
extract( $args );
|
295 |
|
296 |
$categories = tutor_utils()->get_course_categories();
|
297 |
+
$output = '';
|
298 |
+
$output .= __tutor_generate_categories_checkbox( $post_ID, $categories, $args );
|
299 |
|
300 |
return $output;
|
301 |
}
|
307 |
* @return string
|
308 |
*
|
309 |
* Generate course tags checkbox
|
310 |
+
* @since v.1.3.4
|
311 |
*/
|
312 |
|
313 |
+
if ( ! function_exists( 'tutor_course_tags_checkbox' ) ) {
|
314 |
+
function tutor_course_tags_checkbox( $post_ID = 0, $args = array() ) {
|
315 |
$default = array(
|
316 |
+
'name' => 'tax_input[course-tag]',
|
317 |
);
|
318 |
|
319 |
+
$args = apply_filters( 'tutor_course_tags_checkbox_args', array_merge( $default, $args ) );
|
320 |
|
321 |
+
if ( isset( $args['name'] ) ) {
|
322 |
$args['name'] = $args['name'] . '[]';
|
323 |
}
|
324 |
|
325 |
+
extract( $args );
|
326 |
|
327 |
+
$tags = tutor_utils()->get_course_tags();
|
328 |
+
$output = '';
|
329 |
+
$output .= __tutor_generate_tags_checkbox( $post_ID, $tags, $args );
|
330 |
|
331 |
return $output;
|
332 |
}
|
343 |
*
|
344 |
* @since v.1.3.4
|
345 |
*/
|
346 |
+
if ( ! function_exists( '__tutor_generate_categories_checkbox' ) ) {
|
347 |
+
function __tutor_generate_categories_checkbox( $post_ID = 0, $categories = array(), $args = array() ) {
|
|
|
|
|
|
|
348 |
|
349 |
+
$output = '';
|
350 |
+
$input_name = tutor_utils()->array_get( 'name', $args );
|
|
|
|
|
|
|
351 |
|
352 |
+
if ( tutor_utils()->count( $categories ) ) {
|
353 |
+
$output .= '<ul class="tax-input-course-category">';
|
354 |
+
foreach ( $categories as $category_id => $category ) {
|
355 |
+
$childrens = tutor_utils()->array_get( 'children', $category );
|
356 |
+
$has_in_term = has_term( $category->term_id, 'course-category', $post_ID );
|
357 |
|
358 |
+
$output .= '<li class="tax-input-course-category-item tax-input-course-category-item-' . $category->term_id . '"><label class="course-category-checkbox"> <input type="checkbox" name="' . $input_name . '" value="' . $category->term_id . '" ' . checked( $has_in_term, true, false ) . '/> <span>' . $category->name . '</span> </label>';
|
359 |
+
|
360 |
+
if ( tutor_utils()->count( $childrens ) ) {
|
361 |
+
$output .= __tutor_generate_categories_checkbox( $post_ID, $childrens, $args );
|
362 |
}
|
363 |
+
$output .= ' </li>';
|
364 |
}
|
365 |
+
$output .= '</ul>';
|
366 |
}
|
367 |
+
|
368 |
return $output;
|
369 |
|
370 |
}
|
380 |
*
|
381 |
* @since v.1.3.4
|
382 |
*/
|
383 |
+
if ( ! function_exists( '__tutor_generate_tags_checkbox' ) ) {
|
384 |
+
function __tutor_generate_tags_checkbox( $post_ID = 0, $tags = array(), $args = array() ) {
|
385 |
|
386 |
+
$output = '';
|
387 |
+
$input_name = tutor_utils()->array_get( 'name', $args );
|
388 |
|
389 |
+
if ( tutor_utils()->count( $tags ) ) {
|
390 |
+
$output .= '<ul class="tax-input-course-tag">';
|
391 |
+
foreach ( $tags as $tag ) {
|
392 |
+
$has_in_term = has_term( $tag->term_id, 'course-tag', $post_ID );
|
393 |
|
394 |
+
$output .= '<li class="tax-input-course-tag-item tax-input-course-tag-item-' . $tag->term_id . '"><label class="course-tag-checkbox"> <input type="checkbox" name="' . $input_name . '" value="' . $tag->term_id . '" ' . checked( $has_in_term, true, false ) . ' /> <span>' . $tag->name . '</span> </label>';
|
395 |
|
396 |
+
$output .= ' </li>';
|
397 |
}
|
398 |
+
$output .= '</ul>';
|
399 |
}
|
400 |
|
401 |
return $output;
|
413 |
* @since v.1.3.4
|
414 |
*/
|
415 |
|
416 |
+
if ( ! function_exists( 'course_builder_section_wrap' ) ) {
|
417 |
+
function course_builder_section_wrap( $content = '', $title = '', $echo = true ) {
|
418 |
ob_start();
|
419 |
+
?>
|
420 |
<div class="tutor-course-builder-section">
|
421 |
<div class="tutor-course-builder-section-title">
|
422 |
<h3><i class="tutor-icon-down"></i> <span><?php echo $title; ?></span></h3>
|
423 |
</div>
|
424 |
<div class="tutor-course-builder-section-content">
|
425 |
+
<?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
426 |
</div>
|
427 |
</div>
|
428 |
<?php
|
429 |
$html = ob_get_clean();
|
430 |
|
431 |
+
if ( $echo ) {
|
432 |
+
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
433 |
} else {
|
434 |
return $html;
|
435 |
}
|
437 |
}
|
438 |
|
439 |
|
440 |
+
if ( ! function_exists( 'get_tutor_header' ) ) {
|
441 |
+
function get_tutor_header( $fullScreen = false ) {
|
442 |
+
$enable_spotlight_mode = tutor_utils()->get_option( 'enable_spotlight_mode' );
|
443 |
|
444 |
+
if ( $enable_spotlight_mode || $fullScreen ) {
|
445 |
+
?>
|
446 |
<!doctype html>
|
447 |
<html <?php language_attributes(); ?>>
|
448 |
|
449 |
<head>
|
450 |
+
<meta charset="<?php bloginfo( 'charset' ); ?>" />
|
451 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
452 |
<link rel="profile" href="https://gmpg.org/xfn/11" />
|
453 |
+
<?php wp_head(); ?>
|
454 |
</head>
|
455 |
|
456 |
<body <?php body_class(); ?>>
|
457 |
<div id="tutor-page-wrap" class="tutor-site-wrap site">
|
458 |
+
<?php
|
459 |
+
} else {
|
460 |
+
get_header();
|
|
|
461 |
}
|
462 |
}
|
463 |
+
}
|
464 |
|
465 |
+
if ( ! function_exists( 'get_tutor_footer' ) ) {
|
466 |
+
function get_tutor_footer( $fullScreen = false ) {
|
467 |
+
$enable_spotlight_mode = tutor_utils()->get_option( 'enable_spotlight_mode' );
|
468 |
+
if ( $enable_spotlight_mode || $fullScreen ) {
|
469 |
+
?>
|
470 |
</div>
|
471 |
+
<?php wp_footer(); ?>
|
472 |
|
473 |
</body>
|
474 |
|
475 |
</html>
|
476 |
+
<?php
|
477 |
+
} else {
|
478 |
+
get_footer();
|
|
|
479 |
}
|
480 |
}
|
481 |
+
}
|
482 |
|
483 |
/**
|
484 |
* @param null $key
|
490 |
*
|
491 |
* @since v.1.3.6
|
492 |
*/
|
493 |
+
if ( ! function_exists( 'get_tutor_option' ) ) {
|
494 |
+
function get_tutor_option( $key = null, $default = false ) {
|
495 |
+
return tutils()->get_option( $key, $default );
|
|
|
496 |
}
|
497 |
+
}
|
498 |
|
499 |
/**
|
500 |
* @param null $key
|
504 |
*
|
505 |
* @since v.1.3.6
|
506 |
*/
|
507 |
+
if ( ! function_exists( 'update_tutor_option' ) ) {
|
508 |
+
function update_tutor_option( $key = null, $value = false ) {
|
509 |
+
tutils()->update_option( $key, $value );
|
|
|
510 |
}
|
511 |
+
}
|
512 |
/**
|
513 |
* @param int $course_id
|
514 |
* @param null $key
|
520 |
*
|
521 |
* @since v.1.4.1
|
522 |
*/
|
523 |
+
if ( ! function_exists( 'get_tutor_course_settings' ) ) {
|
524 |
+
function get_tutor_course_settings( $course_id = 0, $key = null, $default = false ) {
|
525 |
+
return tutils()->get_course_settings( $course_id, $key, $default );
|
|
|
526 |
}
|
527 |
+
}
|
528 |
|
529 |
/**
|
530 |
* @param int $lesson_id
|
536 |
* Get lesson content drip settings
|
537 |
*/
|
538 |
|
539 |
+
if ( ! function_exists( 'get_item_content_drip_settings' ) ) {
|
540 |
+
function get_item_content_drip_settings( $lesson_id = 0, $key = null, $default = false ) {
|
541 |
+
return tutils()->get_item_content_drip_settings( $lesson_id, $key, $default );
|
|
|
542 |
}
|
543 |
+
}
|
544 |
|
545 |
/**
|
546 |
* @param null $msg
|
553 |
*
|
554 |
* @since v.1.4.1
|
555 |
*/
|
556 |
+
if ( ! function_exists( 'tutor_alert' ) ) {
|
557 |
+
function tutor_alert( $msg = null, $type = 'warning', $echo = true ) {
|
558 |
+
if ( ! $msg ) {
|
559 |
+
|
560 |
+
if ( $type === 'any' ) {
|
561 |
+
if ( ! $msg ) {
|
562 |
+
$type = 'warning';
|
563 |
+
$msg = tutor_flash_get( $type );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
564 |
}
|
565 |
+
if ( ! $msg ) {
|
566 |
+
$type = 'danger';
|
567 |
+
$msg = tutor_flash_get( $type );
|
568 |
+
}
|
569 |
+
if ( ! $msg ) {
|
570 |
+
$type = 'success';
|
571 |
+
$msg = tutor_flash_get( $type );
|
572 |
+
}
|
573 |
+
} else {
|
574 |
+
$msg = tutor_flash_get( $type );
|
575 |
}
|
576 |
+
}
|
577 |
+
if ( ! $msg ) {
|
578 |
+
return $msg;
|
579 |
+
}
|
580 |
|
581 |
+
$html = '<div class="tutor-alert tutor-alert-' . $type . '">' . $msg . '</div>';
|
582 |
+
|
583 |
+
if ( $echo ) {
|
584 |
+
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
|
585 |
}
|
586 |
+
return $html;
|
587 |
}
|
588 |
+
}
|
589 |
|
590 |
|
591 |
/**
|
596 |
* @since v.1.4.2
|
597 |
*/
|
598 |
|
599 |
+
if ( ! function_exists( 'tutor_nonce_field' ) ) {
|
600 |
+
function tutor_nonce_field( $echo = true ) {
|
601 |
+
wp_nonce_field( tutor()->nonce_action, tutor()->nonce, $echo );
|
|
|
602 |
}
|
603 |
+
}
|
604 |
|
605 |
/**
|
606 |
* @param null $key
|
609 |
* Set Flash Message
|
610 |
*/
|
611 |
|
612 |
+
if ( ! function_exists( 'tutor_flash_set' ) ) {
|
613 |
+
function tutor_flash_set( $key = null, $message = '' ) {
|
614 |
+
if ( ! $key ) {
|
615 |
+
return;
|
616 |
+
}
|
617 |
+
// ensure session is started
|
618 |
+
if ( session_status() !== PHP_SESSION_ACTIVE ) {
|
619 |
+
session_start();
|
|
|
|
|
620 |
}
|
621 |
+
$_SESSION[ $key ] = $message;
|
622 |
}
|
623 |
+
}
|
624 |
|
625 |
/**
|
626 |
* @param null $key
|
632 |
* Get flash message
|
633 |
*/
|
634 |
|
635 |
+
if ( ! function_exists( 'tutor_flash_get' ) ) {
|
636 |
+
function tutor_flash_get( $key = null ) {
|
637 |
+
if ( $key ) {
|
638 |
+
// ensure session is started
|
639 |
+
if ( session_status() !== PHP_SESSION_ACTIVE ) {
|
640 |
+
@session_start();
|
641 |
+
}
|
642 |
+
if ( empty( $_SESSION ) ) {
|
643 |
+
return null;
|
|
|
|
|
|
|
|
|
|
|
|
|
644 |
}
|
645 |
+
$message = tutils()->array_get( $key, $_SESSION );
|
646 |
+
if ( $message ) {
|
647 |
+
unset( $_SESSION[ $key ] );
|
648 |
+
}
|
649 |
+
return $message;
|
650 |
}
|
651 |
+
return $key;
|
652 |
}
|
653 |
+
}
|
654 |
|
655 |
+
if ( ! function_exists( 'tutor_redirect_back' ) ) {
|
656 |
+
/**
|
657 |
+
* @param null $url
|
658 |
+
*
|
659 |
+
* Redirect to back or a specific URL and terminate
|
660 |
+
*
|
661 |
+
* @since v.1.4.3
|
662 |
+
*/
|
663 |
+
function tutor_redirect_back( $url = null ) {
|
664 |
+
if ( ! $url ) {
|
665 |
+
$url = tutils()->referer();
|
|
|
|
|
|
|
666 |
}
|
667 |
+
wp_safe_redirect( $url );
|
668 |
+
exit();
|
669 |
}
|
670 |
+
}
|
671 |
|
672 |
/**
|
673 |
* @param string $action
|
678 |
* @since v.1.4.3
|
679 |
*/
|
680 |
|
681 |
+
if ( ! function_exists( 'tutor_action_field' ) ) {
|
682 |
+
function tutor_action_field( $action = '', $echo = true ) {
|
683 |
+
$output = '';
|
684 |
+
if ( $action ) {
|
685 |
+
$output = '<input type="hidden" name="tutor_action" value="' . $action . '">';
|
686 |
+
}
|
687 |
|
688 |
+
if ( $echo ) {
|
689 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
690 |
+
} else {
|
691 |
+
return $output;
|
|
|
692 |
}
|
693 |
}
|
694 |
+
}
|
695 |
|
696 |
/**
|
697 |
* @return int|string
|
698 |
*
|
699 |
+
* Return current Time from WordPress time
|
700 |
*
|
701 |
* @since v.1.4.3
|
702 |
*/
|
703 |
|
704 |
+
if ( ! function_exists( 'tutor_time' ) ) {
|
705 |
+
function tutor_time() {
|
706 |
+
// return current_time( 'timestamp' );
|
707 |
+
return time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
|
|
|
708 |
}
|
709 |
+
}
|
710 |
|
711 |
/**
|
712 |
* Toggle maintenance mode for the site.
|
719 |
*
|
720 |
* @param bool $enable True to enable maintenance mode, false to disable.
|
721 |
*/
|
722 |
+
if ( ! function_exists( 'tutor_maintenance_mode' ) ) {
|
723 |
+
function tutor_maintenance_mode( $enable = false ) {
|
724 |
+
$file = ABSPATH . '.tutor_maintenance';
|
725 |
+
if ( $enable ) {
|
726 |
+
// Create maintenance file to signal that we are upgrading
|
727 |
+
$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
|
728 |
+
|
729 |
+
if ( ! file_exists( $file ) ) {
|
730 |
+
file_put_contents( $file, $maintenance_string );
|
731 |
+
}
|
732 |
+
} else {
|
733 |
+
if ( file_exists( $file ) ) {
|
734 |
+
unlink( $file );
|
|
|
735 |
}
|
736 |
}
|
737 |
}
|
738 |
+
}
|
739 |
|
740 |
/**
|
741 |
* @return bool
|
745 |
* @since v.1.6.0
|
746 |
*/
|
747 |
|
748 |
+
if ( ! function_exists( 'is_single_course' ) ) {
|
749 |
+
function is_single_course() {
|
750 |
+
global $wp_query;
|
751 |
+
$course_post_type = tutor()->course_post_type;
|
752 |
|
753 |
+
if ( is_single() && ! empty( $wp_query->query['post_type'] ) && $wp_query->query['post_type'] === $course_post_type ) {
|
754 |
+
return true;
|
|
|
|
|
755 |
}
|
756 |
+
return false;
|
757 |
}
|
758 |
+
}
|
759 |
|
760 |
/**
|
761 |
+
* Require wp_date form return js date format
|
762 |
+
*
|
763 |
* this is helpfull for date picker
|
764 |
+
*
|
765 |
* @return string
|
766 |
+
*
|
767 |
* @since 1.9.7
|
768 |
*/
|
769 |
+
if ( ! function_exists( 'tutor_js_date_format_against_wp' ) ) {
|
770 |
+
function tutor_js_date_format_against_wp() {
|
771 |
+
$wp_date_format = get_option( 'date_format' );
|
772 |
+
$default_format = 'yy-mm-dd';
|
773 |
+
|
774 |
+
$formats = array(
|
775 |
+
'Y-m-d' => 'yy-mm-dd',
|
776 |
+
'm/d/Y' => 'mm-dd-yy',
|
777 |
+
'd/m/Y' => 'dd-mm-yy',
|
778 |
+
'F j, Y' => 'MM dd, yy',
|
779 |
+
);
|
780 |
+
return isset( $formats[ $wp_date_format ] ) ? $formats[ $wp_date_format ] : $default_format;
|
|
|
781 |
}
|
782 |
+
}
|
783 |
|
784 |
/**
|
785 |
* Convert date to desire format
|
790 |
*
|
791 |
* @return string ( date )
|
792 |
*/
|
793 |
+
if ( ! function_exists( 'tutor_get_formated_date' ) ) {
|
794 |
+
function tutor_get_formated_date( string $require_format, string $user_date ) {
|
795 |
+
return date( $require_format, strtotime( $user_date ) );
|
|
|
796 |
}
|
797 |
+
}
|
798 |
+
|
799 |
|
|
includes/tutor-template-functions.php
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if ( ! defined( 'ABSPATH' ) )
|
4 |
-
|
|
|
5 |
|
6 |
/**
|
7 |
* @param null $template
|
@@ -16,39 +17,39 @@ if ( ! defined( 'ABSPATH' ) )
|
|
16 |
* @updated v.1.4.3
|
17 |
*/
|
18 |
|
19 |
-
if ( ! function_exists('tutor_get_template')) {
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
}
|
53 |
|
54 |
/**
|
@@ -61,30 +62,30 @@ if ( ! function_exists('tutor_get_template')) {
|
|
61 |
*
|
62 |
* @since v.1.4.2
|
63 |
*/
|
64 |
-
if ( ! function_exists('tutor_get_template_path')) {
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
}
|
89 |
|
90 |
/**
|
@@ -99,21 +100,21 @@ if ( ! function_exists('tutor_get_template_path')) {
|
|
99 |
* @updated v.1.1.2
|
100 |
*/
|
101 |
|
102 |
-
if ( ! function_exists('tutor_load_template')) {
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
}
|
118 |
|
119 |
/**
|
@@ -124,30 +125,30 @@ if ( ! function_exists('tutor_load_template')) {
|
|
124 |
* @since v.1.4.3
|
125 |
*/
|
126 |
|
127 |
-
if ( ! function_exists('tutor_load_template_part')) {
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
|
149 |
-
|
150 |
-
|
151 |
}
|
152 |
|
153 |
/**
|
@@ -159,213 +160,225 @@ if ( ! function_exists('tutor_load_template_part')) {
|
|
159 |
* @since v.1.4.3
|
160 |
*/
|
161 |
|
162 |
-
if ( ! function_exists('tutor_get_template_html')) {
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
|
167 |
-
|
168 |
-
|
169 |
}
|
170 |
|
171 |
-
if ( ! function_exists('tutor_course_loop_start')){
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
}
|
183 |
|
184 |
-
if ( ! function_exists('tutor_course_loop_end')) {
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
|
194 |
-
|
195 |
-
|
196 |
}
|
197 |
|
198 |
-
if ( ! function_exists('tutor_course_archive_pagination')) {
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
|
208 |
-
|
209 |
-
|
210 |
}
|
211 |
|
212 |
-
function tutor_course_loop_before_content(){
|
213 |
-
|
214 |
-
|
215 |
|
216 |
-
|
217 |
-
|
218 |
}
|
219 |
|
220 |
-
function tutor_course_loop_after_content(){
|
221 |
-
|
222 |
-
|
223 |
|
224 |
-
|
225 |
-
|
226 |
}
|
227 |
|
228 |
-
if ( ! function_exists('tutor_course_loop_title')) {
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
|
234 |
-
|
235 |
-
|
236 |
}
|
237 |
|
238 |
|
239 |
-
if ( ! function_exists('tutor_course_loop_header')) {
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
|
245 |
-
|
246 |
-
|
247 |
}
|
248 |
|
249 |
-
if ( ! function_exists('tutor_course_loop_footer')) {
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
|
255 |
-
|
256 |
-
|
257 |
}
|
258 |
|
259 |
-
//tutor_course_loop_footer
|
260 |
|
261 |
|
262 |
-
if ( ! function_exists('tutor_course_loop_start_content_wrap')) {
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
|
268 |
-
|
269 |
-
|
270 |
}
|
271 |
|
272 |
-
if ( ! function_exists('tutor_course_loop_end_content_wrap')) {
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
|
278 |
-
|
279 |
-
|
280 |
}
|
281 |
|
282 |
-
if ( ! function_exists('tutor_course_loop_thumbnail')) {
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
}
|
295 |
|
296 |
-
if( ! function_exists('tutor_course_loop_wrap_classes')) {
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
|
|
|
|
|
|
304 |
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
|
310 |
-
|
311 |
-
|
312 |
}
|
313 |
|
314 |
-
if( ! function_exists('tutor_course_loop_col_classes')) {
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
|
|
|
|
|
|
322 |
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
|
328 |
-
|
329 |
-
|
330 |
}
|
331 |
|
332 |
|
333 |
-
if ( ! function_exists('tutor_container_classes')) {
|
334 |
-
|
335 |
-
|
336 |
-
$classes = apply_filters( 'tutor_container_classes', array(
|
337 |
-
'tutor-wrap tutor-courses-wrap',
|
338 |
-
'tutor-container'
|
339 |
-
) );
|
340 |
|
341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
|
343 |
-
|
344 |
-
echo $class;
|
345 |
-
}
|
346 |
|
347 |
-
|
348 |
-
|
349 |
-
}
|
350 |
-
if ( ! function_exists('tutor_post_class')) {
|
351 |
-
function tutor_post_class($default = '') {
|
352 |
-
$classes = apply_filters( 'tutor_post_class', array(
|
353 |
-
'tutor-wrap',
|
354 |
-
$default
|
355 |
-
) );
|
356 |
|
357 |
-
|
358 |
-
|
359 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
|
|
|
|
|
|
|
|
369 |
}
|
370 |
|
371 |
/**
|
@@ -378,78 +391,81 @@ if ( ! function_exists('tutor_course_archive_filter_bar')) {
|
|
378 |
*
|
379 |
* @since v.1.3.1
|
380 |
*/
|
381 |
-
if( ! function_exists('tutor_widget_course_loop_classes')) {
|
382 |
-
|
383 |
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
|
|
|
|
|
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
|
395 |
-
|
396 |
-
|
397 |
}
|
398 |
|
399 |
/**
|
400 |
* Get the post thumbnail
|
401 |
*/
|
402 |
-
if ( ! function_exists('get_tutor_course_thumbnail')) {
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
}
|
426 |
/**
|
427 |
* Get the course/post thumbnail src
|
428 |
*/
|
429 |
-
if ( ! function_exists('get_tutor_course_thumbnail_src')) {
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
|
441 |
-
|
442 |
-
|
443 |
}
|
444 |
|
445 |
-
if ( ! function_exists('tutor_course_loop_meta')) {
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
|
451 |
-
|
452 |
-
|
453 |
}
|
454 |
|
455 |
/**
|
@@ -458,41 +474,39 @@ if ( ! function_exists('tutor_course_loop_meta')) {
|
|
458 |
* @since: v.1.0.0
|
459 |
*/
|
460 |
|
461 |
-
if ( ! function_exists('tutor_course_loop_author')) {
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
|
467 |
-
|
468 |
-
|
469 |
}
|
470 |
|
471 |
/**
|
472 |
* Get formatted price with cart form
|
473 |
*/
|
474 |
|
475 |
-
if ( ! function_exists('tutor_course_loop_price')) {
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
echo apply_filters( 'tutor_course_loop_price', ob_get_clean() );
|
495 |
-
}
|
496 |
}
|
497 |
|
498 |
/**
|
@@ -502,20 +516,20 @@ if ( ! function_exists('tutor_course_loop_price')) {
|
|
502 |
* @updated v.1.4.5
|
503 |
*/
|
504 |
|
505 |
-
if ( ! function_exists('tutor_course_loop_rating')) {
|
506 |
-
|
507 |
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
|
517 |
-
|
518 |
-
|
519 |
}
|
520 |
|
521 |
/**
|
@@ -526,32 +540,32 @@ if ( ! function_exists('tutor_course_loop_rating')) {
|
|
526 |
* Get add to cart form
|
527 |
*/
|
528 |
|
529 |
-
if ( ! function_exists('tutor_course_loop_add_to_cart')) {
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
|
538 |
-
|
539 |
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
}
|
546 |
|
547 |
-
if ( ! function_exists('tutor_course_price')) {
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
|
553 |
-
|
554 |
-
|
555 |
}
|
556 |
|
557 |
/**
|
@@ -561,13 +575,13 @@ if ( ! function_exists('tutor_course_price')) {
|
|
561 |
*
|
562 |
* @since: v.1.0.0
|
563 |
*/
|
564 |
-
if ( ! function_exists('tutor_the_excerpt')) {
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
}
|
572 |
/**
|
573 |
* @param int $post_id
|
@@ -578,15 +592,15 @@ if ( ! function_exists('tutor_the_excerpt')) {
|
|
578 |
*
|
579 |
* @since: v.1.0.0
|
580 |
*/
|
581 |
-
if ( ! function_exists('tutor_get_the_excerpt')) {
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
}
|
591 |
|
592 |
/**
|
@@ -597,16 +611,16 @@ if ( ! function_exists('tutor_get_the_excerpt')) {
|
|
597 |
* @since: v.1.0.0
|
598 |
*/
|
599 |
|
600 |
-
if ( ! function_exists('get_tutor_course_author')) {
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
}
|
606 |
|
607 |
-
function get_tutor_course_author_id(){
|
608 |
-
|
609 |
-
|
610 |
}
|
611 |
|
612 |
/**
|
@@ -618,22 +632,22 @@ function get_tutor_course_author_id(){
|
|
618 |
* @since: v.1.0.0
|
619 |
*/
|
620 |
|
621 |
-
if ( ! function_exists('tutor_course_benefits')) {
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
|
633 |
-
|
634 |
|
635 |
-
|
636 |
-
|
637 |
}
|
638 |
|
639 |
/**
|
@@ -646,17 +660,17 @@ if ( ! function_exists('tutor_course_benefits')) {
|
|
646 |
* @since: v.1.0.0
|
647 |
*/
|
648 |
|
649 |
-
if ( ! function_exists('tutor_course_benefits_html')) {
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
}
|
661 |
|
662 |
/**
|
@@ -668,19 +682,19 @@ if ( ! function_exists('tutor_course_benefits_html')) {
|
|
668 |
*
|
669 |
* @since: v.1.0.0
|
670 |
*/
|
671 |
-
if ( ! function_exists('tutor_course_topics')) {
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
|
682 |
-
|
683 |
-
|
684 |
}
|
685 |
|
686 |
/**
|
@@ -692,21 +706,21 @@ if ( ! function_exists('tutor_course_topics')) {
|
|
692 |
*
|
693 |
* @since: v.1.0.0
|
694 |
*/
|
695 |
-
if ( ! function_exists('tutor_course_requirements')) {
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
}
|
711 |
|
712 |
/**
|
@@ -718,17 +732,17 @@ if ( ! function_exists('tutor_course_requirements')) {
|
|
718 |
*
|
719 |
* @since: v.1.0.0
|
720 |
*/
|
721 |
-
if ( ! function_exists('tutor_course_requirements_html')) {
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
}
|
733 |
|
734 |
|
@@ -741,21 +755,21 @@ if ( ! function_exists('tutor_course_requirements_html')) {
|
|
741 |
*
|
742 |
* @since: v.1.0.0
|
743 |
*/
|
744 |
-
if ( ! function_exists('tutor_course_target_audience')) {
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
}
|
760 |
|
761 |
/**
|
@@ -767,105 +781,105 @@ if ( ! function_exists('tutor_course_target_audience')) {
|
|
767 |
*
|
768 |
* @since: v.1.0.0
|
769 |
*/
|
770 |
-
if ( ! function_exists('tutor_course_target_audience_html')) {
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
}
|
782 |
|
783 |
|
784 |
-
if ( ! function_exists('tutor_course_material_includes')) {
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
}
|
800 |
|
801 |
-
if ( ! function_exists('tutor_course_material_includes_html')) {
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
}
|
813 |
|
814 |
-
//tutor_course_material_includes_html
|
815 |
|
816 |
|
817 |
-
if ( ! function_exists('tutor_course_instructors_html')) {
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
}
|
834 |
|
835 |
-
if ( ! function_exists('tutor_course_target_reviews_html')) {
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
}
|
847 |
|
848 |
-
if ( ! function_exists('tutor_course_target_review_form_html')) {
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
}
|
870 |
|
871 |
/**
|
@@ -877,18 +891,18 @@ if ( ! function_exists('tutor_course_target_review_form_html')) {
|
|
877 |
*
|
878 |
* @since: v.1.0.0
|
879 |
*/
|
880 |
-
if ( ! function_exists('tutor_course_content')) {
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
|
890 |
-
|
891 |
-
|
892 |
}
|
893 |
|
894 |
/**
|
@@ -896,29 +910,36 @@ if ( ! function_exists('tutor_course_content')) {
|
|
896 |
*
|
897 |
* @since: v.1.0.0
|
898 |
*/
|
899 |
-
if ( ! function_exists('tutor_course_lead_info')) {
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
922 |
}
|
923 |
|
924 |
/**
|
@@ -927,59 +948,69 @@ if ( ! function_exists('tutor_course_lead_info')) {
|
|
927 |
* @return mixed|void
|
928 |
*/
|
929 |
|
930 |
-
if ( ! function_exists('tutor_course_enrolled_lead_info')) {
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
}
|
984 |
/**
|
985 |
* @param bool $echo
|
@@ -991,33 +1022,33 @@ if ( ! function_exists('tutor_lesson_lead_info')) {
|
|
991 |
* @since: v.1.0.0
|
992 |
*/
|
993 |
|
994 |
-
if ( ! function_exists('tutor_course_enroll_box')) {
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
|
1019 |
-
|
1020 |
-
|
1021 |
}
|
1022 |
|
1023 |
/**
|
@@ -1028,90 +1059,95 @@ if ( ! function_exists('tutor_course_enroll_box')) {
|
|
1028 |
* Get Only add to cart form
|
1029 |
*/
|
1030 |
|
1031 |
-
function tutor_single_course_add_to_cart($echo = true){
|
1032 |
-
|
|
|
|
|
|
|
1033 |
|
1034 |
-
|
1035 |
-
$output = '';
|
1036 |
|
1037 |
-
|
1038 |
-
|
1039 |
-
tutor_load_template( 'single.course.'.$template );
|
1040 |
-
$output .= apply_filters( 'tutor_course/single/'.$template, ob_get_clean() );
|
1041 |
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
|
1047 |
-
|
1048 |
-
|
1049 |
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
|
1054 |
-
|
1055 |
}
|
1056 |
|
1057 |
-
if ( ! function_exists('tutor_course_enrolled_nav')) {
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
|
1062 |
-
|
1063 |
-
|
1064 |
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
|
1071 |
-
|
1072 |
-
|
|
|
|
|
|
|
|
|
|
|
1073 |
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
}
|
1090 |
|
1091 |
-
if ( ! function_exists('tutor_course_video')){
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
}
|
1103 |
|
1104 |
-
if ( ! function_exists('tutor_lesson_video')){
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
}
|
1116 |
|
1117 |
/**
|
@@ -1124,17 +1160,17 @@ if ( ! function_exists('tutor_lesson_video')){
|
|
1124 |
*
|
1125 |
* @since v.1.0.0
|
1126 |
*/
|
1127 |
-
if ( ! function_exists('get_tutor_posts_attachments')){
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
}
|
1139 |
|
1140 |
/**
|
@@ -1146,18 +1182,18 @@ if ( ! function_exists('get_tutor_posts_attachments')){
|
|
1146 |
*
|
1147 |
* @since v.1.0.0
|
1148 |
*/
|
1149 |
-
if ( ! function_exists('tutor_lessons_sidebar')) {
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
|
1159 |
-
|
1160 |
-
|
1161 |
}
|
1162 |
|
1163 |
/**
|
@@ -1168,46 +1204,46 @@ if ( ! function_exists('tutor_lessons_sidebar')) {
|
|
1168 |
* Render Lesson Main Content
|
1169 |
* @since v.1.0.0
|
1170 |
*/
|
1171 |
-
if ( ! function_exists('tutor_lesson_content')) {
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
|
1181 |
-
|
1182 |
-
|
1183 |
}
|
1184 |
|
1185 |
-
if ( ! function_exists('tutor_lesson_mark_complete_html')) {
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
|
1195 |
-
|
1196 |
-
|
1197 |
}
|
1198 |
|
1199 |
-
if ( ! function_exists('tutor_course_mark_complete_html')) {
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
|
1209 |
-
|
1210 |
-
|
1211 |
}
|
1212 |
|
1213 |
|
@@ -1221,65 +1257,65 @@ if ( ! function_exists('tutor_course_mark_complete_html')) {
|
|
1221 |
* @since v.1.0.0
|
1222 |
*/
|
1223 |
|
1224 |
-
if ( ! function_exists('tutor_course_completing_progress_bar')) {
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
|
1234 |
-
|
1235 |
-
|
1236 |
}
|
1237 |
|
1238 |
-
function tutor_course_question_and_answer($echo = true){
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
|
1247 |
-
|
1248 |
}
|
1249 |
|
1250 |
|
1251 |
-
function tutor_course_announcements($echo = true){
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
|
1260 |
-
|
1261 |
}
|
1262 |
|
1263 |
-
function tutor_single_quiz_top($echo = true){
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
}
|
1273 |
|
1274 |
-
function tutor_single_quiz_body($echo = true){
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
}
|
1284 |
|
1285 |
/**
|
@@ -1289,99 +1325,99 @@ function tutor_single_quiz_body($echo = true){
|
|
1289 |
*
|
1290 |
* Get the quiz description
|
1291 |
*/
|
1292 |
-
function tutor_single_quiz_content($echo = true){
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
}
|
1302 |
|
1303 |
|
1304 |
-
function tutor_single_quiz_no_course_belongs($echo = true){
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
}
|
1314 |
|
1315 |
-
function single_quiz_contents($echo = true){
|
1316 |
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
}
|
1326 |
|
1327 |
-
function get_tutor_course_level($course_id = 0){
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
|
1335 |
-
|
1336 |
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
}
|
1342 |
|
1343 |
-
if ( ! function_exists('get_tutor_course_duration_context')) {
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
|
1370 |
-
|
1371 |
-
|
1372 |
|
1373 |
-
|
1374 |
-
|
1375 |
}
|
1376 |
-
if ( ! function_exists('get_tutor_course_categories')){
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
|
1383 |
-
|
1384 |
-
|
1385 |
}
|
1386 |
|
1387 |
/**
|
@@ -1392,15 +1428,15 @@ if ( ! function_exists('get_tutor_course_categories')){
|
|
1392 |
* Get course tags
|
1393 |
*/
|
1394 |
|
1395 |
-
if ( ! function_exists('get_tutor_course_tags')){
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
|
1402 |
-
|
1403 |
-
|
1404 |
}
|
1405 |
|
1406 |
/**
|
@@ -1411,18 +1447,18 @@ if ( ! function_exists('get_tutor_course_tags')){
|
|
1411 |
* Template for course tags html
|
1412 |
*/
|
1413 |
|
1414 |
-
if ( ! function_exists('tutor_course_tags_html')) {
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
|
1424 |
-
|
1425 |
-
|
1426 |
}
|
1427 |
|
1428 |
/**
|
@@ -1433,18 +1469,18 @@ if ( ! function_exists('tutor_course_tags_html')) {
|
|
1433 |
* Get Q&A in lesson sidebar
|
1434 |
*/
|
1435 |
|
1436 |
-
if ( ! function_exists('tutor_lesson_sidebar_question_and_answer')) {
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
|
1446 |
-
|
1447 |
-
|
1448 |
}
|
1449 |
|
1450 |
/**
|
@@ -1455,25 +1491,25 @@ if ( ! function_exists('tutor_lesson_sidebar_question_and_answer')) {
|
|
1455 |
* Get Social Share button to share on social media
|
1456 |
*/
|
1457 |
|
1458 |
-
if ( ! function_exists('tutor_social_share')) {
|
1459 |
-
|
1460 |
|
1461 |
-
|
1462 |
-
|
1463 |
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
|
1475 |
-
|
1476 |
-
|
1477 |
}
|
1478 |
|
1479 |
/**
|
@@ -1486,18 +1522,18 @@ if ( ! function_exists('tutor_social_share')) {
|
|
1486 |
* @since v.1.3.3
|
1487 |
*/
|
1488 |
|
1489 |
-
if ( ! function_exists('tutor_assignment_content')) {
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
|
1499 |
-
|
1500 |
-
|
1501 |
}
|
1502 |
|
1503 |
/**
|
@@ -1510,26 +1546,26 @@ if ( ! function_exists('tutor_assignment_content')) {
|
|
1510 |
* @since v.1.4.0
|
1511 |
*/
|
1512 |
|
1513 |
-
if ( ! function_exists('get_tnotice')) {
|
1514 |
-
|
1515 |
|
1516 |
-
|
1517 |
<div class="tnotice__icon">¡</div>
|
1518 |
<div class="tnotice__content">';
|
1519 |
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
</div>
|
1525 |
</div>';
|
1526 |
|
1527 |
-
|
1528 |
-
|
1529 |
}
|
1530 |
|
1531 |
/**
|
1532 |
-
* @param int
|
1533 |
* @param bool $echo
|
1534 |
*
|
1535 |
* @return mixed|void
|
@@ -1539,41 +1575,42 @@ if ( ! function_exists('get_tnotice')) {
|
|
1539 |
* @since v.1.4.7
|
1540 |
*/
|
1541 |
|
1542 |
-
function tutor_next_previous_pagination($course_content_id = 0, $echo = true){
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
|
1547 |
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
|
1558 |
-
|
1559 |
}
|
1560 |
|
1561 |
|
1562 |
/**
|
1563 |
* Required login form in archive page
|
|
|
1564 |
* @param bool $echo
|
1565 |
* @since v 1.5.5
|
1566 |
*
|
1567 |
* @todo, it will be remove from 2.0.0
|
1568 |
*/
|
1569 |
-
function tutor_archive_course_add_to_cart($echo = true){
|
1570 |
-
|
1571 |
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
}
|
1578 |
|
1579 |
/**
|
@@ -1585,36 +1622,36 @@ function tutor_archive_course_add_to_cart($echo = true){
|
|
1585 |
* @since v.1.5.8
|
1586 |
*/
|
1587 |
|
1588 |
-
if ( ! function_exists('tutor_login_form_popup')) {
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
|
1596 |
-
|
1597 |
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
}
|
1604 |
|
1605 |
/**
|
1606 |
* Load custom template from any given file
|
1607 |
-
*
|
1608 |
* Pass parameter as wish
|
1609 |
-
*
|
1610 |
* @since 1.9.8
|
1611 |
*/
|
1612 |
-
if ( ! function_exists('tutor_load_template_from_custom_path')) {
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
}
|
1 |
<?php
|
2 |
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
|
7 |
/**
|
8 |
* @param null $template
|
17 |
* @updated v.1.4.3
|
18 |
*/
|
19 |
|
20 |
+
if ( ! function_exists( 'tutor_get_template' ) ) {
|
21 |
+
function tutor_get_template( $template = null, $tutor_pro = false ) {
|
22 |
+
if ( ! $template ) {
|
23 |
+
return false;
|
24 |
+
}
|
25 |
+
$template = str_replace( '.', DIRECTORY_SEPARATOR, $template );
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get template first from child-theme if exists
|
29 |
+
* If child theme not exists, then get template from parent theme
|
30 |
+
*/
|
31 |
+
$template_location = trailingslashit( get_stylesheet_directory() ) . "tutor/{$template}.php";
|
32 |
+
if ( ! file_exists( $template_location ) ) {
|
33 |
+
$template_location = trailingslashit( get_template_directory() ) . "tutor/{$template}.php";
|
34 |
+
}
|
35 |
+
$file_in_theme = $template_location;
|
36 |
+
if ( ! file_exists( $template_location ) ) {
|
37 |
+
$template_location = trailingslashit( tutor()->path ) . "templates/{$template}.php";
|
38 |
+
|
39 |
+
if ( $tutor_pro && function_exists( 'tutor_pro' ) ) {
|
40 |
+
$pro_template_location = trailingslashit( tutor_pro()->path ) . "templates/{$template}.php";
|
41 |
+
if ( file_exists( $pro_template_location ) ) {
|
42 |
+
$template_location = trailingslashit( tutor_pro()->path ) . "templates/{$template}.php";
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
if ( ! file_exists( $template_location ) ) {
|
47 |
+
echo '<div class="tutor-notice-warning"> ' . __( sprintf( 'The file you are trying to load does not exist in your theme or Tutor LMS plugin location. If you are extending the Tutor LMS plugin, please create a php file here: %s ', '<code>' . $file_in_theme . '</code>' ), 'tutor' ) . ' </div>';
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
return apply_filters( 'tutor_get_template_path', $template_location, $template );
|
52 |
+
}
|
53 |
}
|
54 |
|
55 |
/**
|
62 |
*
|
63 |
* @since v.1.4.2
|
64 |
*/
|
65 |
+
if ( ! function_exists( 'tutor_get_template_path' ) ) {
|
66 |
+
function tutor_get_template_path( $template = null, $tutor_pro = false ) {
|
67 |
+
if ( ! $template ) {
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
$template = str_replace( '.', DIRECTORY_SEPARATOR, $template );
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Get template first from child-theme if exists
|
74 |
+
* If child theme not exists, then get template from parent theme
|
75 |
+
*/
|
76 |
+
$template_location = trailingslashit( get_stylesheet_directory() ) . "tutor/{$template}.php";
|
77 |
+
if ( ! file_exists( $template_location ) ) {
|
78 |
+
$template_location = trailingslashit( get_template_directory() ) . "tutor/{$template}.php";
|
79 |
+
}
|
80 |
+
if ( ! file_exists( $template_location ) ) {
|
81 |
+
$template_location = trailingslashit( tutor()->path ) . "templates/{$template}.php";
|
82 |
+
}
|
83 |
+
if ( ! file_exists( $template_location ) && $tutor_pro && function_exists( 'tutor_pro' ) ) {
|
84 |
+
$template_location = trailingslashit( tutor_pro()->path ) . "templates/{$template}.php";
|
85 |
+
}
|
86 |
+
|
87 |
+
return apply_filters( 'tutor_get_template_path', $template_location, $template );
|
88 |
+
}
|
89 |
}
|
90 |
|
91 |
/**
|
100 |
* @updated v.1.1.2
|
101 |
*/
|
102 |
|
103 |
+
if ( ! function_exists( 'tutor_load_template' ) ) {
|
104 |
+
function tutor_load_template( $template = null, $variables = array(), $tutor_pro = false ) {
|
105 |
+
$variables = (array) $variables;
|
106 |
+
$variables = apply_filters( 'get_tutor_load_template_variables', $variables );
|
107 |
+
extract( $variables );
|
108 |
|
109 |
+
$isLoad = apply_filters( 'should_tutor_load_template', true, $template, $variables );
|
110 |
+
if ( ! $isLoad ) {
|
111 |
+
return;
|
112 |
+
}
|
113 |
|
114 |
+
do_action( 'tutor_load_template_before', $template, $variables );
|
115 |
+
include tutor_get_template( $template, $tutor_pro );
|
116 |
+
do_action( 'tutor_load_template_after', $template, $variables );
|
117 |
+
}
|
118 |
}
|
119 |
|
120 |
/**
|
125 |
* @since v.1.4.3
|
126 |
*/
|
127 |
|
128 |
+
if ( ! function_exists( 'tutor_load_template_part' ) ) {
|
129 |
+
function tutor_load_template_part( $template = null, $variables = array(), $tutor_pro = false ) {
|
130 |
+
$variables = (array) $variables;
|
131 |
+
$variables = apply_filters( 'get_tutor_load_template_variables', $variables );
|
132 |
+
extract( $variables );
|
133 |
|
134 |
+
/**
|
135 |
+
* Get template first from child-theme if exists
|
136 |
+
* If child theme not exists, then get template from parent theme
|
137 |
+
*/
|
138 |
+
$template_location = trailingslashit( get_stylesheet_directory() ) . 'tutor/template.php';
|
139 |
+
if ( ! file_exists( $template_location ) ) {
|
140 |
+
$template_location = trailingslashit( get_template_directory() ) . 'tutor/template.php';
|
141 |
+
}
|
142 |
|
143 |
+
if ( ! file_exists( $template_location ) ) {
|
144 |
+
$template_location = trailingslashit( tutor()->path ) . 'templates/template.php';
|
145 |
+
if ( ! file_exists( $template_location ) && $tutor_pro && function_exists( 'tutor_pro' ) ) {
|
146 |
+
$template_location = trailingslashit( tutor_pro()->path ) . 'templates/template.php';
|
147 |
+
}
|
148 |
+
}
|
149 |
|
150 |
+
include apply_filters( 'tutor_get_template_part_path', $template_location, $template );
|
151 |
+
}
|
152 |
}
|
153 |
|
154 |
/**
|
160 |
* @since v.1.4.3
|
161 |
*/
|
162 |
|
163 |
+
if ( ! function_exists( 'tutor_get_template_html' ) ) {
|
164 |
+
function tutor_get_template_html( $template_name, $variables = array(), $tutor_pro = false ) {
|
165 |
+
ob_start();
|
166 |
+
tutor_load_template( $template_name, $variables, $tutor_pro );
|
167 |
|
168 |
+
return ob_get_clean();
|
169 |
+
}
|
170 |
}
|
171 |
|
172 |
+
if ( ! function_exists( 'tutor_course_loop_start' ) ) {
|
173 |
+
function tutor_course_loop_start( $echo = true ) {
|
174 |
+
ob_start();
|
175 |
+
tutor_load_template( 'loop.loop-start' );
|
176 |
+
$output = apply_filters( 'tutor_course_loop_start', ob_get_clean() );
|
177 |
|
178 |
+
if ( $echo ) {
|
179 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
180 |
+
}
|
181 |
+
return $output;
|
182 |
+
}
|
183 |
}
|
184 |
|
185 |
+
if ( ! function_exists( 'tutor_course_loop_end' ) ) {
|
186 |
+
function tutor_course_loop_end( $echo = true ) {
|
187 |
+
ob_start();
|
188 |
+
tutor_load_template( 'loop.loop-end' );
|
189 |
|
190 |
+
$output = apply_filters( 'tutor_course_loop_end', ob_get_clean() );
|
191 |
+
if ( $echo ) {
|
192 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
193 |
+
}
|
194 |
|
195 |
+
return $output;
|
196 |
+
}
|
197 |
}
|
198 |
|
199 |
+
if ( ! function_exists( 'tutor_course_archive_pagination' ) ) {
|
200 |
+
function tutor_course_archive_pagination( $echo = true ) {
|
201 |
+
ob_start();
|
202 |
+
tutor_load_template( 'loop.tutor-pagination' );
|
203 |
|
204 |
+
$output = apply_filters( 'tutor_course_archive_pagination', ob_get_clean() );
|
205 |
+
if ( $echo ) {
|
206 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
207 |
+
}
|
208 |
|
209 |
+
return $output;
|
210 |
+
}
|
211 |
}
|
212 |
|
213 |
+
function tutor_course_loop_before_content() {
|
214 |
+
ob_start();
|
215 |
+
tutor_load_template( 'loop.loop-before-content' );
|
216 |
|
217 |
+
$output = apply_filters( 'tutor_course_loop_before_content', ob_get_clean() );
|
218 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
219 |
}
|
220 |
|
221 |
+
function tutor_course_loop_after_content() {
|
222 |
+
ob_start();
|
223 |
+
tutor_load_template( 'loop.loop-after-content' );
|
224 |
|
225 |
+
$output = apply_filters( 'tutor_course_loop_after_content', ob_get_clean() );
|
226 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
227 |
}
|
228 |
|
229 |
+
if ( ! function_exists( 'tutor_course_loop_title' ) ) {
|
230 |
+
function tutor_course_loop_title() {
|
231 |
+
ob_start();
|
232 |
+
tutor_load_template( 'loop.title' );
|
233 |
+
$output = apply_filters( 'tutor_course_loop_title', ob_get_clean() );
|
234 |
|
235 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
236 |
+
}
|
237 |
}
|
238 |
|
239 |
|
240 |
+
if ( ! function_exists( 'tutor_course_loop_header' ) ) {
|
241 |
+
function tutor_course_loop_header() {
|
242 |
+
ob_start();
|
243 |
+
tutor_load_template( 'loop.header' );
|
244 |
+
$output = apply_filters( 'tutor_course_loop_header', ob_get_clean() );
|
245 |
|
246 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
247 |
+
}
|
248 |
}
|
249 |
|
250 |
+
if ( ! function_exists( 'tutor_course_loop_footer' ) ) {
|
251 |
+
function tutor_course_loop_footer() {
|
252 |
+
ob_start();
|
253 |
+
tutor_load_template( 'loop.footer' );
|
254 |
+
$output = apply_filters( 'tutor_course_loop_footer', ob_get_clean() );
|
255 |
|
256 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
257 |
+
}
|
258 |
}
|
259 |
|
260 |
+
// tutor_course_loop_footer
|
261 |
|
262 |
|
263 |
+
if ( ! function_exists( 'tutor_course_loop_start_content_wrap' ) ) {
|
264 |
+
function tutor_course_loop_start_content_wrap() {
|
265 |
+
ob_start();
|
266 |
+
tutor_load_template( 'loop.start_content_wrap' );
|
267 |
+
$output = apply_filters( 'tutor_course_loop_start_content_wrap', ob_get_clean() );
|
268 |
|
269 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
270 |
+
}
|
271 |
}
|
272 |
|
273 |
+
if ( ! function_exists( 'tutor_course_loop_end_content_wrap' ) ) {
|
274 |
+
function tutor_course_loop_end_content_wrap() {
|
275 |
+
ob_start();
|
276 |
+
tutor_load_template( 'loop.end_content_wrap' );
|
277 |
+
$output = apply_filters( 'tutor_course_loop_end_content_wrap', ob_get_clean() );
|
278 |
|
279 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
280 |
+
}
|
281 |
}
|
282 |
|
283 |
+
if ( ! function_exists( 'tutor_course_loop_thumbnail' ) ) {
|
284 |
+
function tutor_course_loop_thumbnail( $echo = true ) {
|
285 |
+
ob_start();
|
286 |
+
tutor_load_template( 'loop.thumbnail' );
|
287 |
+
$output = apply_filters( 'tutor_course_loop_thumbnail', ob_get_clean() );
|
288 |
|
289 |
+
if ( $echo ) {
|
290 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
291 |
+
} else {
|
292 |
+
return $output;
|
293 |
+
}
|
294 |
+
}
|
295 |
}
|
296 |
|
297 |
+
if ( ! function_exists( 'tutor_course_loop_wrap_classes' ) ) {
|
298 |
+
function tutor_course_loop_wrap_classes( $echo = true ) {
|
299 |
+
$courseID = get_the_ID();
|
300 |
+
$classes = apply_filters(
|
301 |
+
'tutor_course_loop_wrap_classes',
|
302 |
+
array(
|
303 |
+
'tutor-course',
|
304 |
+
'tutor-course-loop',
|
305 |
+
'tutor-course-loop-' . $courseID,
|
306 |
+
)
|
307 |
+
);
|
308 |
|
309 |
+
$class = implode( ' ', $classes );
|
310 |
+
if ( $echo ) {
|
311 |
+
echo esc_attr( $class );
|
312 |
+
}
|
313 |
|
314 |
+
return esc_attr( $class );
|
315 |
+
}
|
316 |
}
|
317 |
|
318 |
+
if ( ! function_exists( 'tutor_course_loop_col_classes' ) ) {
|
319 |
+
function tutor_course_loop_col_classes( $echo = true ) {
|
320 |
+
$course_filter = (bool) tutor_utils()->get_option( 'course_archive_filter', false );
|
321 |
+
$shortcode_arg = isset( $GLOBALS['tutor_shortcode_arg'] ) ? $GLOBALS['tutor_shortcode_arg']['column_per_row'] : null;
|
322 |
+
$course_cols = $shortcode_arg === null ? tutor_utils()->get_option( 'courses_col_per_row', 3 ) : $shortcode_arg;
|
323 |
+
$classes = apply_filters(
|
324 |
+
'tutor_course_loop_col_classes',
|
325 |
+
array(
|
326 |
+
'tutor-course-col-' . $course_cols,
|
327 |
+
)
|
328 |
+
);
|
329 |
|
330 |
+
$class = implode( ' ', $classes );
|
331 |
+
if ( $echo ) {
|
332 |
+
echo esc_attr( $class );
|
333 |
+
}
|
334 |
|
335 |
+
return esc_attr( $class );
|
336 |
+
}
|
337 |
}
|
338 |
|
339 |
|
340 |
+
if ( ! function_exists( 'tutor_container_classes' ) ) {
|
341 |
+
function tutor_container_classes( $echo = true ) {
|
|
|
|
|
|
|
|
|
|
|
342 |
|
343 |
+
$classes = apply_filters(
|
344 |
+
'tutor_container_classes',
|
345 |
+
array(
|
346 |
+
'tutor-wrap tutor-courses-wrap',
|
347 |
+
'tutor-container',
|
348 |
+
)
|
349 |
+
);
|
350 |
|
351 |
+
$class = implode( ' ', $classes );
|
|
|
|
|
352 |
|
353 |
+
if ( $echo ) {
|
354 |
+
echo esc_attr( $class );
|
355 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
|
357 |
+
return esc_attr( $class );
|
358 |
+
}
|
359 |
}
|
360 |
+
if ( ! function_exists( 'tutor_post_class' ) ) {
|
361 |
+
function tutor_post_class( $default = '' ) {
|
362 |
+
$classes = apply_filters(
|
363 |
+
'tutor_post_class',
|
364 |
+
array(
|
365 |
+
'tutor-wrap',
|
366 |
+
$default,
|
367 |
+
)
|
368 |
+
);
|
369 |
|
370 |
+
post_class( $classes );
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
if ( ! function_exists( 'tutor_course_archive_filter_bar' ) ) {
|
375 |
+
function tutor_course_archive_filter_bar() {
|
376 |
+
ob_start();
|
377 |
+
tutor_load_template( 'global.course-archive-filter-bar' );
|
378 |
+
$output = apply_filters( 'tutor_course_archive_filter_bar', ob_get_clean() );
|
379 |
+
|
380 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
381 |
+
}
|
382 |
}
|
383 |
|
384 |
/**
|
391 |
*
|
392 |
* @since v.1.3.1
|
393 |
*/
|
394 |
+
if ( ! function_exists( 'tutor_widget_course_loop_classes' ) ) {
|
395 |
+
function tutor_widget_course_loop_classes( $echo = true ) {
|
396 |
|
397 |
+
$classes = apply_filters(
|
398 |
+
'tutor_widget_course_loop_classes',
|
399 |
+
array(
|
400 |
+
'tutor-widget-course-loop',
|
401 |
+
'tutor-widget-course',
|
402 |
+
'tutor-widget-course-' . get_the_ID(),
|
403 |
+
)
|
404 |
+
);
|
405 |
|
406 |
+
$class = implode( ' ', $classes );
|
407 |
+
if ( $echo ) {
|
408 |
+
echo esc_attr( $class );
|
409 |
+
}
|
410 |
|
411 |
+
return esc_attr( $class );
|
412 |
+
}
|
413 |
}
|
414 |
|
415 |
/**
|
416 |
* Get the post thumbnail
|
417 |
*/
|
418 |
+
if ( ! function_exists( 'get_tutor_course_thumbnail' ) ) {
|
419 |
+
function get_tutor_course_thumbnail( $size = 'post-thumbnail', $url = false ) {
|
420 |
+
$post_id = get_the_ID();
|
421 |
+
$post_thumbnail_id = (int) get_post_thumbnail_id( $post_id );
|
422 |
+
|
423 |
+
if ( $post_thumbnail_id ) {
|
424 |
+
// $size = apply_filters( 'post_thumbnail_size', $size, $post_id );
|
425 |
+
$size = apply_filters( 'tutor_course_thumbnail_size', $size, $post_id );
|
426 |
+
if ( $url ) {
|
427 |
+
return wp_get_attachment_image_url( $post_thumbnail_id, $size );
|
428 |
+
}
|
429 |
+
|
430 |
+
$html = wp_get_attachment_image( $post_thumbnail_id, $size, false );
|
431 |
+
} else {
|
432 |
+
$placeHolderUrl = tutor()->url . 'assets/images/placeholder.jpg';
|
433 |
+
if ( $url ) {
|
434 |
+
return $placeHolderUrl;
|
435 |
+
}
|
436 |
+
$html = sprintf( '<img alt="%s" src="' . $placeHolderUrl . '" />', __( 'Placeholder', 'tutor' ) );
|
437 |
+
}
|
438 |
+
|
439 |
+
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
440 |
+
}
|
441 |
}
|
442 |
/**
|
443 |
* Get the course/post thumbnail src
|
444 |
*/
|
445 |
+
if ( ! function_exists( 'get_tutor_course_thumbnail_src' ) ) {
|
446 |
+
function get_tutor_course_thumbnail_src( $size = 'post-thumbnail' ) {
|
447 |
+
$post_id = get_the_ID();
|
448 |
+
$post_thumbnail_id = (int) get_post_thumbnail_id( $post_id );
|
449 |
|
450 |
+
if ( $post_thumbnail_id ) {
|
451 |
+
$size = apply_filters( 'tutor_course_thumbnail_size', $size, $post_id );
|
452 |
+
$src = wp_get_attachment_image_url( $post_thumbnail_id, $size, false );
|
453 |
+
} else {
|
454 |
+
$src = tutor()->url . 'assets/images/placeholder.jpg';
|
455 |
+
}
|
456 |
|
457 |
+
return $src;
|
458 |
+
}
|
459 |
}
|
460 |
|
461 |
+
if ( ! function_exists( 'tutor_course_loop_meta' ) ) {
|
462 |
+
function tutor_course_loop_meta() {
|
463 |
+
ob_start();
|
464 |
+
tutor_load_template( 'loop.meta' );
|
465 |
+
$output = apply_filters( 'tutor_course_loop_meta', ob_get_clean() );
|
466 |
|
467 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
468 |
+
}
|
469 |
}
|
470 |
|
471 |
/**
|
474 |
* @since: v.1.0.0
|
475 |
*/
|
476 |
|
477 |
+
if ( ! function_exists( 'tutor_course_loop_author' ) ) {
|
478 |
+
function tutor_course_loop_author() {
|
479 |
+
ob_start();
|
480 |
+
tutor_load_template( 'loop.course-author' );
|
481 |
+
$output = apply_filters( 'tutor_course_loop_author', ob_get_clean() );
|
482 |
|
483 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
484 |
+
}
|
485 |
}
|
486 |
|
487 |
/**
|
488 |
* Get formatted price with cart form
|
489 |
*/
|
490 |
|
491 |
+
if ( ! function_exists( 'tutor_course_loop_price' ) ) {
|
492 |
+
function tutor_course_loop_price() {
|
493 |
+
ob_start();
|
494 |
+
|
495 |
+
if ( tutils()->is_course_added_to_cart( get_the_ID() ) ) {
|
496 |
+
tutor_load_template( 'loop.course-in-cart' );
|
497 |
+
} elseif ( tutils()->is_enrolled( get_the_ID() ) ) {
|
498 |
+
tutor_load_template( 'loop.course-continue' );
|
499 |
+
} else {
|
500 |
+
$tutor_course_sell_by = apply_filters( 'tutor_course_sell_by', null );
|
501 |
+
if ( $tutor_course_sell_by ) {
|
502 |
+
tutor_load_template( 'loop.course-price-' . $tutor_course_sell_by );
|
503 |
+
} else {
|
504 |
+
tutor_load_template( 'loop.course-price' );
|
505 |
+
}
|
506 |
+
}
|
507 |
+
|
508 |
+
echo apply_filters( 'tutor_course_loop_price', ob_get_clean() );
|
509 |
+
}
|
|
|
|
|
510 |
}
|
511 |
|
512 |
/**
|
516 |
* @updated v.1.4.5
|
517 |
*/
|
518 |
|
519 |
+
if ( ! function_exists( 'tutor_course_loop_rating' ) ) {
|
520 |
+
function tutor_course_loop_rating() {
|
521 |
|
522 |
+
$disable = get_tutor_option( 'disable_course_review' );
|
523 |
+
if ( $disable ) {
|
524 |
+
return;
|
525 |
+
}
|
526 |
|
527 |
+
ob_start();
|
528 |
+
tutor_load_template( 'loop.rating' );
|
529 |
+
$output = apply_filters( 'tutor_course_loop_rating', ob_get_clean() );
|
530 |
|
531 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
532 |
+
}
|
533 |
}
|
534 |
|
535 |
/**
|
540 |
* Get add to cart form
|
541 |
*/
|
542 |
|
543 |
+
if ( ! function_exists( 'tutor_course_loop_add_to_cart' ) ) {
|
544 |
+
function tutor_course_loop_add_to_cart( $echo = true ) {
|
545 |
+
ob_start();
|
546 |
+
$tutor_course_sell_by = apply_filters( 'tutor_course_sell_by', null );
|
547 |
|
548 |
+
if ( $tutor_course_sell_by ) {
|
549 |
+
tutor_load_template( 'loop.add-to-cart-' . $tutor_course_sell_by );
|
550 |
+
}
|
551 |
|
552 |
+
$output = apply_filters( 'tutor_course_loop_add_to_cart_link', ob_get_clean() );
|
553 |
|
554 |
+
if ( $echo ) {
|
555 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
556 |
+
}
|
557 |
+
return $output;
|
558 |
+
}
|
559 |
}
|
560 |
|
561 |
+
if ( ! function_exists( 'tutor_course_price' ) ) {
|
562 |
+
function tutor_course_price() {
|
563 |
+
ob_start();
|
564 |
+
tutor_load_template( 'single.course.wc-price-html' );
|
565 |
+
$output = apply_filters( 'tutor_course_price', ob_get_clean() );
|
566 |
|
567 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
568 |
+
}
|
569 |
}
|
570 |
|
571 |
/**
|
575 |
*
|
576 |
* @since: v.1.0.0
|
577 |
*/
|
578 |
+
if ( ! function_exists( 'tutor_the_excerpt' ) ) {
|
579 |
+
function tutor_the_excerpt( $post_id = 0 ) {
|
580 |
+
if ( ! $post_id ) {
|
581 |
+
$post_id = get_the_ID();
|
582 |
+
}
|
583 |
+
echo tutor_get_the_excerpt( $post_id );
|
584 |
+
}
|
585 |
}
|
586 |
/**
|
587 |
* @param int $post_id
|
592 |
*
|
593 |
* @since: v.1.0.0
|
594 |
*/
|
595 |
+
if ( ! function_exists( 'tutor_get_the_excerpt' ) ) {
|
596 |
+
function tutor_get_the_excerpt( $post_id = 0 ) {
|
597 |
+
if ( ! $post_id ) {
|
598 |
+
$post_id = get_the_ID();
|
599 |
+
}
|
600 |
|
601 |
+
$get_post = get_post( $post_id );
|
602 |
+
return apply_filters( 'tutor_get_the_excerpt', $get_post->post_excerpt );
|
603 |
+
}
|
604 |
}
|
605 |
|
606 |
/**
|
611 |
* @since: v.1.0.0
|
612 |
*/
|
613 |
|
614 |
+
if ( ! function_exists( 'get_tutor_course_author' ) ) {
|
615 |
+
function get_tutor_course_author() {
|
616 |
+
global $post;
|
617 |
+
return apply_filters( 'get_tutor_course_author', get_the_author_meta( 'display_name', $post->post_author ) );
|
618 |
+
}
|
619 |
}
|
620 |
|
621 |
+
function get_tutor_course_author_id() {
|
622 |
+
global $post;
|
623 |
+
return (int) $post->post_author;
|
624 |
}
|
625 |
|
626 |
/**
|
632 |
* @since: v.1.0.0
|
633 |
*/
|
634 |
|
635 |
+
if ( ! function_exists( 'tutor_course_benefits' ) ) {
|
636 |
+
function tutor_course_benefits( $course_id = 0 ) {
|
637 |
+
if ( ! $course_id ) {
|
638 |
+
$course_id = get_the_ID();
|
639 |
+
}
|
640 |
+
$benefits = get_post_meta( $course_id, '_tutor_course_benefits', true );
|
641 |
|
642 |
+
$benefits_array = array();
|
643 |
+
if ( $benefits ) {
|
644 |
+
$benefits_array = explode( "\n", $benefits );
|
645 |
+
}
|
646 |
|
647 |
+
$array = array_filter( array_map( 'trim', $benefits_array ) );
|
648 |
|
649 |
+
return apply_filters( 'tutor_course/single/benefits', $array, $course_id );
|
650 |
+
}
|
651 |
}
|
652 |
|
653 |
/**
|
660 |
* @since: v.1.0.0
|
661 |
*/
|
662 |
|
663 |
+
if ( ! function_exists( 'tutor_course_benefits_html' ) ) {
|
664 |
+
function tutor_course_benefits_html( $echo = true ) {
|
665 |
+
ob_start();
|
666 |
+
tutor_load_template( 'single.course.course-benefits' );
|
667 |
+
$output = apply_filters( 'tutor_course/single/benefits_html', ob_get_clean() );
|
668 |
|
669 |
+
if ( $echo ) {
|
670 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
671 |
+
}
|
672 |
+
return $output;
|
673 |
+
}
|
674 |
}
|
675 |
|
676 |
/**
|
682 |
*
|
683 |
* @since: v.1.0.0
|
684 |
*/
|
685 |
+
if ( ! function_exists( 'tutor_course_topics' ) ) {
|
686 |
+
function tutor_course_topics( $echo = true ) {
|
687 |
+
ob_start();
|
688 |
+
tutor_load_template( 'single.course.course-topics' );
|
689 |
+
$output = apply_filters( 'tutor_course/single/topics', ob_get_clean() );
|
690 |
+
wp_reset_postdata();
|
691 |
|
692 |
+
if ( $echo ) {
|
693 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
694 |
+
}
|
695 |
|
696 |
+
return $output;
|
697 |
+
}
|
698 |
}
|
699 |
|
700 |
/**
|
706 |
*
|
707 |
* @since: v.1.0.0
|
708 |
*/
|
709 |
+
if ( ! function_exists( 'tutor_course_requirements' ) ) {
|
710 |
+
function tutor_course_requirements( $course_id = 0 ) {
|
711 |
+
if ( ! $course_id ) {
|
712 |
+
$course_id = get_the_ID();
|
713 |
+
}
|
714 |
+
$requirements = get_post_meta( $course_id, '_tutor_course_requirements', true );
|
715 |
|
716 |
+
$requirements_array = array();
|
717 |
+
if ( $requirements ) {
|
718 |
+
$requirements_array = explode( "\n", $requirements );
|
719 |
+
}
|
720 |
|
721 |
+
$array = array_filter( array_map( 'trim', $requirements_array ) );
|
722 |
+
return apply_filters( 'tutor_course/single/requirements', $array, $course_id );
|
723 |
+
}
|
724 |
}
|
725 |
|
726 |
/**
|
732 |
*
|
733 |
* @since: v.1.0.0
|
734 |
*/
|
735 |
+
if ( ! function_exists( 'tutor_course_requirements_html' ) ) {
|
736 |
+
function tutor_course_requirements_html( $echo = true ) {
|
737 |
+
ob_start();
|
738 |
+
tutor_load_template( 'single.course.course-requirements' );
|
739 |
+
$output = apply_filters( 'tutor_course/single/requirements_html', ob_get_clean() );
|
740 |
|
741 |
+
if ( $echo ) {
|
742 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
743 |
+
}
|
744 |
+
return $output;
|
745 |
+
}
|
746 |
}
|
747 |
|
748 |
|
755 |
*
|
756 |
* @since: v.1.0.0
|
757 |
*/
|
758 |
+
if ( ! function_exists( 'tutor_course_target_audience' ) ) {
|
759 |
+
function tutor_course_target_audience( $course_id = 0 ) {
|
760 |
+
if ( ! $course_id ) {
|
761 |
+
$course_id = get_the_ID();
|
762 |
+
}
|
763 |
+
$target_audience = get_post_meta( $course_id, '_tutor_course_target_audience', true );
|
764 |
|
765 |
+
$target_audience_array = array();
|
766 |
+
if ( $target_audience ) {
|
767 |
+
$target_audience_array = explode( "\n", $target_audience );
|
768 |
+
}
|
769 |
|
770 |
+
$array = array_filter( array_map( 'trim', $target_audience_array ) );
|
771 |
+
return apply_filters( 'tutor_course/single/target_audience', $array, $course_id );
|
772 |
+
}
|
773 |
}
|
774 |
|
775 |
/**
|
781 |
*
|
782 |
* @since: v.1.0.0
|
783 |
*/
|
784 |
+
if ( ! function_exists( 'tutor_course_target_audience_html' ) ) {
|
785 |
+
function tutor_course_target_audience_html( $echo = true ) {
|
786 |
+
ob_start();
|
787 |
+
tutor_load_template( 'single.course.course-target-audience' );
|
788 |
+
$output = apply_filters( 'tutor_course/single/audience_html', ob_get_clean() );
|
789 |
|
790 |
+
if ( $echo ) {
|
791 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
792 |
+
}
|
793 |
+
return $output;
|
794 |
+
}
|
795 |
}
|
796 |
|
797 |
|
798 |
+
if ( ! function_exists( 'tutor_course_material_includes' ) ) {
|
799 |
+
function tutor_course_material_includes( $course_id = 0 ) {
|
800 |
+
if ( ! $course_id ) {
|
801 |
+
$course_id = get_the_ID();
|
802 |
+
}
|
803 |
+
$target_audience = get_post_meta( $course_id, '_tutor_course_material_includes', true );
|
804 |
|
805 |
+
$target_audience_array = array();
|
806 |
+
if ( $target_audience ) {
|
807 |
+
$target_audience_array = explode( "\n", $target_audience );
|
808 |
+
}
|
809 |
|
810 |
+
$array = array_filter( array_map( 'trim', $target_audience_array ) );
|
811 |
+
return apply_filters( 'tutor_course/single/material_includes', $array, $course_id );
|
812 |
+
}
|
813 |
}
|
814 |
|
815 |
+
if ( ! function_exists( 'tutor_course_material_includes_html' ) ) {
|
816 |
+
function tutor_course_material_includes_html( $echo = true ) {
|
817 |
+
ob_start();
|
818 |
+
tutor_load_template( 'single.course.material-includes' );
|
819 |
+
$output = apply_filters( 'tutor_course/single/material_includes', ob_get_clean() );
|
820 |
|
821 |
+
if ( $echo ) {
|
822 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
823 |
+
}
|
824 |
+
return $output;
|
825 |
+
}
|
826 |
}
|
827 |
|
828 |
+
// tutor_course_material_includes_html
|
829 |
|
830 |
|
831 |
+
if ( ! function_exists( 'tutor_course_instructors_html' ) ) {
|
832 |
+
function tutor_course_instructors_html( $echo = true ) {
|
833 |
+
$display_course_instructors = tutor_utils()->get_option( 'display_course_instructors' );
|
834 |
+
if ( ! $display_course_instructors ) {
|
835 |
+
return null;
|
836 |
+
}
|
837 |
|
838 |
+
ob_start();
|
839 |
+
tutor_load_template( 'single.course.instructors' );
|
840 |
+
$output = apply_filters( 'tutor_course/single/instructors_html', ob_get_clean() );
|
841 |
|
842 |
+
if ( $echo ) {
|
843 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
844 |
+
}
|
845 |
+
return $output;
|
846 |
+
}
|
847 |
}
|
848 |
|
849 |
+
if ( ! function_exists( 'tutor_course_target_reviews_html' ) ) {
|
850 |
+
function tutor_course_target_reviews_html( $echo = true ) {
|
851 |
+
ob_start();
|
852 |
+
tutor_load_template( 'single.course.reviews' );
|
853 |
+
$output = apply_filters( 'tutor_course/single/reviews_html', ob_get_clean() );
|
854 |
|
855 |
+
if ( $echo ) {
|
856 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
857 |
+
}
|
858 |
+
return $output;
|
859 |
+
}
|
860 |
}
|
861 |
|
862 |
+
if ( ! function_exists( 'tutor_course_target_review_form_html' ) ) {
|
863 |
+
function tutor_course_target_review_form_html( $echo = true ) {
|
864 |
+
$isDisableReview = (bool) tutils()->get_option( 'disable_course_review' );
|
865 |
+
if ( $isDisableReview ) {
|
866 |
+
$output = apply_filters( 'tutor_review_disabled_text', '' );
|
867 |
|
868 |
+
if ( $echo ) {
|
869 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
870 |
+
}
|
871 |
+
return $output;
|
872 |
+
}
|
873 |
|
874 |
+
ob_start();
|
875 |
+
tutor_load_template( 'single.course.review-form' );
|
876 |
+
$output = apply_filters( 'tutor_course/single/reviews_form', ob_get_clean() );
|
877 |
|
878 |
+
if ( $echo ) {
|
879 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
880 |
+
}
|
881 |
+
return $output;
|
882 |
+
}
|
883 |
}
|
884 |
|
885 |
/**
|
891 |
*
|
892 |
* @since: v.1.0.0
|
893 |
*/
|
894 |
+
if ( ! function_exists( 'tutor_course_content' ) ) {
|
895 |
+
function tutor_course_content( $echo = true ) {
|
896 |
+
ob_start();
|
897 |
+
tutor_load_template( 'single.course.course-content' );
|
898 |
+
$output = apply_filters( 'tutor_course/single/content', ob_get_clean() );
|
899 |
|
900 |
+
if ( $echo ) {
|
901 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
902 |
+
}
|
903 |
|
904 |
+
return $output;
|
905 |
+
}
|
906 |
}
|
907 |
|
908 |
/**
|
910 |
*
|
911 |
* @since: v.1.0.0
|
912 |
*/
|
913 |
+
if ( ! function_exists( 'tutor_course_lead_info' ) ) {
|
914 |
+
function tutor_course_lead_info( $echo = true ) {
|
915 |
+
ob_start();
|
916 |
+
|
917 |
+
// exit('failed');
|
918 |
+
|
919 |
+
$course_id = get_the_ID();
|
920 |
+
$course_post_type = tutor()->course_post_type;
|
921 |
+
$queryCourse = new WP_Query(
|
922 |
+
array(
|
923 |
+
'p' => $course_id,
|
924 |
+
'post_type' => $course_post_type,
|
925 |
+
)
|
926 |
+
);
|
927 |
+
|
928 |
+
if ( $queryCourse->have_posts() ) {
|
929 |
+
while ( $queryCourse->have_posts() ) {
|
930 |
+
$queryCourse->the_post();
|
931 |
+
tutor_load_template( 'single.course.lead-info' );
|
932 |
+
}
|
933 |
+
wp_reset_postdata();
|
934 |
+
}
|
935 |
+
|
936 |
+
$output = apply_filters( 'tutor_course/single/lead_info', ob_get_clean() );
|
937 |
+
|
938 |
+
if ( $echo ) {
|
939 |
+
echo $output;
|
940 |
+
}
|
941 |
+
return $output;
|
942 |
+
}
|
943 |
}
|
944 |
|
945 |
/**
|
948 |
* @return mixed|void
|
949 |
*/
|
950 |
|
951 |
+
if ( ! function_exists( 'tutor_course_enrolled_lead_info' ) ) {
|
952 |
+
function tutor_course_enrolled_lead_info( $echo = true ) {
|
953 |
+
ob_start();
|
954 |
+
|
955 |
+
$course_id = get_the_ID();
|
956 |
+
$course_post_type = tutor()->course_post_type;
|
957 |
+
$queryCourse = new WP_Query(
|
958 |
+
array(
|
959 |
+
'p' => $course_id,
|
960 |
+
'post_type' => $course_post_type,
|
961 |
+
)
|
962 |
+
);
|
963 |
+
|
964 |
+
if ( $queryCourse->have_posts() ) {
|
965 |
+
while ( $queryCourse->have_posts() ) {
|
966 |
+
$queryCourse->the_post();
|
967 |
+
tutor_load_template( 'single.course.enrolled.lead-info' );
|
968 |
+
}
|
969 |
+
wp_reset_postdata();
|
970 |
+
}
|
971 |
+
|
972 |
+
$output = apply_filters( 'tutor_course/single/enrolled/lead_info', ob_get_clean() );
|
973 |
+
|
974 |
+
if ( $echo ) {
|
975 |
+
echo $output;
|
976 |
+
}
|
977 |
+
|
978 |
+
return $output;
|
979 |
+
}
|
980 |
+
}
|
981 |
+
|
982 |
+
if ( ! function_exists( 'tutor_lesson_lead_info' ) ) {
|
983 |
+
function tutor_lesson_lead_info( $lesson_id = 0, $echo = true ) {
|
984 |
+
if ( ! $lesson_id ) {
|
985 |
+
$lesson_id = get_the_ID();
|
986 |
+
}
|
987 |
+
|
988 |
+
ob_start();
|
989 |
+
$course_id = tutor_utils()->get_course_id_by( 'lesson', $lesson_id );
|
990 |
+
$course_post_type = tutor()->course_post_type;
|
991 |
+
$queryCourse = new WP_Query(
|
992 |
+
array(
|
993 |
+
'p' => $course_id,
|
994 |
+
'post_type' => $course_post_type,
|
995 |
+
)
|
996 |
+
);
|
997 |
+
|
998 |
+
if ( $queryCourse->have_posts() ) {
|
999 |
+
while ( $queryCourse->have_posts() ) {
|
1000 |
+
$queryCourse->the_post();
|
1001 |
+
tutor_load_template( 'single.course.enrolled.lead-info' );
|
1002 |
+
}
|
1003 |
+
wp_reset_postdata();
|
1004 |
+
}
|
1005 |
+
$output = apply_filters( 'tutor_course/single/enrolled/lead_info', ob_get_clean() );
|
1006 |
+
|
1007 |
+
if ( $echo ) {
|
1008 |
+
echo $output;
|
1009 |
+
}
|
1010 |
+
|
1011 |
+
return $output;
|
1012 |
+
|
1013 |
+
}
|
1014 |
}
|
1015 |
/**
|
1016 |
* @param bool $echo
|
1022 |
* @since: v.1.0.0
|
1023 |
*/
|
1024 |
|
1025 |
+
if ( ! function_exists( 'tutor_course_enroll_box' ) ) {
|
1026 |
+
function tutor_course_enroll_box( $echo = true ) {
|
1027 |
+
$isLoggedIn = is_user_logged_in();
|
1028 |
+
$enrolled = tutor_utils()->is_enrolled();
|
1029 |
|
1030 |
+
$is_administrator = current_user_can( 'administrator' );
|
1031 |
+
$is_instructor = tutor_utils()->is_instructor_of_this_course();
|
1032 |
+
$course_content_access = (bool) get_tutor_option( 'course_content_access_for_ia' );
|
1033 |
+
ob_start();
|
1034 |
|
1035 |
+
if ( $enrolled ) {
|
1036 |
+
tutor_load_template( 'single.course.course-enrolled-box' );
|
1037 |
+
$output = apply_filters( 'tutor_course/single/enrolled', ob_get_clean() );
|
1038 |
+
} elseif ( $course_content_access && ( $is_administrator || $is_instructor ) ) {
|
1039 |
+
tutor_load_template( 'single.course.continue-lesson' );
|
1040 |
+
$output = apply_filters( 'tutor_course/single/continue_lesson', ob_get_clean() );
|
1041 |
+
} else {
|
1042 |
+
tutor_load_template( 'single.course.course-enroll-box' );
|
1043 |
+
$output = apply_filters( 'tutor_course/single/enroll', ob_get_clean() );
|
1044 |
+
}
|
1045 |
|
1046 |
+
if ( $echo ) {
|
1047 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1048 |
+
}
|
1049 |
|
1050 |
+
return $output;
|
1051 |
+
}
|
1052 |
}
|
1053 |
|
1054 |
/**
|
1059 |
* Get Only add to cart form
|
1060 |
*/
|
1061 |
|
1062 |
+
function tutor_single_course_add_to_cart( $echo = true ) {
|
1063 |
+
ob_start();
|
1064 |
+
|
1065 |
+
$isLoggedIn = is_user_logged_in();
|
1066 |
+
$output = '';
|
1067 |
|
1068 |
+
$template = tutor_utils()->is_course_fully_booked( null ) ? 'closed-enrollment' : 'add-to-cart';
|
|
|
1069 |
|
1070 |
+
tutor_load_template( 'single.course.' . $template );
|
1071 |
+
$output .= apply_filters( 'tutor_course/single/' . $template, ob_get_clean() );
|
|
|
|
|
1072 |
|
1073 |
+
if ( ! $isLoggedIn ) {
|
1074 |
+
ob_start();
|
1075 |
+
tutor_load_template( 'single.course.login' );
|
1076 |
+
$login_form = apply_filters( 'tutor_course/global/login', ob_get_clean() );
|
1077 |
|
1078 |
+
$output .= '<div class="tutor-cart-box-login-form" style="display: none;"><span class="login-overlay-close"></span><div class="tutor-cart-box-login-form-inner"><button class="tutor-popup-form-close tutor-icon-line-cross"></button>' . $login_form . '</div></div>';
|
1079 |
+
}
|
1080 |
|
1081 |
+
if ( $echo ) {
|
1082 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1083 |
+
}
|
1084 |
|
1085 |
+
return $output;
|
1086 |
}
|
1087 |
|
1088 |
+
if ( ! function_exists( 'tutor_course_enrolled_nav' ) ) {
|
1089 |
+
function tutor_course_enrolled_nav( $echo = true ) {
|
1090 |
+
$course_post_type = tutor()->course_post_type;
|
1091 |
+
$lesson_post_type = tutor()->lesson_post_type;
|
1092 |
|
1093 |
+
ob_start();
|
1094 |
+
global $post;
|
1095 |
|
1096 |
+
if ( ! empty( $post->post_type ) && $post->post_type === $course_post_type ) {
|
1097 |
+
tutor_load_template( 'single.course.enrolled.nav' );
|
1098 |
+
} elseif ( ! empty( $post->post_type ) && $post->post_type === $lesson_post_type ) {
|
1099 |
+
$lesson_id = get_the_ID();
|
1100 |
+
$course_id = tutor_utils()->get_course_id_by( 'lesson', $lesson_id );
|
1101 |
|
1102 |
+
$course_post_type = tutor()->course_post_type;
|
1103 |
+
$queryCourse = new WP_Query(
|
1104 |
+
array(
|
1105 |
+
'p' => $course_id,
|
1106 |
+
'post_type' => $course_post_type,
|
1107 |
+
)
|
1108 |
+
);
|
1109 |
|
1110 |
+
if ( $queryCourse->have_posts() ) {
|
1111 |
+
while ( $queryCourse->have_posts() ) {
|
1112 |
+
$queryCourse->the_post();
|
1113 |
+
tutor_load_template( 'single.course.enrolled.nav' );
|
1114 |
+
}
|
1115 |
+
wp_reset_postdata();
|
1116 |
+
}
|
1117 |
+
}
|
1118 |
+
$output = apply_filters( 'tutor_course/single/enrolled/nav', ob_get_clean() );
|
1119 |
|
1120 |
+
if ( $echo ) {
|
1121 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1122 |
+
}
|
1123 |
+
return $output;
|
1124 |
+
}
|
1125 |
}
|
1126 |
|
1127 |
+
if ( ! function_exists( 'tutor_course_video' ) ) {
|
1128 |
+
function tutor_course_video( $echo = true ) {
|
1129 |
+
ob_start();
|
1130 |
+
tutor_load_template( 'single.video.video' );
|
1131 |
+
$output = apply_filters( 'tutor_course/single/video', ob_get_clean() );
|
1132 |
|
1133 |
+
if ( $echo ) {
|
1134 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1135 |
+
}
|
1136 |
+
return $output;
|
1137 |
+
}
|
1138 |
}
|
1139 |
|
1140 |
+
if ( ! function_exists( 'tutor_lesson_video' ) ) {
|
1141 |
+
function tutor_lesson_video( $echo = true ) {
|
1142 |
+
ob_start();
|
1143 |
+
tutor_load_template( 'single.video.video' );
|
1144 |
+
$output = apply_filters( 'tutor_lesson/single/video', ob_get_clean() );
|
1145 |
|
1146 |
+
if ( $echo ) {
|
1147 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1148 |
+
}
|
1149 |
+
return $output;
|
1150 |
+
}
|
1151 |
}
|
1152 |
|
1153 |
/**
|
1160 |
*
|
1161 |
* @since v.1.0.0
|
1162 |
*/
|
1163 |
+
if ( ! function_exists( 'get_tutor_posts_attachments' ) ) {
|
1164 |
+
function get_tutor_posts_attachments( $echo = true ) {
|
1165 |
+
ob_start();
|
1166 |
+
tutor_load_template( 'global.attachments' );
|
1167 |
+
$output = apply_filters( 'tutor_lesson/single/attachments', ob_get_clean() );
|
1168 |
|
1169 |
+
if ( $echo ) {
|
1170 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1171 |
+
}
|
1172 |
+
return $output;
|
1173 |
+
}
|
1174 |
}
|
1175 |
|
1176 |
/**
|
1182 |
*
|
1183 |
* @since v.1.0.0
|
1184 |
*/
|
1185 |
+
if ( ! function_exists( 'tutor_lessons_sidebar' ) ) {
|
1186 |
+
function tutor_lessons_sidebar( $echo = true ) {
|
1187 |
+
ob_start();
|
1188 |
+
tutor_load_template( 'single.lesson.lesson_sidebar' );
|
1189 |
+
$output = apply_filters( 'tutor_lesson/single/lesson_sidebar', ob_get_clean() );
|
1190 |
|
1191 |
+
if ( $echo ) {
|
1192 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1193 |
+
}
|
1194 |
|
1195 |
+
return $output;
|
1196 |
+
}
|
1197 |
}
|
1198 |
|
1199 |
/**
|
1204 |
* Render Lesson Main Content
|
1205 |
* @since v.1.0.0
|
1206 |
*/
|
1207 |
+
if ( ! function_exists( 'tutor_lesson_content' ) ) {
|
1208 |
+
function tutor_lesson_content( $echo = true ) {
|
1209 |
+
ob_start();
|
1210 |
+
tutor_load_template( 'single.lesson.content' );
|
1211 |
+
$output = apply_filters( 'tutor_lesson/single/content', ob_get_clean() );
|
1212 |
|
1213 |
+
if ( $echo ) {
|
1214 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1215 |
+
}
|
1216 |
|
1217 |
+
return $output;
|
1218 |
+
}
|
1219 |
}
|
1220 |
|
1221 |
+
if ( ! function_exists( 'tutor_lesson_mark_complete_html' ) ) {
|
1222 |
+
function tutor_lesson_mark_complete_html( $echo = true ) {
|
1223 |
+
ob_start();
|
1224 |
+
tutor_load_template( 'single.lesson.complete_form' );
|
1225 |
+
$output = apply_filters( 'tutor_lesson/single/complete_form', ob_get_clean() );
|
1226 |
|
1227 |
+
if ( $echo ) {
|
1228 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1229 |
+
}
|
1230 |
|
1231 |
+
return $output;
|
1232 |
+
}
|
1233 |
}
|
1234 |
|
1235 |
+
if ( ! function_exists( 'tutor_course_mark_complete_html' ) ) {
|
1236 |
+
function tutor_course_mark_complete_html( $echo = true ) {
|
1237 |
+
ob_start();
|
1238 |
+
tutor_load_template( 'single.course.complete_form' );
|
1239 |
+
$output = apply_filters( 'tutor_course/single/complete_form', ob_get_clean() );
|
1240 |
|
1241 |
+
if ( $echo ) {
|
1242 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1243 |
+
}
|
1244 |
|
1245 |
+
return $output;
|
1246 |
+
}
|
1247 |
}
|
1248 |
|
1249 |
|
1257 |
* @since v.1.0.0
|
1258 |
*/
|
1259 |
|
1260 |
+
if ( ! function_exists( 'tutor_course_completing_progress_bar' ) ) {
|
1261 |
+
function tutor_course_completing_progress_bar( $echo = true ) {
|
1262 |
+
ob_start();
|
1263 |
+
tutor_load_template( 'single.course.enrolled.completing-progress' );
|
1264 |
+
$output = apply_filters( 'tutor_course/single/completing-progress-bar', ob_get_clean() );
|
1265 |
|
1266 |
+
if ( $echo ) {
|
1267 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1268 |
+
}
|
1269 |
|
1270 |
+
return $output;
|
1271 |
+
}
|
1272 |
}
|
1273 |
|
1274 |
+
function tutor_course_question_and_answer( $echo = true ) {
|
1275 |
+
ob_start();
|
1276 |
+
tutor_load_template( 'single.course.enrolled.question_and_answer' );
|
1277 |
+
$output = apply_filters( 'tutor_course/single/question_and_answer', ob_get_clean() );
|
1278 |
|
1279 |
+
if ( $echo ) {
|
1280 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1281 |
+
}
|
1282 |
|
1283 |
+
return $output;
|
1284 |
}
|
1285 |
|
1286 |
|
1287 |
+
function tutor_course_announcements( $echo = true ) {
|
1288 |
+
ob_start();
|
1289 |
+
tutor_load_template( 'single.course.enrolled.announcements' );
|
1290 |
+
$output = apply_filters( 'tutor_course/single/announcements', ob_get_clean() );
|
1291 |
|
1292 |
+
if ( $echo ) {
|
1293 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1294 |
+
}
|
1295 |
|
1296 |
+
return $output;
|
1297 |
}
|
1298 |
|
1299 |
+
function tutor_single_quiz_top( $echo = true ) {
|
1300 |
+
ob_start();
|
1301 |
+
tutor_load_template( 'single.quiz.top' );
|
1302 |
+
$output = apply_filters( 'tutor_single_quiz/top', ob_get_clean() );
|
1303 |
|
1304 |
+
if ( $echo ) {
|
1305 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1306 |
+
}
|
1307 |
+
return $output;
|
1308 |
}
|
1309 |
|
1310 |
+
function tutor_single_quiz_body( $echo = true ) {
|
1311 |
+
ob_start();
|
1312 |
+
tutor_load_template( 'single.quiz.body' );
|
1313 |
+
$output = apply_filters( 'tutor_single_quiz/body', ob_get_clean() );
|
1314 |
|
1315 |
+
if ( $echo ) {
|
1316 |
+
echo $output;
|
1317 |
+
}
|
1318 |
+
return $output;
|
1319 |
}
|
1320 |
|
1321 |
/**
|
1325 |
*
|
1326 |
* Get the quiz description
|
1327 |
*/
|
1328 |
+
function tutor_single_quiz_content( $echo = true ) {
|
1329 |
+
ob_start();
|
1330 |
+
tutor_load_template( 'single.quiz.content' );
|
1331 |
+
$output = apply_filters( 'tutor_single_quiz/content', ob_get_clean() );
|
1332 |
|
1333 |
+
if ( $echo ) {
|
1334 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1335 |
+
}
|
1336 |
+
return $output;
|
1337 |
}
|
1338 |
|
1339 |
|
1340 |
+
function tutor_single_quiz_no_course_belongs( $echo = true ) {
|
1341 |
+
ob_start();
|
1342 |
+
tutor_load_template( 'single.quiz.no_course_belongs' );
|
1343 |
+
$output = apply_filters( 'tutor_single_quiz/no_course_belongs', ob_get_clean() );
|
1344 |
|
1345 |
+
if ( $echo ) {
|
1346 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1347 |
+
}
|
1348 |
+
return $output;
|
1349 |
}
|
1350 |
|
1351 |
+
function single_quiz_contents( $echo = true ) {
|
1352 |
|
1353 |
+
ob_start();
|
1354 |
+
tutor_load_template( 'single.quiz.single_quiz_contents' );
|
1355 |
+
$output = apply_filters( 'tutor_single_quiz/single_quiz_contents', ob_get_clean() );
|
1356 |
|
1357 |
+
if ( $echo ) {
|
1358 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1359 |
+
}
|
1360 |
+
return $output;
|
1361 |
}
|
1362 |
|
1363 |
+
function get_tutor_course_level( $course_id = 0 ) {
|
1364 |
+
if ( ! $course_id ) {
|
1365 |
+
$course_id = get_the_ID();
|
1366 |
+
}
|
1367 |
+
if ( ! $course_id ) {
|
1368 |
+
return '';
|
1369 |
+
}
|
1370 |
|
1371 |
+
$course_level = get_post_meta( $course_id, '_tutor_course_level', true );
|
1372 |
|
1373 |
+
if ( $course_level ) {
|
1374 |
+
return tutor_utils()->course_levels( $course_level );
|
1375 |
+
}
|
1376 |
+
return false;
|
1377 |
}
|
1378 |
|
1379 |
+
if ( ! function_exists( 'get_tutor_course_duration_context' ) ) {
|
1380 |
+
function get_tutor_course_duration_context( $course_id = 0 ) {
|
1381 |
+
if ( ! $course_id ) {
|
1382 |
+
$course_id = get_the_ID();
|
1383 |
+
}
|
1384 |
+
if ( ! $course_id ) {
|
1385 |
+
return '';
|
1386 |
+
}
|
1387 |
+
$duration = get_post_meta( $course_id, '_course_duration', true );
|
1388 |
+
$durationHours = tutor_utils()->avalue_dot( 'hours', $duration );
|
1389 |
+
$durationMinutes = tutor_utils()->avalue_dot( 'minutes', $duration );
|
1390 |
+
$durationSeconds = tutor_utils()->avalue_dot( 'seconds', $duration );
|
1391 |
|
1392 |
+
if ( $duration ) {
|
1393 |
+
$output = '';
|
1394 |
+
if ( $durationHours > 0 ) {
|
1395 |
+
$output .= $durationHours . 'h ';
|
1396 |
+
}
|
1397 |
|
1398 |
+
if ( $durationMinutes > 0 ) {
|
1399 |
+
$output .= $durationMinutes . 'm ';
|
1400 |
+
}
|
1401 |
|
1402 |
+
if ( $durationSeconds > 0 ) {
|
1403 |
+
$output .= $durationSeconds . 's ';
|
1404 |
+
}
|
1405 |
|
1406 |
+
return $output;
|
1407 |
+
}
|
1408 |
|
1409 |
+
return false;
|
1410 |
+
}
|
1411 |
}
|
1412 |
+
if ( ! function_exists( 'get_tutor_course_categories' ) ) {
|
1413 |
+
function get_tutor_course_categories( $course_id = 0 ) {
|
1414 |
+
if ( ! $course_id ) {
|
1415 |
+
$course_id = get_the_ID();
|
1416 |
+
}
|
1417 |
+
$terms = get_the_terms( $course_id, 'course-category' );
|
1418 |
|
1419 |
+
return $terms;
|
1420 |
+
}
|
1421 |
}
|
1422 |
|
1423 |
/**
|
1428 |
* Get course tags
|
1429 |
*/
|
1430 |
|
1431 |
+
if ( ! function_exists( 'get_tutor_course_tags' ) ) {
|
1432 |
+
function get_tutor_course_tags( $course_id = 0 ) {
|
1433 |
+
if ( ! $course_id ) {
|
1434 |
+
$course_id = get_the_ID();
|
1435 |
+
}
|
1436 |
+
$terms = get_the_terms( $course_id, 'course-tag' );
|
1437 |
|
1438 |
+
return $terms;
|
1439 |
+
}
|
1440 |
}
|
1441 |
|
1442 |
/**
|
1447 |
* Template for course tags html
|
1448 |
*/
|
1449 |
|
1450 |
+
if ( ! function_exists( 'tutor_course_tags_html' ) ) {
|
1451 |
+
function tutor_course_tags_html( $echo = true ) {
|
1452 |
+
ob_start();
|
1453 |
+
tutor_load_template( 'single.course.tags' );
|
1454 |
+
$output = apply_filters( 'tutor_course/single/tags_html', ob_get_clean() );
|
1455 |
|
1456 |
+
if ( $echo ) {
|
1457 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1458 |
+
}
|
1459 |
|
1460 |
+
return $output;
|
1461 |
+
}
|
1462 |
}
|
1463 |
|
1464 |
/**
|
1469 |
* Get Q&A in lesson sidebar
|
1470 |
*/
|
1471 |
|
1472 |
+
if ( ! function_exists( 'tutor_lesson_sidebar_question_and_answer' ) ) {
|
1473 |
+
function tutor_lesson_sidebar_question_and_answer( $echo = true ) {
|
1474 |
+
ob_start();
|
1475 |
+
tutor_load_template( 'single.lesson.sidebar_question_and_answer' );
|
1476 |
+
$output = apply_filters( 'tutor_lesson/single/sidebar_question_and_answer', ob_get_clean() );
|
1477 |
|
1478 |
+
if ( $echo ) {
|
1479 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1480 |
+
}
|
1481 |
|
1482 |
+
return $output;
|
1483 |
+
}
|
1484 |
}
|
1485 |
|
1486 |
/**
|
1491 |
* Get Social Share button to share on social media
|
1492 |
*/
|
1493 |
|
1494 |
+
if ( ! function_exists( 'tutor_social_share' ) ) {
|
1495 |
+
function tutor_social_share( $echo = true ) {
|
1496 |
|
1497 |
+
$output = '';
|
1498 |
+
$tutor_social_share_icons = tutor_utils()->tutor_social_share_icons();
|
1499 |
|
1500 |
+
if ( tutor_utils()->count( $tutor_social_share_icons ) ) {
|
1501 |
+
ob_start();
|
1502 |
+
tutor_load_template( 'single.course.social_share', array( 'tutor_social_share_icons' => $tutor_social_share_icons ) );
|
1503 |
+
$output = apply_filters( 'tutor_course/single/social_share', ob_get_clean() );
|
1504 |
+
}
|
1505 |
|
1506 |
+
if ( $echo && $output != '' ) {
|
1507 |
+
echo '<span>' . __( 'Share:', 'tutor' ) . '</span>';
|
1508 |
+
echo $output;
|
1509 |
+
}
|
1510 |
|
1511 |
+
return $output;
|
1512 |
+
}
|
1513 |
}
|
1514 |
|
1515 |
/**
|
1522 |
* @since v.1.3.3
|
1523 |
*/
|
1524 |
|
1525 |
+
if ( ! function_exists( 'tutor_assignment_content' ) ) {
|
1526 |
+
function tutor_assignment_content( $echo = true ) {
|
1527 |
+
ob_start();
|
1528 |
+
tutor_load_template( 'single.assignment.content' );
|
1529 |
+
$output = apply_filters( 'tutor_assignment/single/content', ob_get_clean() );
|
1530 |
|
1531 |
+
if ( $echo ) {
|
1532 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1533 |
+
}
|
1534 |
|
1535 |
+
return $output;
|
1536 |
+
}
|
1537 |
}
|
1538 |
|
1539 |
/**
|
1546 |
* @since v.1.4.0
|
1547 |
*/
|
1548 |
|
1549 |
+
if ( ! function_exists( 'get_tnotice' ) ) {
|
1550 |
+
function get_tnotice( $msg = '', $title = 'Success', $type = 'success' ) {
|
1551 |
|
1552 |
+
$output = '<div class="tnotice tnotice--' . $type . '">
|
1553 |
<div class="tnotice__icon">¡</div>
|
1554 |
<div class="tnotice__content">';
|
1555 |
|
1556 |
+
if ( $title ) {
|
1557 |
+
$output .= '<p class="tnotice__type">' . $title . '</p>';
|
1558 |
+
}
|
1559 |
+
$output .= '<p class="tnotice__message">' . $msg . '</p>
|
1560 |
</div>
|
1561 |
</div>';
|
1562 |
|
1563 |
+
return $output;
|
1564 |
+
}
|
1565 |
}
|
1566 |
|
1567 |
/**
|
1568 |
+
* @param int $course_content_id
|
1569 |
* @param bool $echo
|
1570 |
*
|
1571 |
* @return mixed|void
|
1575 |
* @since v.1.4.7
|
1576 |
*/
|
1577 |
|
1578 |
+
function tutor_next_previous_pagination( $course_content_id = 0, $echo = true ) {
|
1579 |
+
$content_id = tutils()->get_post_id( $course_content_id );
|
1580 |
+
$contents = tutils()->get_course_prev_next_contents_by_id( $content_id );
|
1581 |
+
$previous_id = $contents->previous_id;
|
1582 |
+
$next_id = $contents->next_id;
|
1583 |
|
1584 |
+
ob_start();
|
1585 |
+
do_action( 'tutor_lesson_next_previous_pagination_before' );
|
1586 |
+
tutor_load_template( 'single.next-previous-pagination', compact( 'previous_id', 'next_id' ) );
|
1587 |
+
do_action( 'tutor_lesson_next_previous_pagination_after' );
|
1588 |
+
$output = apply_filters( 'tutor/single/next_previous_pagination', ob_get_clean() );
|
1589 |
|
1590 |
+
if ( $echo ) {
|
1591 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1592 |
+
}
|
1593 |
|
1594 |
+
return $output;
|
1595 |
}
|
1596 |
|
1597 |
|
1598 |
/**
|
1599 |
* Required login form in archive page
|
1600 |
+
*
|
1601 |
* @param bool $echo
|
1602 |
* @since v 1.5.5
|
1603 |
*
|
1604 |
* @todo, it will be remove from 2.0.0
|
1605 |
*/
|
1606 |
+
function tutor_archive_course_add_to_cart( $echo = true ) {
|
1607 |
+
_deprecated_function( __FUNCTION__, '1.5.8' );
|
1608 |
|
1609 |
+
$output = '';
|
1610 |
+
if ( $echo ) {
|
1611 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1612 |
+
}
|
1613 |
+
return $output;
|
1614 |
}
|
1615 |
|
1616 |
/**
|
1622 |
* @since v.1.5.8
|
1623 |
*/
|
1624 |
|
1625 |
+
if ( ! function_exists( 'tutor_login_form_popup' ) ) {
|
1626 |
+
function tutor_login_form_popup( $echo = true ) {
|
1627 |
+
$output = '';
|
1628 |
+
ob_start();
|
1629 |
+
tutor_load_template( 'single.course.login' );
|
1630 |
+
$login_form = apply_filters( 'tutor_course/global/login', ob_get_clean() );
|
1631 |
+
$output .= '<div class="tutor-cart-box-login-form" style="display: none;"><span class="login-overlay-close"></span><div class="tutor-cart-box-login-form-inner"><button class="tutor-popup-form-close tutor-icon-line-cross"></button>' . $login_form . '</div></div>';
|
1632 |
|
1633 |
+
$output = apply_filters( 'tutor_login_form_popup_html', $output );
|
1634 |
|
1635 |
+
if ( $echo ) {
|
1636 |
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
1637 |
+
}
|
1638 |
+
return $output;
|
1639 |
+
}
|
1640 |
}
|
1641 |
|
1642 |
/**
|
1643 |
* Load custom template from any given file
|
1644 |
+
*
|
1645 |
* Pass parameter as wish
|
1646 |
+
*
|
1647 |
* @since 1.9.8
|
1648 |
*/
|
1649 |
+
if ( ! function_exists( 'tutor_load_template_from_custom_path' ) ) {
|
1650 |
+
function tutor_load_template_from_custom_path( $template = null, $data = array() ) {
|
1651 |
+
do_action( 'tutor_load_template_from_custom_path_before', $template, $data );
|
1652 |
+
if ( file_exists( $template ) ) {
|
1653 |
+
include_once $template;
|
1654 |
+
}
|
1655 |
+
do_action( 'tutor_load_template_from_custom_path_after', $template, $data );
|
1656 |
+
}
|
1657 |
+
}
|
languages/tutor.pot
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# Copyright (C)
|
2 |
# This file is distributed under the same license as the Tutor LMS package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
@@ -17,95 +17,95 @@ msgstr ""
|
|
17 |
msgid "Tutor Instructor"
|
18 |
msgstr ""
|
19 |
|
20 |
-
#: classes/Addons.php:
|
21 |
msgid "BuddyPress"
|
22 |
msgstr ""
|
23 |
|
24 |
-
#: classes/Addons.php:
|
25 |
msgid "Gradebook"
|
26 |
msgstr ""
|
27 |
|
28 |
-
#: classes/Addons.php:
|
29 |
msgid "Content Drip"
|
30 |
msgstr ""
|
31 |
|
32 |
-
#: classes/Addons.php:
|
33 |
msgid "Enrollments"
|
34 |
msgstr ""
|
35 |
|
36 |
-
#: classes/Addons.php:
|
37 |
msgid "WooCommerce Subscriptions"
|
38 |
msgstr ""
|
39 |
|
40 |
-
#: classes/Addons.php:
|
41 |
msgid "Paid Memberships Pro"
|
42 |
msgstr ""
|
43 |
|
44 |
-
#: classes/Addons.php:
|
45 |
msgid "Restrict Content Pro"
|
46 |
msgstr ""
|
47 |
|
48 |
-
#: classes/Addons.php:
|
49 |
msgid "Tutor Assignments"
|
50 |
msgstr ""
|
51 |
|
52 |
-
#: classes/Addons.php:
|
53 |
msgid "Tutor Certificate"
|
54 |
msgstr ""
|
55 |
|
56 |
-
#: classes/Addons.php:
|
57 |
msgid "Tutor Course Attachments"
|
58 |
msgstr ""
|
59 |
|
60 |
-
#: classes/Addons.php:
|
61 |
msgid "Tutor Course Preview"
|
62 |
msgstr ""
|
63 |
|
64 |
-
#: classes/Addons.php:
|
65 |
msgid "Tutor E-Mail"
|
66 |
msgstr ""
|
67 |
|
68 |
-
#: classes/Addons.php:
|
69 |
msgid "Tutor Multi Instructors"
|
70 |
msgstr ""
|
71 |
|
72 |
-
#: classes/Addons.php:
|
73 |
msgid "Tutor Prerequisites"
|
74 |
msgstr ""
|
75 |
|
76 |
-
#: classes/Addons.php:
|
77 |
msgid "Tutor Report"
|
78 |
msgstr ""
|
79 |
|
80 |
-
#: classes/Addons.php:
|
81 |
msgid "Quiz Export/Import"
|
82 |
msgstr ""
|
83 |
|
84 |
-
#: classes/Addons.php:
|
85 |
msgid "Save time by exporting/importing quiz data with easy options."
|
86 |
msgstr ""
|
87 |
|
88 |
-
#: classes/Addons.php:
|
89 |
msgid "Tutor Zoom Integration"
|
90 |
msgstr ""
|
91 |
|
92 |
-
#: classes/Addons.php:
|
93 |
msgid "Connect Tutor LMS with Zoom to host live online classes. Students can attend live classes right from the lesson page."
|
94 |
msgstr ""
|
95 |
|
96 |
-
#: classes/Addons.php:
|
97 |
msgid "Google Classroom Integration"
|
98 |
msgstr ""
|
99 |
|
100 |
-
#: classes/Addons.php:
|
101 |
msgid "Helps connect Google Classrooms with Tutor LMS courses, allowing you to use features like Classroom streams and files directly from the Tutor LMS course."
|
102 |
msgstr ""
|
103 |
|
104 |
-
#: classes/Addons.php:
|
105 |
msgid "WPML Multilingual CMS"
|
106 |
msgstr ""
|
107 |
|
108 |
-
#: classes/Addons.php:
|
109 |
msgid "Create multilingual courses, lessons, dashboard and more for a global audience."
|
110 |
msgstr ""
|
111 |
|
@@ -117,7 +117,7 @@ msgstr ""
|
|
117 |
msgid "Tutor LMS"
|
118 |
msgstr ""
|
119 |
|
120 |
-
#: classes/Admin.php:56, classes/Admin.php:56, templates/single/course/lead-info.php:
|
121 |
msgid "Categories"
|
122 |
msgstr ""
|
123 |
|
@@ -125,15 +125,15 @@ msgstr ""
|
|
125 |
msgid "Tags"
|
126 |
msgstr ""
|
127 |
|
128 |
-
#: classes/Admin.php:60, classes/Admin.php:60, classes/Course.php:
|
129 |
msgid "Students"
|
130 |
msgstr ""
|
131 |
|
132 |
-
#: classes/Admin.php:63, classes/Admin.php:63, classes/Course.php:
|
133 |
msgid "Instructors"
|
134 |
msgstr ""
|
135 |
|
136 |
-
#: classes/Admin.php:66, classes/Admin.php:66, classes/Utils.php:
|
137 |
msgid "Announcements"
|
138 |
msgstr ""
|
139 |
|
@@ -145,7 +145,7 @@ msgstr ""
|
|
145 |
msgid "Q & A "
|
146 |
msgstr ""
|
147 |
|
148 |
-
#: classes/Admin.php:70, classes/Admin.php:70, classes/Utils.php:
|
149 |
msgid "Quiz Attempts"
|
150 |
msgstr ""
|
151 |
|
@@ -157,7 +157,7 @@ msgstr ""
|
|
157 |
msgid "Add-ons"
|
158 |
msgstr ""
|
159 |
|
160 |
-
#: classes/Admin.php:80, classes/Admin.php:80, classes/Admin.php:453, classes/Utils.php:
|
161 |
msgid "Settings"
|
162 |
msgstr ""
|
163 |
|
@@ -177,11 +177,11 @@ msgstr ""
|
|
177 |
msgid "Tutor Pages"
|
178 |
msgstr ""
|
179 |
|
180 |
-
#: classes/Admin.php:139, classes/Instructors_List.php:
|
181 |
msgid "Status"
|
182 |
msgstr ""
|
183 |
|
184 |
-
#: classes/Admin.php:245, templates/permission-denied.php:
|
185 |
msgid "Permission Denied"
|
186 |
msgstr ""
|
187 |
|
@@ -201,187 +201,187 @@ msgstr ""
|
|
201 |
msgid "If you like %1$s please leave us a %2$s rating. A huge thanks in advance!"
|
202 |
msgstr ""
|
203 |
|
204 |
-
#: classes/Ajax.php:
|
205 |
msgid "Access Denied"
|
206 |
msgstr ""
|
207 |
|
208 |
-
#: classes/Ajax.php:
|
209 |
msgid "Rating placed success"
|
210 |
msgstr ""
|
211 |
|
212 |
-
#: classes/Ajax.php:
|
213 |
msgid "Empty question title or body"
|
214 |
msgstr ""
|
215 |
|
216 |
-
#: classes/Ajax.php:
|
217 |
msgid "Question has been added successfully"
|
218 |
msgstr ""
|
219 |
|
220 |
-
#: classes/Ajax.php:
|
221 |
msgid "Please write answer"
|
222 |
msgstr ""
|
223 |
|
224 |
-
#: classes/Ajax.php:
|
225 |
msgid "Answer has been added successfully"
|
226 |
msgstr ""
|
227 |
|
228 |
-
#: classes/Ajax.php:
|
229 |
msgid "Course added to wish list"
|
230 |
msgstr ""
|
231 |
|
232 |
-
#: classes/Ajax.php:
|
233 |
msgid "Course removed from wish list"
|
234 |
msgstr ""
|
235 |
|
236 |
-
#: classes/Ajax.php:
|
237 |
msgid "ERROR:"
|
238 |
msgstr ""
|
239 |
|
240 |
-
#: classes/Ajax.php:
|
241 |
msgid "Username is required."
|
242 |
msgstr ""
|
243 |
|
244 |
-
#: classes/Ajax.php:
|
245 |
msgid "Announcement created successfully"
|
246 |
msgstr ""
|
247 |
|
248 |
-
#: classes/Ajax.php:
|
249 |
msgid "Announcement updated successfully"
|
250 |
msgstr ""
|
251 |
|
252 |
-
#: classes/Ajax.php:
|
253 |
msgid "Announcement creation failed"
|
254 |
msgstr ""
|
255 |
|
256 |
-
#: classes/Ajax.php:
|
257 |
msgid "Announcement update failed"
|
258 |
msgstr ""
|
259 |
|
260 |
-
#: classes/Ajax.php:
|
261 |
msgid "Course name required"
|
262 |
msgstr ""
|
263 |
|
264 |
-
#: classes/Ajax.php:
|
265 |
msgid "Announcement title required"
|
266 |
msgstr ""
|
267 |
|
268 |
-
#: classes/Ajax.php:
|
269 |
msgid "Announcement summary required"
|
270 |
msgstr ""
|
271 |
|
272 |
-
#: classes/Ajax.php:
|
273 |
msgid "Announcement delete failed"
|
274 |
msgstr ""
|
275 |
|
276 |
-
#: classes/Ajax.php:
|
277 |
msgid "Announcement deleted successfully"
|
278 |
msgstr ""
|
279 |
|
280 |
-
#: classes/Course.php:
|
281 |
msgid "Fully booked"
|
282 |
msgstr ""
|
283 |
|
284 |
-
#: classes/Course.php:
|
285 |
msgid "Course Builder"
|
286 |
msgstr ""
|
287 |
|
288 |
-
#: classes/Course.php:
|
289 |
msgid "Additional Data"
|
290 |
msgstr ""
|
291 |
|
292 |
-
#: classes/Course.php:
|
293 |
msgid "Video"
|
294 |
msgstr ""
|
295 |
|
296 |
-
#: classes/Course.php:
|
297 |
msgid "Tutor Settings"
|
298 |
msgstr ""
|
299 |
|
300 |
-
#: classes/Course.php:
|
301 |
msgid "Topic has been updated"
|
302 |
msgstr ""
|
303 |
|
304 |
-
#: classes/Course.php:
|
305 |
msgid "Lessons"
|
306 |
msgstr ""
|
307 |
|
308 |
-
#: classes/Course.php:
|
309 |
msgid "Price"
|
310 |
msgstr ""
|
311 |
|
312 |
-
#: classes/Course.php:
|
313 |
msgid "free"
|
314 |
msgstr ""
|
315 |
|
316 |
-
#: classes/Course.php:
|
317 |
msgid "Please Sign In first"
|
318 |
msgstr ""
|
319 |
|
320 |
-
#: classes/Course.php:
|
321 |
msgid "Please Sign-In"
|
322 |
msgstr ""
|
323 |
|
324 |
-
#: classes/Course.php:
|
325 |
-
msgid "
|
326 |
msgstr ""
|
327 |
|
328 |
-
#: classes/Course.php:
|
329 |
-
msgid "To add unlimited multiple instructors in your course, get %sTutor LMS Pro%s"
|
330 |
msgstr ""
|
331 |
|
332 |
-
#: classes/Course.php:
|
333 |
msgid "complete all lessons to mark this course as complete"
|
334 |
msgstr ""
|
335 |
|
336 |
-
#: classes/Course.php:
|
337 |
msgid "You have to pass %s quizzes to complete this course."
|
338 |
msgstr ""
|
339 |
|
340 |
-
#: classes/Course.php:
|
341 |
msgid "Make This Course Public"
|
342 |
msgstr ""
|
343 |
|
344 |
-
#: classes/Course.php:
|
345 |
msgid "No enrollment required."
|
346 |
msgstr ""
|
347 |
|
348 |
-
#: classes/Course.php:
|
349 |
msgid "Disable Q&A"
|
350 |
msgstr ""
|
351 |
|
352 |
-
#: classes/Course.php:
|
353 |
msgid "Invalid Course ID or Access Denied."
|
354 |
msgstr ""
|
355 |
|
356 |
-
#: classes/Course_Settings_Tabs.php:
|
357 |
msgid "Course Settings"
|
358 |
msgstr ""
|
359 |
|
360 |
-
#: classes/Course_Settings_Tabs.php:
|
361 |
msgid "General"
|
362 |
msgstr ""
|
363 |
|
364 |
-
#: classes/Course_Settings_Tabs.php:
|
365 |
msgid "General Settings"
|
366 |
msgstr ""
|
367 |
|
368 |
-
#: classes/Course_Settings_Tabs.php:
|
369 |
msgid "Maximum Students"
|
370 |
msgstr ""
|
371 |
|
372 |
-
#: classes/Course_Settings_Tabs.php:
|
373 |
msgid "Enable"
|
374 |
msgstr ""
|
375 |
|
376 |
-
#: classes/Course_Settings_Tabs.php:
|
377 |
msgid "Number of students that can enrol in this course. Set 0 for no limits."
|
378 |
msgstr ""
|
379 |
|
380 |
-
#: classes/Course_Widget.php:
|
381 |
msgid "Tutor Course"
|
382 |
msgstr ""
|
383 |
|
384 |
-
#: classes/Course_Widget.php:
|
385 |
msgid "Display courses wherever widget support is available."
|
386 |
msgstr ""
|
387 |
|
@@ -389,51 +389,51 @@ msgstr ""
|
|
389 |
msgid "New title"
|
390 |
msgstr ""
|
391 |
|
392 |
-
#: classes/Course_Widget.php:
|
393 |
-
msgid "Title
|
394 |
msgstr ""
|
395 |
|
396 |
-
#: classes/Course_Widget.php:
|
397 |
-
msgid "ID
|
398 |
msgstr ""
|
399 |
|
400 |
-
#: classes/Course_Widget.php:
|
401 |
msgid "Place single course id or comma (,) separated course ids"
|
402 |
msgstr ""
|
403 |
|
404 |
-
#: classes/Course_Widget.php:
|
405 |
msgid "Exclude IDS:"
|
406 |
msgstr ""
|
407 |
|
408 |
-
#: classes/Course_Widget.php:
|
409 |
msgid "Place comma (,) separated courses ids which you like to exclude from the query"
|
410 |
msgstr ""
|
411 |
|
412 |
-
#: classes/Course_Widget.php:
|
413 |
-
msgid "Category
|
414 |
msgstr ""
|
415 |
|
416 |
-
#: classes/Course_Widget.php:
|
417 |
msgid "Place comma (,) separated category ids"
|
418 |
msgstr ""
|
419 |
|
420 |
-
#: classes/Course_Widget.php:
|
421 |
msgid "OrderBy"
|
422 |
msgstr ""
|
423 |
|
424 |
-
#: classes/Course_Widget.php:
|
425 |
-
msgid "
|
426 |
msgstr ""
|
427 |
|
428 |
-
#: classes/Course_Widget.php:
|
429 |
msgid "Count:"
|
430 |
msgstr ""
|
431 |
|
432 |
-
#: classes/Course_Widget.php:
|
433 |
msgid "Total results you like to show"
|
434 |
msgstr ""
|
435 |
|
436 |
-
#: classes/Dashboard.php:
|
437 |
msgid "Auto Draft"
|
438 |
msgstr ""
|
439 |
|
@@ -449,7 +449,7 @@ msgstr ""
|
|
449 |
msgid "Check and place necessary information here."
|
450 |
msgstr ""
|
451 |
|
452 |
-
#: classes/Email.php:32, classes/Instructors_List.php:
|
453 |
msgid "Name"
|
454 |
msgstr ""
|
455 |
|
@@ -505,15 +505,15 @@ msgstr ""
|
|
505 |
msgid "This key is invalid or has already been used. Please reset your password again if needed."
|
506 |
msgstr ""
|
507 |
|
508 |
-
#: classes/FormHandler.php:
|
509 |
msgid "Please enter your password."
|
510 |
msgstr ""
|
511 |
|
512 |
-
#: classes/FormHandler.php:
|
513 |
msgid "Passwords do not match."
|
514 |
msgstr ""
|
515 |
|
516 |
-
#: classes/FormHandler.php:
|
517 |
msgid "Password Reset Request for %s"
|
518 |
msgstr ""
|
519 |
|
@@ -565,856 +565,852 @@ msgstr ""
|
|
565 |
msgid "Instructor has been added successfully"
|
566 |
msgstr ""
|
567 |
|
568 |
-
#: classes/Instructors_List.php:
|
569 |
msgid "Approve"
|
570 |
msgstr ""
|
571 |
|
572 |
-
#: classes/Instructors_List.php:
|
573 |
msgid "Sure to Block?"
|
574 |
msgstr ""
|
575 |
|
576 |
-
#: classes/Instructors_List.php:
|
577 |
msgid "Block"
|
578 |
msgstr ""
|
579 |
|
580 |
-
#: classes/Instructors_List.php:
|
581 |
msgid "Sure to Un Block?"
|
582 |
msgstr ""
|
583 |
|
584 |
-
#: classes/Instructors_List.php:
|
585 |
msgid "Unblock"
|
586 |
msgstr ""
|
587 |
|
588 |
-
#: classes/Instructors_List.php:
|
589 |
msgid "Reject"
|
590 |
msgstr ""
|
591 |
|
592 |
-
#: classes/Instructors_List.php:
|
593 |
msgid "Remove as Instructor"
|
594 |
msgstr ""
|
595 |
|
596 |
-
#: classes/Instructors_List.php:
|
597 |
msgid "Sure to Reject?"
|
598 |
msgstr ""
|
599 |
|
600 |
-
#: classes/Instructors_List.php:
|
601 |
msgid "Sure to Remove as Instructor?"
|
602 |
msgstr ""
|
603 |
|
604 |
-
#: classes/Instructors_List.php:
|
605 |
msgid "E-Mail"
|
606 |
msgstr ""
|
607 |
|
608 |
-
#: classes/Instructors_List.php:
|
609 |
msgid "Total Course"
|
610 |
msgstr ""
|
611 |
|
612 |
-
#: classes/Instructors_List.php:
|
613 |
msgid "Instructor Commission"
|
614 |
msgstr ""
|
615 |
|
616 |
-
#: classes/Instructors_List.php:
|
617 |
msgid "Date"
|
618 |
msgstr ""
|
619 |
|
620 |
-
#: classes/Lesson.php:
|
621 |
msgid "Select Course"
|
622 |
msgstr ""
|
623 |
|
624 |
-
#: classes/Lesson.php:
|
625 |
msgid "Lesson Video"
|
626 |
msgstr ""
|
627 |
|
628 |
-
#: classes/Lesson.php:
|
629 |
msgid "Attachments"
|
630 |
msgstr ""
|
631 |
|
632 |
-
#: classes/Lesson.php:
|
633 |
msgid "Draft Lesson"
|
634 |
msgstr ""
|
635 |
|
636 |
-
#: classes/Lesson.php:
|
637 |
msgid "Couldn't create lesson."
|
638 |
msgstr ""
|
639 |
|
640 |
-
#: classes/Lesson.php:
|
641 |
msgid "Course"
|
642 |
msgstr ""
|
643 |
|
644 |
-
#: classes/Options.php:
|
645 |
msgid "Option Updated"
|
646 |
msgstr ""
|
647 |
|
648 |
-
#: classes/Options.php:
|
649 |
msgid "/course/sample-course/<code>lessons</code>/sample-lesson/"
|
650 |
msgstr ""
|
651 |
|
652 |
-
#: classes/Options.php:
|
653 |
msgctxt "tutor student profile"
|
654 |
msgid "profile"
|
655 |
msgstr ""
|
656 |
|
657 |
-
#: classes/Options.php:
|
658 |
msgid "Unlimited"
|
659 |
msgstr ""
|
660 |
|
661 |
-
#: classes/Options.php:
|
662 |
msgid "HTML 5 (mp4)"
|
663 |
msgstr ""
|
664 |
|
665 |
-
#: classes/Options.php:
|
666 |
msgid "External URL"
|
667 |
msgstr ""
|
668 |
|
669 |
-
#: classes/Options.php:
|
670 |
msgid "Youtube"
|
671 |
msgstr ""
|
672 |
|
673 |
-
#: classes/Options.php:
|
674 |
msgid "Vimeo"
|
675 |
msgstr ""
|
676 |
|
677 |
-
#: classes/Options.php:
|
678 |
msgid "Embedded"
|
679 |
msgstr ""
|
680 |
|
681 |
-
#: classes/Options.php:
|
682 |
msgid "Keyword Search"
|
683 |
msgstr ""
|
684 |
|
685 |
-
#: classes/Options.php:
|
686 |
-
msgid "Category"
|
687 |
-
msgstr ""
|
688 |
-
|
689 |
-
#: classes/Options.php:113, templates/course-filter/filters.php:42
|
690 |
msgid "Tag"
|
691 |
msgstr ""
|
692 |
|
693 |
-
#: classes/Options.php:
|
694 |
msgid "Difficulty Level"
|
695 |
msgstr ""
|
696 |
|
697 |
-
#: classes/Options.php:
|
698 |
msgid "Price Type"
|
699 |
msgstr ""
|
700 |
|
701 |
-
#: classes/Options.php:
|
702 |
msgid "Dashboard Page"
|
703 |
msgstr ""
|
704 |
|
705 |
-
#: classes/Options.php:
|
706 |
msgid "This page will be used for student and instructor dashboard"
|
707 |
msgstr ""
|
708 |
|
709 |
-
#: classes/Options.php:
|
710 |
msgid "Public Profile"
|
711 |
msgstr ""
|
712 |
|
713 |
-
#: classes/Options.php:
|
714 |
msgid "Enable this to make a profile publicly visible"
|
715 |
msgstr ""
|
716 |
|
717 |
-
#: classes/Options.php:
|
718 |
msgid "Profile Completion"
|
719 |
msgstr ""
|
720 |
|
721 |
-
#: classes/Options.php:
|
722 |
msgid "Enabling this feature will show a notification bar to students and instructors to complete their profile information"
|
723 |
msgstr ""
|
724 |
|
725 |
-
#: classes/Options.php:
|
726 |
msgid "Tutor Native Login"
|
727 |
msgstr ""
|
728 |
|
729 |
-
#: classes/Options.php:
|
730 |
msgid "Disable"
|
731 |
msgstr ""
|
732 |
|
733 |
-
#: classes/Options.php:
|
734 |
msgid "Disable to use the default WordPress login page"
|
735 |
msgstr ""
|
736 |
|
737 |
-
#: classes/Options.php:
|
738 |
msgid "Course Visibility"
|
739 |
msgstr ""
|
740 |
|
741 |
-
#: classes/Options.php:
|
742 |
msgid "Logged in only"
|
743 |
msgstr ""
|
744 |
|
745 |
-
#: classes/Options.php:
|
746 |
msgid "Students must be logged in to view course"
|
747 |
msgstr ""
|
748 |
|
749 |
-
#: classes/Options.php:
|
750 |
msgid "Erase upon uninstallation"
|
751 |
msgstr ""
|
752 |
|
753 |
-
#: classes/Options.php:
|
754 |
msgid "Delete all data during uninstallation"
|
755 |
msgstr ""
|
756 |
|
757 |
-
#: classes/Options.php:
|
758 |
msgid "Spotlight mode"
|
759 |
msgstr ""
|
760 |
|
761 |
-
#: classes/Options.php:
|
762 |
msgid "This will hide the header and the footer and enable spotlight (full screen) mode when students view lessons."
|
763 |
msgstr ""
|
764 |
|
765 |
-
#: classes/Options.php:
|
766 |
msgid "YouTube Player"
|
767 |
msgstr ""
|
768 |
|
769 |
-
#: classes/Options.php:
|
770 |
msgid "Disable this option to use Tutor LMS video player."
|
771 |
msgstr ""
|
772 |
|
773 |
-
#: classes/Options.php:
|
774 |
msgid "Vimeo Player"
|
775 |
msgstr ""
|
776 |
|
777 |
-
#: classes/Options.php:
|
778 |
msgid "Pagination"
|
779 |
msgstr ""
|
780 |
|
781 |
-
#: classes/Options.php:
|
782 |
msgid "Number of items you would like displayed \"per page\" in the pagination"
|
783 |
msgstr ""
|
784 |
|
785 |
-
#: classes/Options.php:
|
786 |
msgid "Maintenance Mode"
|
787 |
msgstr ""
|
788 |
|
789 |
-
#: classes/Options.php:
|
790 |
msgid "Enabling the maintenance mode allows you to display a custom message on the frontend. During this time, visitors can not access the site content. But the wp-admin dashboard will remain accessible."
|
791 |
msgstr ""
|
792 |
|
793 |
-
#: classes/Options.php:
|
794 |
msgid "Frontend Admin Bar"
|
795 |
msgstr ""
|
796 |
|
797 |
-
#: classes/Options.php:
|
798 |
msgid "Hide"
|
799 |
msgstr ""
|
800 |
|
801 |
-
#: classes/Options.php:
|
802 |
msgid "Hide admin bar option allow you to hide WordPress admin bar entirely from the frontend. It will still show to administrator roles user"
|
803 |
msgstr ""
|
804 |
|
805 |
-
#: classes/Options.php:
|
806 |
msgid "Error message for wrong login credentials"
|
807 |
msgstr ""
|
808 |
|
809 |
-
#: classes/Options.php:
|
810 |
msgid "Login error message displayed when the user puts wrong login credentials."
|
811 |
msgstr ""
|
812 |
|
813 |
-
#: classes/Options.php:
|
814 |
msgid "Gutenberg Editor"
|
815 |
msgstr ""
|
816 |
|
817 |
-
#: classes/Options.php:
|
818 |
msgid "Use Gutenberg editor on course description area."
|
819 |
msgstr ""
|
820 |
|
821 |
-
#: classes/Options.php:
|
822 |
msgid "Enable / Disable"
|
823 |
msgstr ""
|
824 |
|
825 |
-
#: classes/Options.php:
|
826 |
msgid "Hide course products from shop page"
|
827 |
msgstr ""
|
828 |
|
829 |
-
#: classes/Options.php:
|
830 |
msgid "Enabling this feature will remove course products from the shop page."
|
831 |
msgstr ""
|
832 |
|
833 |
-
#: classes/Options.php:
|
834 |
msgid "Course Content Access"
|
835 |
msgstr ""
|
836 |
|
837 |
-
#: classes/Options.php:
|
838 |
msgid "Allow instructors and admins to view the course content without enrolling"
|
839 |
msgstr ""
|
840 |
|
841 |
-
#: classes/Options.php:
|
842 |
msgid "Auto redirect to courses"
|
843 |
msgstr ""
|
844 |
|
845 |
-
#: classes/Options.php:
|
846 |
msgid "When a user's WooCommerce order is auto-completed, they will be redirected to enrolled courses"
|
847 |
msgstr ""
|
848 |
|
849 |
-
#: classes/Options.php:
|
850 |
msgid "Course Completion Process"
|
851 |
msgstr ""
|
852 |
|
853 |
-
#: classes/Options.php:
|
854 |
msgid "Flexible"
|
855 |
msgstr ""
|
856 |
|
857 |
-
#: classes/Options.php:
|
858 |
msgid "Strict Mode"
|
859 |
msgstr ""
|
860 |
|
861 |
-
#: classes/Options.php:
|
862 |
msgid "Students can complete courses anytime in the Flexible mode. In the Strict mode, students have to complete, pass all the lessons and quizzes (if any) to mark a course as complete."
|
863 |
msgstr ""
|
864 |
|
865 |
-
#: classes/Options.php:
|
866 |
msgid "Course Retake"
|
867 |
msgstr ""
|
868 |
|
869 |
-
#: classes/Options.php:
|
870 |
msgid "Enabling this feature will allow students to reset course progress and start over."
|
871 |
msgstr ""
|
872 |
|
873 |
-
#: classes/Options.php:
|
874 |
msgid "Archive"
|
875 |
msgstr ""
|
876 |
|
877 |
-
#: classes/Options.php:
|
878 |
msgid "Course Archive Settings"
|
879 |
msgstr ""
|
880 |
|
881 |
-
#: classes/Options.php:
|
882 |
msgid "Course Archive Page"
|
883 |
msgstr ""
|
884 |
|
885 |
-
#: classes/Options.php:
|
886 |
msgid "This page will be used to list all the published courses."
|
887 |
msgstr ""
|
888 |
|
889 |
-
#: classes/Options.php:
|
890 |
msgid "Column Per Row"
|
891 |
msgstr ""
|
892 |
|
893 |
-
#: classes/Options.php:
|
894 |
msgid "Define how many column you want to use to display courses."
|
895 |
msgstr ""
|
896 |
|
897 |
-
#: classes/Options.php:
|
898 |
msgid "Courses Per Page"
|
899 |
msgstr ""
|
900 |
|
901 |
-
#: classes/Options.php:
|
902 |
msgid "Define how many courses you want to show per page"
|
903 |
msgstr ""
|
904 |
|
905 |
-
#: classes/Options.php:
|
906 |
msgid "Course Filter"
|
907 |
msgstr ""
|
908 |
|
909 |
-
#: classes/Options.php:
|
910 |
msgid "Show sorting and filtering options on course archive page"
|
911 |
msgstr ""
|
912 |
|
913 |
-
#: classes/Options.php:
|
914 |
msgid "Preferred Course Filters"
|
915 |
msgstr ""
|
916 |
|
917 |
-
#: classes/Options.php:
|
918 |
msgid "Choose preferred filter options you'd like to show in course archive page."
|
919 |
msgstr ""
|
920 |
|
921 |
-
#: classes/Options.php:
|
922 |
msgid "Course Display Settings"
|
923 |
msgstr ""
|
924 |
|
925 |
-
#: classes/Options.php:
|
926 |
msgid "Display Instructor Info"
|
927 |
msgstr ""
|
928 |
|
929 |
-
#: classes/Options.php:
|
930 |
msgid "Show instructor bio on each page"
|
931 |
msgstr ""
|
932 |
|
933 |
-
#: classes/Options.php:
|
934 |
msgid "Question and Answer"
|
935 |
msgstr ""
|
936 |
|
937 |
-
#: classes/Options.php:
|
938 |
msgid "Enabling this feature will add a Q&A section on every course."
|
939 |
msgstr ""
|
940 |
|
941 |
-
#: classes/Options.php:
|
942 |
msgid "Course Author"
|
943 |
msgstr ""
|
944 |
|
945 |
-
#: classes/Options.php:
|
946 |
msgid "Disabling this feature will be removed course author name from the course page."
|
947 |
msgstr ""
|
948 |
|
949 |
-
#: classes/Options.php:
|
950 |
msgid "Course Level"
|
951 |
msgstr ""
|
952 |
|
953 |
-
#: classes/Options.php:
|
954 |
msgid "Disabling this feature will be removed course level from the course page."
|
955 |
msgstr ""
|
956 |
|
957 |
-
#: classes/Options.php:
|
958 |
msgid "Course Share"
|
959 |
msgstr ""
|
960 |
|
961 |
-
#: classes/Options.php:
|
962 |
msgid "Disabling this feature will be removed course share option from the course page."
|
963 |
msgstr ""
|
964 |
|
965 |
-
#: classes/Options.php:
|
966 |
msgid "Course Duration"
|
967 |
msgstr ""
|
968 |
|
969 |
-
#: classes/Options.php:
|
970 |
msgid "Disabling this feature will be removed course duration from the course page."
|
971 |
msgstr ""
|
972 |
|
973 |
-
#: classes/Options.php:
|
974 |
msgid "Course Total Enrolled"
|
975 |
msgstr ""
|
976 |
|
977 |
-
#: classes/Options.php:
|
978 |
msgid "Disabling this feature will be removed course total enrolled from the course page."
|
979 |
msgstr ""
|
980 |
|
981 |
-
#: classes/Options.php:
|
982 |
msgid "Course Update Date"
|
983 |
msgstr ""
|
984 |
|
985 |
-
#: classes/Options.php:
|
986 |
msgid "Disabling this feature will be removed course update date from the course page."
|
987 |
msgstr ""
|
988 |
|
989 |
-
#: classes/Options.php:
|
990 |
msgid "Course Progress Bar"
|
991 |
msgstr ""
|
992 |
|
993 |
-
#: classes/Options.php:
|
994 |
msgid "Disabling this feature will be removed completing progress bar from the course page."
|
995 |
msgstr ""
|
996 |
|
997 |
-
#: classes/Options.php:
|
998 |
msgid "Course Material"
|
999 |
msgstr ""
|
1000 |
|
1001 |
-
#: classes/Options.php:
|
1002 |
msgid "Disabling this feature will be removed course material from the course page."
|
1003 |
msgstr ""
|
1004 |
|
1005 |
-
#: classes/Options.php:
|
1006 |
msgid "Course About"
|
1007 |
msgstr ""
|
1008 |
|
1009 |
-
#: classes/Options.php:
|
1010 |
msgid "Disabling this feature will be removed course about from the course page."
|
1011 |
msgstr ""
|
1012 |
|
1013 |
-
#: classes/Options.php:
|
1014 |
msgid "Course Description"
|
1015 |
msgstr ""
|
1016 |
|
1017 |
-
#: classes/Options.php:
|
1018 |
msgid "Disabling this feature will be removed course description from the course page."
|
1019 |
msgstr ""
|
1020 |
|
1021 |
-
#: classes/Options.php:
|
1022 |
msgid "Course Benefits"
|
1023 |
msgstr ""
|
1024 |
|
1025 |
-
#: classes/Options.php:
|
1026 |
msgid "Disabling this feature will be removed course benefits from the course page."
|
1027 |
msgstr ""
|
1028 |
|
1029 |
-
#: classes/Options.php:
|
1030 |
msgid "Course Requirements"
|
1031 |
msgstr ""
|
1032 |
|
1033 |
-
#: classes/Options.php:
|
1034 |
msgid "Disabling this feature will be removed course requirements from the course page."
|
1035 |
msgstr ""
|
1036 |
|
1037 |
-
#: classes/Options.php:
|
1038 |
msgid "Course Target Audience"
|
1039 |
msgstr ""
|
1040 |
|
1041 |
-
#: classes/Options.php:
|
1042 |
msgid "Disabling this feature will be removed course target audience from the course page."
|
1043 |
msgstr ""
|
1044 |
|
1045 |
-
#: classes/Options.php:
|
1046 |
msgid "Course Announcements"
|
1047 |
msgstr ""
|
1048 |
|
1049 |
-
#: classes/Options.php:
|
1050 |
msgid "Disabling this feature will be removed course announcements from the course page."
|
1051 |
msgstr ""
|
1052 |
|
1053 |
-
#: classes/Options.php:
|
1054 |
msgid "Course Review"
|
1055 |
msgstr ""
|
1056 |
|
1057 |
-
#: classes/Options.php:
|
1058 |
msgid "Disabling this feature will be removed course review system from the course page."
|
1059 |
msgstr ""
|
1060 |
|
1061 |
-
#: classes/Options.php:
|
1062 |
msgid "Preferred Video Source"
|
1063 |
msgstr ""
|
1064 |
|
1065 |
-
#: classes/Options.php:
|
1066 |
msgid "Choose video sources you'd like to support. Unchecking all will not disable video feature."
|
1067 |
msgstr ""
|
1068 |
|
1069 |
-
#: classes/Options.php:
|
1070 |
msgid "Default Video Source"
|
1071 |
msgstr ""
|
1072 |
|
1073 |
-
#: classes/Options.php:
|
1074 |
msgid "Choose video source to be selected by default."
|
1075 |
msgstr ""
|
1076 |
|
1077 |
-
#: classes/Options.php:
|
1078 |
msgid "Lesson Settings"
|
1079 |
msgstr ""
|
1080 |
|
1081 |
-
#: classes/Options.php:
|
1082 |
msgid "Lesson settings will be here"
|
1083 |
msgstr ""
|
1084 |
|
1085 |
-
#: classes/Options.php:
|
1086 |
msgid "Classic Editor"
|
1087 |
msgstr ""
|
1088 |
|
1089 |
-
#: classes/Options.php:
|
1090 |
msgid "Enable classic editor to get full support of any editor/page builder."
|
1091 |
msgstr ""
|
1092 |
|
1093 |
-
#: classes/Options.php:
|
1094 |
msgid "Automatically load next course content."
|
1095 |
msgstr ""
|
1096 |
|
1097 |
-
#: classes/Options.php:
|
1098 |
msgid "Enabling this feature will be load next course content automatically after finishing current video."
|
1099 |
msgstr ""
|
1100 |
|
1101 |
-
#: classes/Options.php:
|
1102 |
msgid "Lesson Permalink Base"
|
1103 |
msgstr ""
|
1104 |
|
1105 |
-
#: classes/Options.php:
|
1106 |
msgid "Youtube API Key"
|
1107 |
msgstr ""
|
1108 |
|
1109 |
-
#: classes/Options.php:
|
1110 |
msgid "Quiz"
|
1111 |
msgstr ""
|
1112 |
|
1113 |
-
#: classes/Options.php:
|
1114 |
msgid "The values you set here define the default values that are used in the settings form when you create a new quiz."
|
1115 |
msgstr ""
|
1116 |
|
1117 |
-
#: classes/Options.php:
|
1118 |
msgid "Time Limit"
|
1119 |
msgstr ""
|
1120 |
|
1121 |
-
#: classes/Options.php:
|
1122 |
msgid "0 means unlimited time."
|
1123 |
msgstr ""
|
1124 |
|
1125 |
-
#: classes/Options.php:
|
1126 |
msgid "Weeks"
|
1127 |
msgstr ""
|
1128 |
|
1129 |
-
#: classes/Options.php:
|
1130 |
msgid "Days"
|
1131 |
msgstr ""
|
1132 |
|
1133 |
-
#: classes/Options.php:
|
1134 |
msgid "Hours"
|
1135 |
msgstr ""
|
1136 |
|
1137 |
-
#: classes/Options.php:
|
1138 |
msgid "Minutes"
|
1139 |
msgstr ""
|
1140 |
|
1141 |
-
#: classes/Options.php:
|
1142 |
msgid "Seconds"
|
1143 |
msgstr ""
|
1144 |
|
1145 |
-
#: classes/Options.php:
|
1146 |
msgid "When time expires"
|
1147 |
msgstr ""
|
1148 |
|
1149 |
-
#: classes/Options.php:
|
1150 |
msgid "The current quiz answers are submitted automatically."
|
1151 |
msgstr ""
|
1152 |
|
1153 |
-
#: classes/Options.php:
|
1154 |
msgid "The current quiz answers are submitted by students."
|
1155 |
msgstr ""
|
1156 |
|
1157 |
-
#: classes/Options.php:
|
1158 |
msgid "Attempts must be submitted before time expires, otherwise they will not be counted"
|
1159 |
msgstr ""
|
1160 |
|
1161 |
-
#: classes/Options.php:
|
1162 |
msgid "Choose which action to follow when the quiz time expires."
|
1163 |
msgstr ""
|
1164 |
|
1165 |
-
#: classes/Options.php:
|
1166 |
msgid "Attempts allowed"
|
1167 |
msgstr ""
|
1168 |
|
1169 |
-
#: classes/Options.php:
|
1170 |
msgid "The highest number of attempts students are allowed to take for a quiz. 0 means unlimited attempts."
|
1171 |
msgstr ""
|
1172 |
|
1173 |
-
#: classes/Options.php:
|
1174 |
msgid "Show Previous button"
|
1175 |
msgstr ""
|
1176 |
|
1177 |
-
#: classes/Options.php:
|
1178 |
msgid "Choose whether to show or hide previous button for single question."
|
1179 |
msgstr ""
|
1180 |
|
1181 |
-
#: classes/Options.php:
|
1182 |
msgid "Final grade calculation"
|
1183 |
msgstr ""
|
1184 |
|
1185 |
-
#: classes/Options.php:
|
1186 |
msgid "Highest Grade"
|
1187 |
msgstr ""
|
1188 |
|
1189 |
-
#: classes/Options.php:
|
1190 |
msgid "Average Grade"
|
1191 |
msgstr ""
|
1192 |
|
1193 |
-
#: classes/Options.php:
|
1194 |
msgid "First Attempt"
|
1195 |
msgstr ""
|
1196 |
|
1197 |
-
#: classes/Options.php:
|
1198 |
msgid "Last Attempt"
|
1199 |
msgstr ""
|
1200 |
|
1201 |
-
#: classes/Options.php:
|
1202 |
msgid "When multiple attempts are allowed, which method should be used to calculate a student's final grade for the quiz."
|
1203 |
msgstr ""
|
1204 |
|
1205 |
-
#: classes/Options.php:
|
1206 |
msgid "Instructor Profile Settings"
|
1207 |
msgstr ""
|
1208 |
|
1209 |
-
#: classes/Options.php:
|
1210 |
msgid "Enable Disable Option to on/off notification on various event"
|
1211 |
msgstr ""
|
1212 |
|
1213 |
-
#: classes/Options.php:
|
1214 |
msgid "Course Marketplace"
|
1215 |
msgstr ""
|
1216 |
|
1217 |
-
#: classes/Options.php:
|
1218 |
msgid "Allow multiple instructors to upload their courses."
|
1219 |
msgstr ""
|
1220 |
|
1221 |
-
#: classes/Options.php:
|
1222 |
msgid "Instructor Registration Page"
|
1223 |
msgstr ""
|
1224 |
|
1225 |
-
#: classes/Options.php:
|
1226 |
msgid "This page will be used to sign up new instructors."
|
1227 |
msgstr ""
|
1228 |
|
1229 |
-
#: classes/Options.php:
|
1230 |
msgid "Allow publishing course"
|
1231 |
msgstr ""
|
1232 |
|
1233 |
-
#: classes/Options.php:
|
1234 |
msgid "Enable instructors to publish course directly. <strong>Do not select</strong> if admins want to review courses before publishing."
|
1235 |
msgstr ""
|
1236 |
|
1237 |
-
#: classes/Options.php:
|
1238 |
msgid "Become Instructor Button"
|
1239 |
msgstr ""
|
1240 |
|
1241 |
-
#: classes/Options.php:
|
1242 |
msgid "Uncheck this option to hide the button from student dashboard."
|
1243 |
msgstr ""
|
1244 |
|
1245 |
-
#: classes/Options.php:
|
1246 |
msgid "Student Profile settings"
|
1247 |
msgstr ""
|
1248 |
|
1249 |
-
#: classes/Options.php:
|
1250 |
msgid "Student Registration Page"
|
1251 |
msgstr ""
|
1252 |
|
1253 |
-
#: classes/Options.php:
|
1254 |
msgid "Choose the page for student registration page"
|
1255 |
msgstr ""
|
1256 |
|
1257 |
-
#: classes/Options.php:
|
1258 |
msgid "Show reviews on profile"
|
1259 |
msgstr ""
|
1260 |
|
1261 |
-
#: classes/Options.php:
|
1262 |
msgid "Enabling this will show the reviews written by each student on their profile"
|
1263 |
msgstr ""
|
1264 |
|
1265 |
-
#: classes/Options.php:
|
1266 |
msgid "Show completed courses"
|
1267 |
msgstr ""
|
1268 |
|
1269 |
-
#: classes/Options.php:
|
1270 |
msgid "Completed courses will be shown on student profiles. <br/> For example, you can see this link-"
|
1271 |
msgstr ""
|
1272 |
|
1273 |
-
#: classes/Options.php:
|
1274 |
msgid "Earning"
|
1275 |
msgstr ""
|
1276 |
|
1277 |
-
#: classes/Options.php:
|
1278 |
msgid "Earning and commission allocation"
|
1279 |
msgstr ""
|
1280 |
|
1281 |
-
#: classes/Options.php:
|
1282 |
msgid "If disabled, the Admin will receive 100% of the earning"
|
1283 |
msgstr ""
|
1284 |
|
1285 |
-
#: classes/Options.php:
|
1286 |
msgid "Admin Commission Percentage"
|
1287 |
msgstr ""
|
1288 |
|
1289 |
-
#: classes/Options.php:
|
1290 |
msgid "Define the commission of the Admin from each sale.(after deducting fees)"
|
1291 |
msgstr ""
|
1292 |
|
1293 |
-
#: classes/Options.php:
|
1294 |
msgid "Instructor Commission Percentage"
|
1295 |
msgstr ""
|
1296 |
|
1297 |
-
#: classes/Options.php:
|
1298 |
msgid "Define the commission for instructors from each sale.(after deducting fees)"
|
1299 |
msgstr ""
|
1300 |
|
1301 |
-
#: classes/Options.php:
|
1302 |
msgid "Fee Deduction"
|
1303 |
msgstr ""
|
1304 |
|
1305 |
-
#: classes/Options.php:
|
1306 |
msgid "Fees are charged from the entire sales amount. The remaining amount will be divided among admin and instructors."
|
1307 |
msgstr ""
|
1308 |
|
1309 |
-
#: classes/Options.php:
|
1310 |
msgid "Fee Name"
|
1311 |
msgstr ""
|
1312 |
|
1313 |
-
#: classes/Options.php:
|
1314 |
msgid "Fee Amount"
|
1315 |
msgstr ""
|
1316 |
|
1317 |
-
#: classes/Options.php:
|
1318 |
msgid "Select Fees Type"
|
1319 |
msgstr ""
|
1320 |
|
1321 |
-
#: classes/Options.php:
|
1322 |
msgid "Percent"
|
1323 |
msgstr ""
|
1324 |
|
1325 |
-
#: classes/Options.php:
|
1326 |
msgid "Fixed"
|
1327 |
msgstr ""
|
1328 |
|
1329 |
-
#: classes/Options.php:
|
1330 |
msgid "Show Statement Per Page"
|
1331 |
msgstr ""
|
1332 |
|
1333 |
-
#: classes/Options.php:
|
1334 |
msgid "Define the number of statements to show."
|
1335 |
msgstr ""
|
1336 |
|
1337 |
-
#: classes/Options.php:
|
1338 |
msgid "Withdrawal"
|
1339 |
msgstr ""
|
1340 |
|
1341 |
-
#: classes/Options.php:
|
1342 |
msgid "Withdrawal Settings"
|
1343 |
msgstr ""
|
1344 |
|
1345 |
-
#: classes/Options.php:
|
1346 |
msgid "Minimum Withdraw Amount"
|
1347 |
msgstr ""
|
1348 |
|
1349 |
-
#: classes/Options.php:
|
1350 |
msgid "Instructors should earn equal or above this amount to make a withdraw request."
|
1351 |
msgstr ""
|
1352 |
|
1353 |
-
#: classes/Options.php:
|
1354 |
msgid "Withdraw Methods"
|
1355 |
msgstr ""
|
1356 |
|
1357 |
-
#: classes/Options.php:
|
1358 |
msgid "Set withdraw settings"
|
1359 |
msgstr ""
|
1360 |
|
1361 |
-
#: classes/Options.php:
|
1362 |
msgid "Style"
|
1363 |
msgstr ""
|
1364 |
|
1365 |
-
#: classes/Options.php:
|
1366 |
msgid "Color Style"
|
1367 |
msgstr ""
|
1368 |
|
1369 |
-
#: classes/Options.php:
|
1370 |
msgid "Primary Color"
|
1371 |
msgstr ""
|
1372 |
|
1373 |
-
#: classes/Options.php:
|
1374 |
msgid "Primary Hover Color"
|
1375 |
msgstr ""
|
1376 |
|
1377 |
-
#: classes/Options.php:
|
1378 |
msgid "Text color"
|
1379 |
msgstr ""
|
1380 |
|
1381 |
-
#: classes/Options.php:
|
1382 |
msgid "Light color"
|
1383 |
msgstr ""
|
1384 |
|
1385 |
-
#: classes/Options.php:
|
1386 |
msgid "Button Primary Color"
|
1387 |
msgstr ""
|
1388 |
|
1389 |
-
#: classes/Options.php:
|
1390 |
msgid "Button Danger Color"
|
1391 |
msgstr ""
|
1392 |
|
1393 |
-
#: classes/Options.php:
|
1394 |
msgid "Button Success Color"
|
1395 |
msgstr ""
|
1396 |
|
1397 |
-
#: classes/Options.php:
|
1398 |
msgid "Button Warning Color"
|
1399 |
msgstr ""
|
1400 |
|
1401 |
-
#: classes/Options.php:
|
1402 |
msgid "Monetization"
|
1403 |
msgstr ""
|
1404 |
|
1405 |
-
#: classes/Options.php:
|
1406 |
msgid "You can monetize your LMS website by selling courses in a various way."
|
1407 |
msgstr ""
|
1408 |
|
1409 |
-
#: classes/Options.php:
|
1410 |
msgid "Monetize Option"
|
1411 |
msgstr ""
|
1412 |
|
1413 |
-
#: classes/Options.php:
|
1414 |
msgid "Disable Monetization"
|
1415 |
msgstr ""
|
1416 |
|
1417 |
-
#: classes/Options.php:
|
1418 |
msgid "Select a monetization option to generate revenue by selling courses. Supports: WooCommerce, Easy Digital Downloads, Paid Memberships Pro"
|
1419 |
msgstr ""
|
1420 |
|
@@ -1455,11 +1451,11 @@ msgstr ""
|
|
1455 |
msgid "Edit Course"
|
1456 |
msgstr ""
|
1457 |
|
1458 |
-
#: classes/Post_types.php:48, templates/dashboard/create-course.php:
|
1459 |
msgid "View Course"
|
1460 |
msgstr ""
|
1461 |
|
1462 |
-
#: classes/Post_types.php:49, classes/Tutor_List_Table.php:
|
1463 |
msgid "Courses"
|
1464 |
msgstr ""
|
1465 |
|
@@ -1754,7 +1750,7 @@ msgstr ""
|
|
1754 |
msgid "View Assignment"
|
1755 |
msgstr ""
|
1756 |
|
1757 |
-
#: classes/Post_types.php:287, views/metabox/course-topics.php:
|
1758 |
msgid "Assignments"
|
1759 |
msgstr ""
|
1760 |
|
@@ -1824,91 +1820,91 @@ msgstr ""
|
|
1824 |
msgid "Preview course"
|
1825 |
msgstr ""
|
1826 |
|
1827 |
-
#: classes/Question_Answers_List.php:
|
1828 |
msgid "Answer"
|
1829 |
msgstr ""
|
1830 |
|
1831 |
-
#: classes/Question_Answers_List.php:
|
1832 |
msgid "Question"
|
1833 |
msgstr ""
|
1834 |
|
1835 |
-
#: classes/Question_Answers_List.php:
|
1836 |
msgid "Student"
|
1837 |
msgstr ""
|
1838 |
|
1839 |
-
#: classes/Quiz.php:
|
1840 |
msgid "Quiz has been timeout already"
|
1841 |
msgstr ""
|
1842 |
|
1843 |
-
#: classes/Quiz.php:
|
1844 |
msgid "QUIZ"
|
1845 |
msgstr ""
|
1846 |
|
1847 |
-
#: classes/Quiz.php:
|
1848 |
msgid "Please make sure you have added more than one option and saved them"
|
1849 |
msgstr ""
|
1850 |
|
1851 |
-
#: classes/Quiz.php:
|
1852 |
msgid "Please select the correct answer"
|
1853 |
msgstr ""
|
1854 |
|
1855 |
-
#: classes/Quiz.php:
|
1856 |
msgid "True"
|
1857 |
msgstr ""
|
1858 |
|
1859 |
-
#: classes/Quiz.php:
|
1860 |
msgid "False"
|
1861 |
msgstr ""
|
1862 |
|
1863 |
-
#: classes/Quiz.php:
|
1864 |
msgid "Answer options & mark correct"
|
1865 |
msgstr ""
|
1866 |
|
1867 |
-
#: classes/Quiz.php:
|
1868 |
msgid "Make sure you’re saving the answers in the right order. Students will have to match this order exactly."
|
1869 |
msgstr ""
|
1870 |
|
1871 |
-
#: classes/Quiz.php:
|
1872 |
msgid "Mark as correct"
|
1873 |
msgstr ""
|
1874 |
|
1875 |
-
#: classes/Quiz.php:
|
1876 |
msgid "Access Denied."
|
1877 |
msgstr ""
|
1878 |
|
1879 |
-
#: classes/Quiz_Attempts_List.php:
|
1880 |
msgid "Review"
|
1881 |
msgstr ""
|
1882 |
|
1883 |
-
#: classes/Quiz_Attempts_List.php:
|
1884 |
msgid " ago"
|
1885 |
msgstr ""
|
1886 |
|
1887 |
-
#: classes/Quiz_Attempts_List.php:
|
1888 |
msgid " out of "
|
1889 |
msgstr ""
|
1890 |
|
1891 |
-
#: classes/Quiz_Attempts_List.php:
|
1892 |
msgid " pass "
|
1893 |
msgstr ""
|
1894 |
|
1895 |
-
#: classes/Quiz_Attempts_List.php:
|
1896 |
msgid "Fail"
|
1897 |
msgstr ""
|
1898 |
|
1899 |
-
#: classes/Quiz_Attempts_List.php:
|
1900 |
msgid "Pass"
|
1901 |
msgstr ""
|
1902 |
|
1903 |
-
#: classes/Quiz_Attempts_List.php:
|
1904 |
msgid "Under Review"
|
1905 |
msgstr ""
|
1906 |
|
1907 |
-
#: classes/Quiz_Attempts_List.php:
|
1908 |
msgid "Total Questions"
|
1909 |
msgstr ""
|
1910 |
|
1911 |
-
#: classes/Quiz_Attempts_List.php:
|
1912 |
msgid "Earned Points"
|
1913 |
msgstr ""
|
1914 |
|
@@ -1968,7 +1964,7 @@ msgstr ""
|
|
1968 |
msgid "Setup Wizard"
|
1969 |
msgstr ""
|
1970 |
|
1971 |
-
#: classes/Tutor.php:519, classes/Utils.php:
|
1972 |
msgid "Dashboard"
|
1973 |
msgstr ""
|
1974 |
|
@@ -2000,27 +1996,27 @@ msgstr ""
|
|
2000 |
msgid "Easy Digital Downloads"
|
2001 |
msgstr ""
|
2002 |
|
2003 |
-
#: classes/TutorEDD.php:106, classes/WooCommerce.php:
|
2004 |
msgid "Add Product"
|
2005 |
msgstr ""
|
2006 |
|
2007 |
-
#: classes/Tutor_List_Table.php:
|
2008 |
msgid "All"
|
2009 |
msgstr ""
|
2010 |
|
2011 |
-
#: classes/Tutor_List_Table.php:
|
2012 |
msgid "Sort By"
|
2013 |
msgstr ""
|
2014 |
|
2015 |
-
#: classes/Tutor_List_Table.php:
|
2016 |
msgid "Bulk Actions"
|
2017 |
msgstr ""
|
2018 |
|
2019 |
-
#: classes/Tutor_List_Table.php:
|
2020 |
msgid "No course found"
|
2021 |
msgstr ""
|
2022 |
|
2023 |
-
#: classes/Tutor_List_Table.php:
|
2024 |
msgid "Search"
|
2025 |
msgstr ""
|
2026 |
|
@@ -2064,7 +2060,7 @@ msgstr ""
|
|
2064 |
msgid "weeks"
|
2065 |
msgstr ""
|
2066 |
|
2067 |
-
#: classes/Tutor_Setup.php:275, classes/Tutor_Setup.php:564, classes/Utils.php:
|
2068 |
msgid "Instructor"
|
2069 |
msgstr ""
|
2070 |
|
@@ -2144,7 +2140,7 @@ msgstr ""
|
|
2144 |
msgid "What message to display when the quiz time expires?"
|
2145 |
msgstr ""
|
2146 |
|
2147 |
-
#: classes/Tutor_Setup.php:447, views/modal/edit_quiz.php:
|
2148 |
msgid "Attempts Allowed"
|
2149 |
msgstr ""
|
2150 |
|
@@ -2248,7 +2244,7 @@ msgstr ""
|
|
2248 |
msgid "Payment"
|
2249 |
msgstr ""
|
2250 |
|
2251 |
-
#: classes/Tutor_Setup.php:567, templates/single/quiz/body.php:
|
2252 |
msgid "Finish"
|
2253 |
msgstr ""
|
2254 |
|
@@ -2280,7 +2276,7 @@ msgstr ""
|
|
2280 |
msgid "Skip This Step"
|
2281 |
msgstr ""
|
2282 |
|
2283 |
-
#: classes/Tutor_Setup.php:623, classes/Tutor_Setup.php:730, templates/shortcode/tutor-instructor.php:48, views/modal/add_quiz.php:
|
2284 |
msgid "Next"
|
2285 |
msgstr ""
|
2286 |
|
@@ -2368,354 +2364,354 @@ msgstr ""
|
|
2368 |
msgid "Tutor › Setup Wizard"
|
2369 |
msgstr ""
|
2370 |
|
2371 |
-
#: classes/User.php:
|
2372 |
msgid "Dismiss"
|
2373 |
msgstr ""
|
2374 |
|
2375 |
-
#: classes/Utils.php:
|
2376 |
msgid "Nonce not matched"
|
2377 |
msgstr ""
|
2378 |
|
2379 |
-
#: classes/Utils.php:
|
2380 |
msgid "Q&A"
|
2381 |
msgstr ""
|
2382 |
|
2383 |
-
#: classes/Utils.php:
|
2384 |
msgid "Course Enrolled"
|
2385 |
msgstr ""
|
2386 |
|
2387 |
-
#: classes/Utils.php:
|
2388 |
msgid "My Profile"
|
2389 |
msgstr ""
|
2390 |
|
2391 |
-
#: classes/Utils.php:
|
2392 |
msgid "Enrolled Courses"
|
2393 |
msgstr ""
|
2394 |
|
2395 |
-
#: classes/Utils.php:
|
2396 |
msgid "Wishlist"
|
2397 |
msgstr ""
|
2398 |
|
2399 |
-
#: classes/Utils.php:
|
2400 |
msgid "Reviews"
|
2401 |
msgstr ""
|
2402 |
|
2403 |
-
#: classes/Utils.php:
|
2404 |
msgid "My Quiz Attempts"
|
2405 |
msgstr ""
|
2406 |
|
2407 |
-
#: classes/Utils.php:
|
2408 |
msgid "Purchase History"
|
2409 |
msgstr ""
|
2410 |
|
2411 |
-
#: classes/Utils.php:
|
2412 |
msgid "Create Course"
|
2413 |
msgstr ""
|
2414 |
|
2415 |
-
#: classes/Utils.php:
|
2416 |
msgid "My Courses"
|
2417 |
msgstr ""
|
2418 |
|
2419 |
-
#: classes/Utils.php:
|
2420 |
msgid "Withdrawals"
|
2421 |
msgstr ""
|
2422 |
|
2423 |
-
#: classes/Utils.php:
|
2424 |
msgid "Question & Answer"
|
2425 |
msgstr ""
|
2426 |
|
2427 |
-
#: classes/Utils.php:
|
2428 |
msgid "Logout"
|
2429 |
msgstr ""
|
2430 |
|
2431 |
-
#: classes/Utils.php:
|
2432 |
msgid "Retrieve Password"
|
2433 |
msgstr ""
|
2434 |
|
2435 |
-
#: classes/Utils.php:
|
2436 |
msgid "Pending"
|
2437 |
msgstr ""
|
2438 |
|
2439 |
-
#: classes/Utils.php:
|
2440 |
msgid "Approved"
|
2441 |
msgstr ""
|
2442 |
|
2443 |
-
#: classes/Utils.php:
|
2444 |
msgid "Blocked"
|
2445 |
msgstr ""
|
2446 |
|
2447 |
-
#: classes/Utils.php:
|
2448 |
msgid "True/False"
|
2449 |
msgstr ""
|
2450 |
|
2451 |
-
#: classes/Utils.php:
|
2452 |
msgid "Single Choice"
|
2453 |
msgstr ""
|
2454 |
|
2455 |
-
#: classes/Utils.php:
|
2456 |
msgid "Multiple Choice"
|
2457 |
msgstr ""
|
2458 |
|
2459 |
-
#: classes/Utils.php:
|
2460 |
msgid "Open Ended/Essay"
|
2461 |
msgstr ""
|
2462 |
|
2463 |
-
#: classes/Utils.php:
|
2464 |
msgid "Fill In The Blanks"
|
2465 |
msgstr ""
|
2466 |
|
2467 |
-
#: classes/Utils.php:
|
2468 |
msgid "Short Answer"
|
2469 |
msgstr ""
|
2470 |
|
2471 |
-
#: classes/Utils.php:
|
2472 |
msgid "Matching"
|
2473 |
msgstr ""
|
2474 |
|
2475 |
-
#: classes/Utils.php:
|
2476 |
msgid "Image Matching"
|
2477 |
msgstr ""
|
2478 |
|
2479 |
-
#: classes/Utils.php:
|
2480 |
msgid "Image Answering"
|
2481 |
msgstr ""
|
2482 |
|
2483 |
-
#: classes/Utils.php:
|
2484 |
msgid "Ordering"
|
2485 |
msgstr ""
|
2486 |
|
2487 |
-
#: classes/Utils.php:
|
2488 |
msgid "All Levels"
|
2489 |
msgstr ""
|
2490 |
|
2491 |
-
#: classes/Utils.php:
|
2492 |
msgid "Beginner"
|
2493 |
msgstr ""
|
2494 |
|
2495 |
-
#: classes/Utils.php:
|
2496 |
msgid "Intermediate"
|
2497 |
msgstr ""
|
2498 |
|
2499 |
-
#: classes/Utils.php:
|
2500 |
msgid "Expert"
|
2501 |
msgstr ""
|
2502 |
|
2503 |
-
#: classes/Utils.php:
|
2504 |
msgid "Courses Taken"
|
2505 |
msgstr ""
|
2506 |
|
2507 |
-
#: classes/Utils.php:
|
2508 |
msgid "Enrolled Course"
|
2509 |
msgstr ""
|
2510 |
|
2511 |
-
#: classes/Utils.php:
|
2512 |
msgid "Reviews Written"
|
2513 |
msgstr ""
|
2514 |
|
2515 |
-
#: classes/Utils.php:
|
2516 |
msgid "Website URL"
|
2517 |
msgstr ""
|
2518 |
|
2519 |
-
#: classes/Utils.php:
|
2520 |
msgid "Github URL"
|
2521 |
msgstr ""
|
2522 |
|
2523 |
-
#: classes/Utils.php:
|
2524 |
msgid "Facebook URL"
|
2525 |
msgstr ""
|
2526 |
|
2527 |
-
#: classes/Utils.php:
|
2528 |
msgid "Twitter URL"
|
2529 |
msgstr ""
|
2530 |
|
2531 |
-
#: classes/Utils.php:
|
2532 |
msgid "Linkedin URL"
|
2533 |
msgstr ""
|
2534 |
|
2535 |
-
#: classes/Utils.php:
|
2536 |
msgid "Not Taken"
|
2537 |
msgstr ""
|
2538 |
|
2539 |
-
#: classes/Utils.php:
|
2540 |
msgid "In Progress"
|
2541 |
msgstr ""
|
2542 |
|
2543 |
-
#: classes/Utils.php:
|
2544 |
msgid "Completed"
|
2545 |
msgstr ""
|
2546 |
|
2547 |
-
#: classes/Utils.php:
|
2548 |
msgid "First Name"
|
2549 |
msgstr ""
|
2550 |
|
2551 |
-
#: classes/Utils.php:
|
2552 |
msgid "Last Name"
|
2553 |
msgstr ""
|
2554 |
|
2555 |
-
#: classes/Utils.php:
|
2556 |
msgid "Profile Photo"
|
2557 |
msgstr ""
|
2558 |
|
2559 |
-
#: classes/Utils.php:
|
2560 |
msgid "Withdraw Method"
|
2561 |
msgstr ""
|
2562 |
|
2563 |
-
#: classes/Withdraw.php:
|
2564 |
msgid "Bank Transfer"
|
2565 |
msgstr ""
|
2566 |
|
2567 |
-
#: classes/Withdraw.php:
|
2568 |
msgid "Get your payment directly into your bank account"
|
2569 |
msgstr ""
|
2570 |
|
2571 |
-
#: classes/Withdraw.php:
|
2572 |
msgid "Instruction"
|
2573 |
msgstr ""
|
2574 |
|
2575 |
-
#: classes/Withdraw.php:
|
2576 |
msgid "Write instruction for the instructor to fill bank information"
|
2577 |
msgstr ""
|
2578 |
|
2579 |
-
#: classes/Withdraw.php:
|
2580 |
msgid "Account Name"
|
2581 |
msgstr ""
|
2582 |
|
2583 |
-
#: classes/Withdraw.php:
|
2584 |
msgid "Account Number"
|
2585 |
msgstr ""
|
2586 |
|
2587 |
-
#: classes/Withdraw.php:
|
2588 |
msgid "Bank Name"
|
2589 |
msgstr ""
|
2590 |
|
2591 |
-
#: classes/Withdraw.php:
|
2592 |
msgid "IBAN"
|
2593 |
msgstr ""
|
2594 |
|
2595 |
-
#: classes/Withdraw.php:
|
2596 |
msgid "BIC / SWIFT"
|
2597 |
msgstr ""
|
2598 |
|
2599 |
-
#: classes/Withdraw.php:
|
2600 |
msgid "E-Check"
|
2601 |
msgstr ""
|
2602 |
|
2603 |
-
#: classes/Withdraw.php:
|
2604 |
msgid "Your Physical Address"
|
2605 |
msgstr ""
|
2606 |
|
2607 |
-
#: classes/Withdraw.php:
|
2608 |
msgid "We will send you an E-Check to this address directly."
|
2609 |
msgstr ""
|
2610 |
|
2611 |
-
#: classes/Withdraw.php:
|
2612 |
msgid "PayPal"
|
2613 |
msgstr ""
|
2614 |
|
2615 |
-
#: classes/Withdraw.php:
|
2616 |
msgid "PayPal E-Mail Address"
|
2617 |
msgstr ""
|
2618 |
|
2619 |
-
#: classes/Withdraw.php:
|
2620 |
msgid "We will use this email address to send the money to your Paypal account"
|
2621 |
msgstr ""
|
2622 |
|
2623 |
-
#: classes/Withdraw.php:
|
2624 |
msgid "Withdrawal account information saved successfully!"
|
2625 |
msgstr ""
|
2626 |
|
2627 |
-
#: classes/Withdraw.php:
|
2628 |
msgid "Please save withdraw method "
|
2629 |
msgstr ""
|
2630 |
|
2631 |
-
#: classes/Withdraw.php:
|
2632 |
-
msgid "Minimum withdrawal amount is %s %s %s "
|
2633 |
msgstr ""
|
2634 |
|
2635 |
-
#: classes/Withdraw.php:
|
2636 |
msgid "Insufficient balance."
|
2637 |
msgstr ""
|
2638 |
|
2639 |
-
#: classes/Withdraw.php:
|
2640 |
msgid "Withdrawal Request Sent!"
|
2641 |
msgstr ""
|
2642 |
|
2643 |
-
#: classes/Withdraw_Requests_List.php:
|
2644 |
msgid "Rejected"
|
2645 |
msgstr ""
|
2646 |
|
2647 |
-
#: classes/Withdraw_Requests_List.php:
|
2648 |
msgid "Are you Sure? It can not be undone."
|
2649 |
msgstr ""
|
2650 |
|
2651 |
-
#: classes/Withdraw_Requests_List.php:
|
2652 |
msgid "Delete"
|
2653 |
msgstr ""
|
2654 |
|
2655 |
-
#: classes/Withdraw_Requests_List.php:
|
2656 |
msgid "pending"
|
2657 |
msgstr ""
|
2658 |
|
2659 |
-
#: classes/Withdraw_Requests_List.php:
|
2660 |
msgid "approved"
|
2661 |
msgstr ""
|
2662 |
|
2663 |
-
#: classes/Withdraw_Requests_List.php:
|
2664 |
msgid "rejected"
|
2665 |
msgstr ""
|
2666 |
|
2667 |
-
#: classes/Withdraw_Requests_List.php:
|
2668 |
msgid "Requested By"
|
2669 |
msgstr ""
|
2670 |
|
2671 |
-
#: classes/Withdraw_Requests_List.php:
|
2672 |
msgid "Amount"
|
2673 |
msgstr ""
|
2674 |
|
2675 |
-
#: classes/Withdraw_Requests_List.php:
|
2676 |
msgid "Withdrawal Method"
|
2677 |
msgstr ""
|
2678 |
|
2679 |
-
#: classes/Withdraw_Requests_List.php:
|
2680 |
msgid "Requested Time"
|
2681 |
msgstr ""
|
2682 |
|
2683 |
-
#: classes/WooCommerce.php:
|
2684 |
msgid ""
|
2685 |
-
" Seems like you don’t have WooCommerce plugin installed on your site. In order to use this functionality, you need to have the
|
2686 |
-
" WooCommerce plugin installed. Get back on this page after installing the plugin and enable the following feature to start selling
|
2687 |
" courses with Tutor."
|
2688 |
msgstr ""
|
2689 |
|
2690 |
-
#: classes/WooCommerce.php:
|
2691 |
msgid "This notice will disappear after activating <strong>WooCommerce</strong>"
|
2692 |
msgstr ""
|
2693 |
|
2694 |
-
#: classes/WooCommerce.php:
|
2695 |
msgid "For Tutor"
|
2696 |
msgstr ""
|
2697 |
|
2698 |
-
#: classes/WooCommerce.php:
|
2699 |
msgid "This checkmark ensure that you will sell a specif course via this product."
|
2700 |
msgstr ""
|
2701 |
|
2702 |
-
#: classes/WooCommerce.php:
|
2703 |
msgid "WooCommerce"
|
2704 |
msgstr ""
|
2705 |
|
2706 |
-
#: classes/WooCommerce.php:
|
2707 |
msgid "WooCommerce Settings"
|
2708 |
msgstr ""
|
2709 |
|
2710 |
-
#: classes/WooCommerce.php:
|
2711 |
msgid "Enable add to cart feature for guest users"
|
2712 |
msgstr ""
|
2713 |
|
2714 |
-
#: classes/WooCommerce.php:
|
2715 |
msgid "Enabling this will let an unregistered user purchase any course from the Course Details page. Head over to Documentation to know how to configure this setting."
|
2716 |
msgstr ""
|
2717 |
|
2718 |
-
#: classes/WooCommerce.php:
|
2719 |
msgid "Since WooCommerce is disabled, your monetized courses have been set to free. Please make sure to enable Tutor LMS monetization if you decide to re-enable WooCommerce."
|
2720 |
msgstr ""
|
2721 |
|
@@ -2765,27 +2761,27 @@ msgstr ""
|
|
2765 |
msgid "Count"
|
2766 |
msgstr ""
|
2767 |
|
2768 |
-
#: includes/tutor-general-functions.php:
|
2769 |
msgid "Search Course Category. ex. Design, Development, Business"
|
2770 |
msgstr ""
|
2771 |
|
2772 |
-
#: includes/tutor-general-functions.php:
|
2773 |
msgid "Select a category"
|
2774 |
msgstr ""
|
2775 |
|
2776 |
-
#: includes/tutor-general-functions.php:
|
2777 |
msgid "Search Course Tags. ex. Design, Development, Business"
|
2778 |
msgstr ""
|
2779 |
|
2780 |
-
#: includes/tutor-general-functions.php:
|
2781 |
msgid "Select a tag"
|
2782 |
msgstr ""
|
2783 |
|
2784 |
-
#: includes/tutor-template-functions.php:
|
2785 |
msgid "Placeholder"
|
2786 |
msgstr ""
|
2787 |
|
2788 |
-
#: includes/tutor-template-functions.php:
|
2789 |
msgid "Share:"
|
2790 |
msgstr ""
|
2791 |
|
@@ -2881,31 +2877,31 @@ msgstr ""
|
|
2881 |
msgid "Topic not found for given ID"
|
2882 |
msgstr ""
|
2883 |
|
2884 |
-
#: templates/dashboard.php:
|
2885 |
msgid "%d Ratings"
|
2886 |
msgstr ""
|
2887 |
|
2888 |
-
#: templates/dashboard.php:
|
2889 |
msgid "Become an instructor"
|
2890 |
msgstr ""
|
2891 |
|
2892 |
-
#: templates/dashboard.php:
|
2893 |
msgid "Your Application is pending from"
|
2894 |
msgstr ""
|
2895 |
|
2896 |
-
#: templates/dashboard.php:
|
2897 |
msgid "Add A New Course"
|
2898 |
msgstr ""
|
2899 |
|
2900 |
-
#: templates/dashboard.php:
|
2901 |
msgid "Your application to become an instructor was rejected on"
|
2902 |
msgstr ""
|
2903 |
|
2904 |
-
#: templates/instructor-setting.php:
|
2905 |
msgid "Instructor List Layout"
|
2906 |
msgstr ""
|
2907 |
|
2908 |
-
#: templates/instructor-setting.php:
|
2909 |
msgid "Selected one will be used if layout is not defined as shortcode attribute."
|
2910 |
msgstr ""
|
2911 |
|
@@ -2913,91 +2909,95 @@ msgstr ""
|
|
2913 |
msgid "Please Sign-In to view this section"
|
2914 |
msgstr ""
|
2915 |
|
2916 |
-
#: templates/permission-denied.php:
|
2917 |
msgid "You don't have enough privilege to access this page"
|
2918 |
msgstr ""
|
2919 |
|
2920 |
-
#: templates/permission-denied.php:
|
2921 |
msgid "Please make sure you are logged in to correct account if the content needs authorization."
|
2922 |
msgstr ""
|
2923 |
|
2924 |
-
#: templates/public-profile-setting.php:
|
2925 |
msgid "Public Profile Layout"
|
2926 |
msgstr ""
|
2927 |
|
2928 |
-
#: templates/public-profile-setting.php:
|
2929 |
msgid "Selected one will be used as public profile layout."
|
2930 |
msgstr ""
|
2931 |
|
2932 |
-
#: templates/single-preview-lesson.php:
|
2933 |
msgid "Lesson List"
|
2934 |
msgstr ""
|
2935 |
|
2936 |
-
#: templates/single-preview-lesson.php:
|
2937 |
msgid "Go to Course Home"
|
2938 |
msgstr ""
|
2939 |
|
2940 |
-
#: templates/student-public-profile.php:
|
2941 |
msgid "Courses Enrolled"
|
2942 |
msgstr ""
|
2943 |
|
2944 |
-
#: templates/student-public-profile.php:
|
2945 |
msgid "Courses Completed"
|
2946 |
msgstr ""
|
2947 |
|
2948 |
-
#: templates/student-public-profile.php:
|
2949 |
msgid "Course Completed"
|
2950 |
msgstr ""
|
2951 |
|
2952 |
-
#: templates/student-public-profile.php:
|
2953 |
msgid "Biography"
|
2954 |
msgstr ""
|
2955 |
|
2956 |
-
#: templates/course-filter/filters.php:9, templates/dashboard/create-course.php:
|
2957 |
msgid "Free"
|
2958 |
msgstr ""
|
2959 |
|
2960 |
-
#: templates/course-filter/filters.php:10, views/metabox/course-add-edd-product-metabox.php:
|
2961 |
msgid "Paid"
|
2962 |
msgstr ""
|
2963 |
|
|
|
|
|
|
|
|
|
2964 |
#: templates/course-filter/filters.php:54
|
2965 |
msgid "Level"
|
2966 |
msgstr ""
|
2967 |
|
2968 |
-
#: templates/dashboard/announcements.php:
|
2969 |
msgid "Announcement"
|
2970 |
msgstr ""
|
2971 |
|
2972 |
-
#: templates/dashboard/announcements.php:
|
2973 |
msgid "Create Announcement"
|
2974 |
msgstr ""
|
2975 |
|
2976 |
-
#: templates/dashboard/announcements.php:
|
2977 |
msgid "Notify all students of your course"
|
2978 |
msgstr ""
|
2979 |
|
2980 |
-
#: templates/dashboard/announcements.php:
|
2981 |
msgid "Add New Announcement"
|
2982 |
msgstr ""
|
2983 |
|
2984 |
-
#: templates/dashboard/announcements.php:
|
2985 |
msgid "ASC"
|
2986 |
msgstr ""
|
2987 |
|
2988 |
-
#: templates/dashboard/announcements.php:
|
2989 |
msgid "DESC"
|
2990 |
msgstr ""
|
2991 |
|
2992 |
-
#: templates/dashboard/announcements.php:
|
2993 |
msgid "Announcements not found"
|
2994 |
msgstr ""
|
2995 |
|
2996 |
-
#: templates/dashboard/announcements.php:
|
2997 |
msgid "Details"
|
2998 |
msgstr ""
|
2999 |
|
3000 |
-
#: templates/dashboard/announcements.php:
|
3001 |
msgid "Edit"
|
3002 |
msgstr ""
|
3003 |
|
@@ -3005,131 +3005,127 @@ msgstr ""
|
|
3005 |
msgid "Create Date"
|
3006 |
msgstr ""
|
3007 |
|
3008 |
-
#: templates/dashboard/assignments.php:
|
3009 |
msgid "No assignment available"
|
3010 |
msgstr ""
|
3011 |
|
3012 |
-
#: templates/dashboard/assignments.php:
|
3013 |
msgid "Course Name"
|
3014 |
msgstr ""
|
3015 |
|
3016 |
-
#: templates/dashboard/assignments.php:
|
3017 |
msgid "Total Points"
|
3018 |
msgstr ""
|
3019 |
|
3020 |
-
#: templates/dashboard/assignments.php:
|
3021 |
msgid "Total Submits"
|
3022 |
msgstr ""
|
3023 |
|
3024 |
-
#: templates/dashboard/
|
3025 |
-
msgid "Course: "
|
3026 |
-
msgstr ""
|
3027 |
-
|
3028 |
-
#: templates/dashboard/create-course.php:25
|
3029 |
msgid "You don't have the right to edit this course"
|
3030 |
msgstr ""
|
3031 |
|
3032 |
-
#: templates/dashboard/create-course.php:
|
3033 |
msgid "Please make sure you are logged in to correct account"
|
3034 |
msgstr ""
|
3035 |
|
3036 |
-
#: templates/dashboard/create-course.php:
|
3037 |
msgid "Save"
|
3038 |
msgstr ""
|
3039 |
|
3040 |
-
#: templates/dashboard/create-course.php:
|
3041 |
msgid "Preview"
|
3042 |
msgstr ""
|
3043 |
|
3044 |
-
#: templates/dashboard/create-course.php:
|
3045 |
msgid "Submit for Review"
|
3046 |
msgstr ""
|
3047 |
|
3048 |
-
#: templates/dashboard/create-course.php:
|
3049 |
msgid "Publish Course"
|
3050 |
msgstr ""
|
3051 |
|
3052 |
-
#: templates/dashboard/create-course.php:
|
3053 |
msgid "Exit"
|
3054 |
msgstr ""
|
3055 |
|
3056 |
-
#: templates/dashboard/create-course.php:
|
3057 |
msgid "Course Info"
|
3058 |
msgstr ""
|
3059 |
|
3060 |
-
#: templates/dashboard/create-course.php:
|
3061 |
msgid "Course Title"
|
3062 |
msgstr ""
|
3063 |
|
3064 |
-
#: templates/dashboard/create-course.php:
|
3065 |
msgid "ex. Learn photoshop CS6 from scratch"
|
3066 |
msgstr ""
|
3067 |
|
3068 |
-
#: templates/dashboard/create-course.php:
|
3069 |
msgid "Description"
|
3070 |
msgstr ""
|
3071 |
|
3072 |
-
#: templates/dashboard/create-course.php:
|
3073 |
msgid "Choose a category"
|
3074 |
msgstr ""
|
3075 |
|
3076 |
-
#: templates/dashboard/create-course.php:
|
3077 |
msgid "Choose a tag"
|
3078 |
msgstr ""
|
3079 |
|
3080 |
-
#: templates/dashboard/create-course.php:
|
3081 |
msgid "Course Price"
|
3082 |
msgstr ""
|
3083 |
|
3084 |
-
#: templates/dashboard/create-course.php:
|
3085 |
msgid "Set course price"
|
3086 |
msgstr ""
|
3087 |
|
3088 |
-
#: templates/dashboard/create-course.php:
|
3089 |
msgid "Course Thumbnail"
|
3090 |
msgstr ""
|
3091 |
|
3092 |
-
#: templates/dashboard/create-course.php:
|
3093 |
msgid "Important Guideline: %1$s 700x430 pixels %2$s %3$s File Support: %1$s jpg, .jpeg,. gif, or .png %2$s no text on the image."
|
3094 |
msgstr ""
|
3095 |
|
3096 |
-
#: templates/dashboard/create-course.php:
|
3097 |
msgid "Upload Image"
|
3098 |
msgstr ""
|
3099 |
|
3100 |
-
#: templates/dashboard/create-course.php:
|
3101 |
msgid "Save course as draft"
|
3102 |
msgstr ""
|
3103 |
|
3104 |
-
#: templates/dashboard/create-course.php:
|
3105 |
msgid "Course Upload Tips"
|
3106 |
msgstr ""
|
3107 |
|
3108 |
-
#: templates/dashboard/create-course.php:
|
3109 |
msgid "Set the Course Price option or make it free."
|
3110 |
msgstr ""
|
3111 |
|
3112 |
-
#: templates/dashboard/create-course.php:
|
3113 |
msgid "Standard size for the course thumbnail is 700x430."
|
3114 |
msgstr ""
|
3115 |
|
3116 |
-
#: templates/dashboard/create-course.php:
|
3117 |
msgid "Video section controls the course overview video."
|
3118 |
msgstr ""
|
3119 |
|
3120 |
-
#: templates/dashboard/create-course.php:
|
3121 |
msgid "Course Builder is where you create & organize a course."
|
3122 |
msgstr ""
|
3123 |
|
3124 |
-
#: templates/dashboard/create-course.php:
|
3125 |
msgid "Add Topics in the Course Builder section to create lessons, quizzes, and assignments."
|
3126 |
msgstr ""
|
3127 |
|
3128 |
-
#: templates/dashboard/create-course.php:
|
3129 |
msgid "Prerequisites refers to the fundamental courses to complete before taking this particular course."
|
3130 |
msgstr ""
|
3131 |
|
3132 |
-
#: templates/dashboard/create-course.php:
|
3133 |
msgid "Information from the Additional Data section shows up on the course single page."
|
3134 |
msgstr ""
|
3135 |
|
@@ -3153,19 +3149,19 @@ msgstr ""
|
|
3153 |
msgid "Total Students"
|
3154 |
msgstr ""
|
3155 |
|
3156 |
-
#: templates/dashboard/dashboard.php:
|
3157 |
msgid "Total Courses"
|
3158 |
msgstr ""
|
3159 |
|
3160 |
-
#: templates/dashboard/dashboard.php:
|
3161 |
msgid "Total Earnings"
|
3162 |
msgstr ""
|
3163 |
|
3164 |
-
#: templates/dashboard/dashboard.php:
|
3165 |
msgid "Most Popular Courses"
|
3166 |
msgstr ""
|
3167 |
|
3168 |
-
#: templates/dashboard/dashboard.php:
|
3169 |
msgid "Enrolled"
|
3170 |
msgstr ""
|
3171 |
|
@@ -3181,7 +3177,7 @@ msgstr ""
|
|
3181 |
msgid "Reports"
|
3182 |
msgstr ""
|
3183 |
|
3184 |
-
#: templates/dashboard/earning.php:53, templates/dashboard/earning/report.php:
|
3185 |
msgid "Statements"
|
3186 |
msgstr ""
|
3187 |
|
@@ -3197,11 +3193,11 @@ msgstr ""
|
|
3197 |
msgid "My Earnings"
|
3198 |
msgstr ""
|
3199 |
|
3200 |
-
#: templates/dashboard/earning.php:72, templates/dashboard/earning/report-date_range.php:41, templates/dashboard/earning/report-last_month.php:40, templates/dashboard/earning/report-last_week.php:44, templates/dashboard/earning/report-last_year.php:40, templates/dashboard/earning/report-this_month.php:
|
3201 |
msgid "Based on course price"
|
3202 |
msgstr ""
|
3203 |
|
3204 |
-
#: templates/dashboard/earning.php:74, templates/dashboard/earning/report-date_range.php:43, templates/dashboard/earning/report-last_month.php:42, templates/dashboard/earning/report-last_week.php:46, templates/dashboard/earning/report-last_year.php:42, templates/dashboard/earning/report-this_month.php:
|
3205 |
msgid "All time sales"
|
3206 |
msgstr ""
|
3207 |
|
@@ -3213,7 +3209,7 @@ msgstr ""
|
|
3213 |
msgid "All time withdrawals"
|
3214 |
msgstr ""
|
3215 |
|
3216 |
-
#: templates/dashboard/earning.php:86, templates/dashboard/earning/report-date_range.php:49, templates/dashboard/earning/report-last_month.php:48, templates/dashboard/earning/report-last_week.php:52, templates/dashboard/earning/report-last_year.php:48, templates/dashboard/earning/report-this_month.php:
|
3217 |
msgid "Deducted Commissions"
|
3218 |
msgstr ""
|
3219 |
|
@@ -3229,15 +3225,15 @@ msgstr ""
|
|
3229 |
msgid "All Courses"
|
3230 |
msgstr ""
|
3231 |
|
3232 |
-
#: templates/dashboard/enrolled-courses.php:
|
3233 |
msgid "You haven't purchased any course"
|
3234 |
msgstr ""
|
3235 |
|
3236 |
-
#: templates/dashboard/enrolled-courses.php:
|
3237 |
msgid "Total Lessons:"
|
3238 |
msgstr ""
|
3239 |
|
3240 |
-
#: templates/dashboard/enrolled-courses.php:
|
3241 |
msgid "Completed Lessons:"
|
3242 |
msgstr ""
|
3243 |
|
@@ -3245,11 +3241,11 @@ msgstr ""
|
|
3245 |
msgid "You are already logged in"
|
3246 |
msgstr ""
|
3247 |
|
3248 |
-
#: templates/dashboard/my-courses.php:
|
3249 |
msgid "Not Found"
|
3250 |
msgstr ""
|
3251 |
|
3252 |
-
#: templates/dashboard/my-courses.php:
|
3253 |
msgid "Sorry, but you are looking for something that isn't here."
|
3254 |
msgstr ""
|
3255 |
|
@@ -3269,19 +3265,19 @@ msgstr ""
|
|
3269 |
msgid "View"
|
3270 |
msgstr ""
|
3271 |
|
3272 |
-
#: templates/dashboard/my-courses.php:
|
3273 |
msgid "Delete This Course?"
|
3274 |
msgstr ""
|
3275 |
|
3276 |
-
#: templates/dashboard/my-courses.php:
|
3277 |
msgid "You are going to delete this course, it can't be undone"
|
3278 |
msgstr ""
|
3279 |
|
3280 |
-
#: templates/dashboard/my-courses.php:
|
3281 |
msgid "Cancel"
|
3282 |
msgstr ""
|
3283 |
|
3284 |
-
#: templates/dashboard/my-courses.php:
|
3285 |
msgid "Yes, Delete Course"
|
3286 |
msgstr ""
|
3287 |
|
@@ -3289,47 +3285,47 @@ msgstr ""
|
|
3289 |
msgid "Registration Date"
|
3290 |
msgstr ""
|
3291 |
|
3292 |
-
#: templates/dashboard/my-profile.php:
|
3293 |
msgid "Username"
|
3294 |
msgstr ""
|
3295 |
|
3296 |
-
#: templates/dashboard/my-profile.php:
|
3297 |
msgid "Email"
|
3298 |
msgstr ""
|
3299 |
|
3300 |
-
#: templates/dashboard/my-profile.php:
|
3301 |
msgid "Phone Number"
|
3302 |
msgstr ""
|
3303 |
|
3304 |
-
#: templates/dashboard/my-profile.php:
|
3305 |
msgid "Bio"
|
3306 |
msgstr ""
|
3307 |
|
3308 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3309 |
msgid "You have not attempted any quiz yet"
|
3310 |
msgstr ""
|
3311 |
|
3312 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3313 |
msgid "Correct Answer"
|
3314 |
msgstr ""
|
3315 |
|
3316 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3317 |
msgid "Incorrect Answer"
|
3318 |
msgstr ""
|
3319 |
|
3320 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3321 |
msgid "Earned Marks"
|
3322 |
msgstr ""
|
3323 |
|
3324 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3325 |
msgid "Result"
|
3326 |
msgstr ""
|
3327 |
|
3328 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3329 |
msgid "Question: "
|
3330 |
msgstr ""
|
3331 |
|
3332 |
-
#: templates/dashboard/my-quiz-attempts.php:
|
3333 |
msgid "Total Marks: "
|
3334 |
msgstr ""
|
3335 |
|
@@ -3337,27 +3333,23 @@ msgstr ""
|
|
3337 |
msgid "No purchase history available"
|
3338 |
msgstr ""
|
3339 |
|
3340 |
-
#: templates/dashboard/
|
3341 |
-
msgid "ID"
|
3342 |
-
msgstr ""
|
3343 |
-
|
3344 |
-
#: templates/dashboard/question-answer.php:83
|
3345 |
msgid "No question is available"
|
3346 |
msgstr ""
|
3347 |
|
3348 |
-
#: templates/dashboard/question-answer.php:
|
3349 |
msgid "Delete This Question?"
|
3350 |
msgstr ""
|
3351 |
|
3352 |
-
#: templates/dashboard/question-answer.php:
|
3353 |
msgid "You are going to delete this question, it can't be undone"
|
3354 |
msgstr ""
|
3355 |
|
3356 |
-
#: templates/dashboard/question-answer.php:
|
3357 |
msgid "Yes, Delete Question"
|
3358 |
msgstr ""
|
3359 |
|
3360 |
-
#: templates/dashboard/quiz-attempts.php:
|
3361 |
msgid "No quiz attempt yet."
|
3362 |
msgstr ""
|
3363 |
|
@@ -3365,23 +3357,23 @@ msgstr ""
|
|
3365 |
msgid "Earned Mark"
|
3366 |
msgstr ""
|
3367 |
|
3368 |
-
#: templates/dashboard/registration.php:
|
3369 |
msgid "User Name"
|
3370 |
msgstr ""
|
3371 |
|
3372 |
-
#: templates/dashboard/registration.php:
|
3373 |
msgid "Password"
|
3374 |
msgstr ""
|
3375 |
|
3376 |
-
#: templates/dashboard/registration.php:
|
3377 |
msgid "Password confirmation"
|
3378 |
msgstr ""
|
3379 |
|
3380 |
-
#: templates/dashboard/registration.php:
|
3381 |
msgid "Password Confirmation"
|
3382 |
msgstr ""
|
3383 |
|
3384 |
-
#: templates/dashboard/registration.php:
|
3385 |
msgid "Register"
|
3386 |
msgstr ""
|
3387 |
|
@@ -3406,10 +3398,14 @@ msgid "Given"
|
|
3406 |
msgstr ""
|
3407 |
|
3408 |
#: templates/dashboard/reviews.php:51
|
3409 |
-
msgid "Showing results %d to %d out of %d"
|
|
|
|
|
|
|
|
|
3410 |
msgstr ""
|
3411 |
|
3412 |
-
#: templates/dashboard/reviews.php:72, templates/profile/reviews_wrote.php:
|
3413 |
msgid "%s ago"
|
3414 |
msgstr ""
|
3415 |
|
@@ -3425,63 +3421,63 @@ msgstr ""
|
|
3425 |
msgid "Withdrawal request is pending for approval, please hold tight."
|
3426 |
msgstr ""
|
3427 |
|
3428 |
-
#: templates/dashboard/withdraw.php:
|
3429 |
msgid "Current Balance"
|
3430 |
msgstr ""
|
3431 |
|
3432 |
-
#: templates/dashboard/withdraw.php:
|
3433 |
-
msgid "You currently have %s %s %s and this is insufficient balance to withdraw"
|
3434 |
msgstr ""
|
3435 |
|
3436 |
-
#: templates/dashboard/withdraw.php:
|
3437 |
-
msgid "You currently have %s %s %s ready to withdraw"
|
3438 |
msgstr ""
|
3439 |
|
3440 |
-
#: templates/dashboard/withdraw.php:
|
3441 |
msgid "Withdrawal Request"
|
3442 |
msgstr ""
|
3443 |
|
3444 |
-
#: templates/dashboard/withdraw.php:
|
3445 |
msgid "The preferred payment method is selected as %s. "
|
3446 |
msgstr ""
|
3447 |
|
3448 |
-
#: templates/dashboard/withdraw.php:
|
3449 |
-
msgid "You can change your %s withdrawal preference %s"
|
3450 |
msgstr ""
|
3451 |
|
3452 |
-
#: templates/dashboard/withdraw.php:
|
3453 |
msgid "Your withdrawal request has been successfully accepted"
|
3454 |
msgstr ""
|
3455 |
|
3456 |
-
#: templates/dashboard/withdraw.php:
|
3457 |
msgid "Please check your transaction notification on your connected withdrawal method"
|
3458 |
msgstr ""
|
3459 |
|
3460 |
-
#: templates/dashboard/withdraw.php:
|
3461 |
msgid "Please enter withdrawal amount and click the submit request button"
|
3462 |
msgstr ""
|
3463 |
|
3464 |
-
#: templates/dashboard/withdraw.php:
|
3465 |
msgid "Selected Payment Method"
|
3466 |
msgstr ""
|
3467 |
|
3468 |
-
#: templates/dashboard/withdraw.php:
|
3469 |
msgid "Minimum withdraw amount is"
|
3470 |
msgstr ""
|
3471 |
|
3472 |
-
#: templates/dashboard/withdraw.php:
|
3473 |
msgid "Submit Request"
|
3474 |
msgstr ""
|
3475 |
|
3476 |
-
#: templates/dashboard/withdraw.php:
|
3477 |
msgid "Withdrawal History"
|
3478 |
msgstr ""
|
3479 |
|
3480 |
-
#: templates/dashboard/withdraw.php:
|
3481 |
msgid "No withdrawal yet"
|
3482 |
msgstr ""
|
3483 |
|
3484 |
-
#: templates/dashboard/withdraw.php:
|
3485 |
msgid "Requested On"
|
3486 |
msgstr ""
|
3487 |
|
@@ -3521,39 +3517,39 @@ msgstr ""
|
|
3521 |
msgid "Release Date (newest first)"
|
3522 |
msgstr ""
|
3523 |
|
3524 |
-
#: templates/global/course-archive-filter-bar.php:
|
3525 |
msgid "Release Date (oldest first)"
|
3526 |
msgstr ""
|
3527 |
|
3528 |
-
#: templates/global/course-archive-filter-bar.php:
|
3529 |
msgid "Course Title (a-z)"
|
3530 |
msgstr ""
|
3531 |
|
3532 |
-
#: templates/global/course-archive-filter-bar.php:
|
3533 |
msgid "Course Title (z-a)"
|
3534 |
msgstr ""
|
3535 |
|
3536 |
-
#: templates/global/login.php:
|
3537 |
msgid "Username or Email Address"
|
3538 |
msgstr ""
|
3539 |
|
3540 |
-
#: templates/global/login.php:
|
3541 |
msgid "Remember Me"
|
3542 |
msgstr ""
|
3543 |
|
3544 |
-
#: templates/global/login.php:
|
3545 |
msgid "Log In"
|
3546 |
msgstr ""
|
3547 |
|
3548 |
-
#: templates/global/login.php:
|
3549 |
msgid "Create a new account"
|
3550 |
msgstr ""
|
3551 |
|
3552 |
-
#: templates/global/login.php:
|
3553 |
msgid "Forgot Password?"
|
3554 |
msgstr ""
|
3555 |
|
3556 |
-
#: templates/loop/course-continue.php:18, templates/single/course/course-enrolled-box.php:
|
3557 |
msgid "Continue Course"
|
3558 |
msgstr ""
|
3559 |
|
@@ -3561,7 +3557,7 @@ msgstr ""
|
|
3561 |
msgid "View Cart"
|
3562 |
msgstr ""
|
3563 |
|
3564 |
-
#: templates/loop/course-price-edd.php:
|
3565 |
msgid "Get Enrolled"
|
3566 |
msgstr ""
|
3567 |
|
@@ -3569,11 +3565,11 @@ msgstr ""
|
|
3569 |
msgid "Start Learning "
|
3570 |
msgstr ""
|
3571 |
|
3572 |
-
#: templates/loop/meta.php:
|
3573 |
msgid "by"
|
3574 |
msgstr ""
|
3575 |
|
3576 |
-
#: templates/loop/meta.php:
|
3577 |
msgid "In"
|
3578 |
msgstr ""
|
3579 |
|
@@ -3585,23 +3581,23 @@ msgstr ""
|
|
3585 |
msgid "No course yet."
|
3586 |
msgstr ""
|
3587 |
|
3588 |
-
#: templates/profile/reviews_wrote.php:
|
3589 |
msgid "No review yet."
|
3590 |
msgstr ""
|
3591 |
|
3592 |
-
#: templates/profile/reviews_wrote.php:
|
3593 |
msgid "On"
|
3594 |
msgstr ""
|
3595 |
|
3596 |
-
#: templates/shortcode/instructor-filter.php:
|
3597 |
msgid "Clear All"
|
3598 |
msgstr ""
|
3599 |
|
3600 |
-
#: templates/shortcode/instructor-filter.php:
|
3601 |
msgid "Search any instructor..."
|
3602 |
msgstr ""
|
3603 |
|
3604 |
-
#: templates/shortcode/instructor-filter.php:
|
3605 |
msgid "Apply Filter"
|
3606 |
msgstr ""
|
3607 |
|
@@ -3637,19 +3633,19 @@ msgstr ""
|
|
3637 |
msgid "When selling the course"
|
3638 |
msgstr ""
|
3639 |
|
3640 |
-
#: views/metabox/course-add-edd-product-metabox.php:
|
3641 |
msgid "Sell your product, process by EDD"
|
3642 |
msgstr ""
|
3643 |
|
3644 |
-
#: views/metabox/course-add-edd-product-metabox.php:
|
3645 |
msgid "Course Type"
|
3646 |
msgstr ""
|
3647 |
|
3648 |
-
#: views/metabox/course-add-product-metabox.php:
|
3649 |
msgid "Edit attached Product"
|
3650 |
msgstr ""
|
3651 |
|
3652 |
-
#: views/metabox/course-add-product-metabox.php:
|
3653 |
msgid "Select a product if you want to sell your course. The sale will be handled by your preferred monetization option. (WooCommerce, EDD, Paid Memberships Pro)"
|
3654 |
msgstr ""
|
3655 |
|
@@ -3657,15 +3653,15 @@ msgstr ""
|
|
3657 |
msgid "Total Course Duration"
|
3658 |
msgstr ""
|
3659 |
|
3660 |
-
#: views/metabox/course-additional-data.php:26, views/metabox/video-metabox.php:
|
3661 |
msgid "HH"
|
3662 |
msgstr ""
|
3663 |
|
3664 |
-
#: views/metabox/course-additional-data.php:30, views/metabox/video-metabox.php:
|
3665 |
msgid "MM"
|
3666 |
msgstr ""
|
3667 |
|
3668 |
-
#: views/metabox/course-additional-data.php:35, views/metabox/video-metabox.php:
|
3669 |
msgid "SS"
|
3670 |
msgstr ""
|
3671 |
|
@@ -3673,89 +3669,89 @@ msgstr ""
|
|
3673 |
msgid "Benefits of the course"
|
3674 |
msgstr ""
|
3675 |
|
3676 |
-
#: views/metabox/course-additional-data.php:
|
3677 |
msgid ""
|
3678 |
"List the knowledge and skills that students will learn after completing this course. (One per line)\n"
|
3679 |
""
|
3680 |
msgstr ""
|
3681 |
|
3682 |
-
#: views/metabox/course-additional-data.php:
|
3683 |
msgid "Requirements/Instructions"
|
3684 |
msgstr ""
|
3685 |
|
3686 |
-
#: views/metabox/course-additional-data.php:
|
3687 |
msgid "Additional requirements or special instructions for the students (One per line)"
|
3688 |
msgstr ""
|
3689 |
|
3690 |
-
#: views/metabox/course-additional-data.php:
|
3691 |
msgid "Targeted Audience"
|
3692 |
msgstr ""
|
3693 |
|
3694 |
-
#: views/metabox/course-additional-data.php:
|
3695 |
msgid "Specify the target audience that will benefit the most from the course. (One line per target audience.)"
|
3696 |
msgstr ""
|
3697 |
|
3698 |
-
#: views/metabox/course-additional-data.php:
|
3699 |
msgid "Materials Included"
|
3700 |
msgstr ""
|
3701 |
|
3702 |
-
#: views/metabox/course-additional-data.php:
|
3703 |
msgid "A list of assets you will be providing for the students in this course (One per line)"
|
3704 |
msgstr ""
|
3705 |
|
3706 |
-
#: views/metabox/course-contents.php:
|
3707 |
msgid "Add a topic to build your course"
|
3708 |
msgstr ""
|
3709 |
|
3710 |
-
#: views/metabox/course-contents.php:
|
3711 |
msgid "Delete Topic"
|
3712 |
msgstr ""
|
3713 |
|
3714 |
-
#: views/metabox/course-contents.php:
|
3715 |
msgid "Topic Name"
|
3716 |
msgstr ""
|
3717 |
|
3718 |
-
#: views/metabox/course-contents.php:
|
3719 |
msgid "Topic title will be publicly show where required, you can call it as a section also in course"
|
3720 |
msgstr ""
|
3721 |
|
3722 |
-
#: views/metabox/course-contents.php:
|
3723 |
msgid "Topic Summary"
|
3724 |
msgstr ""
|
3725 |
|
3726 |
-
#: views/metabox/course-contents.php:
|
3727 |
msgid "The idea of a summary is a short text to prepare students for the activities within the topic or week. The text is shown on the course page under the topic name."
|
3728 |
msgstr ""
|
3729 |
|
3730 |
-
#: views/metabox/course-contents.php:
|
3731 |
msgid "Update Topic"
|
3732 |
msgstr ""
|
3733 |
|
3734 |
-
#: views/metabox/course-contents.php:
|
3735 |
msgid "Lesson"
|
3736 |
msgstr ""
|
3737 |
|
3738 |
-
#: views/metabox/course-topics.php:
|
3739 |
msgid "Expand all"
|
3740 |
msgstr ""
|
3741 |
|
3742 |
-
#: views/metabox/course-topics.php:
|
3743 |
msgid "Collapse all"
|
3744 |
msgstr ""
|
3745 |
|
3746 |
-
#: views/metabox/course-topics.php:
|
3747 |
msgid "Add new topic"
|
3748 |
msgstr ""
|
3749 |
|
3750 |
-
#: views/metabox/course-topics.php:
|
3751 |
msgid "Add Topic"
|
3752 |
msgstr ""
|
3753 |
|
3754 |
-
#: views/metabox/course-topics.php:
|
3755 |
msgid "Topic titles are displayed publicly wherever required. Each topic may contain one or more lessons, quiz and assignments."
|
3756 |
msgstr ""
|
3757 |
|
3758 |
-
#: views/metabox/course-topics.php:
|
3759 |
msgid "Zoom Meeting"
|
3760 |
msgstr ""
|
3761 |
|
@@ -3767,15 +3763,15 @@ msgstr ""
|
|
3767 |
msgid "Add More Instructors"
|
3768 |
msgstr ""
|
3769 |
|
3770 |
-
#: views/metabox/instructors-metabox.php:
|
3771 |
msgid "Add instructors"
|
3772 |
msgstr ""
|
3773 |
|
3774 |
-
#: views/metabox/instructors-metabox.php:
|
3775 |
msgid "Search instructors..."
|
3776 |
msgstr ""
|
3777 |
|
3778 |
-
#: views/metabox/instructors-metabox.php:
|
3779 |
msgid "Add Instructors"
|
3780 |
msgstr ""
|
3781 |
|
@@ -3787,7 +3783,7 @@ msgstr ""
|
|
3787 |
msgid "Select a course"
|
3788 |
msgstr ""
|
3789 |
|
3790 |
-
#: views/metabox/lesson-metabox.php:
|
3791 |
msgid "Choose the course for this lesson"
|
3792 |
msgstr ""
|
3793 |
|
@@ -3811,92 +3807,92 @@ msgstr ""
|
|
3811 |
msgid "Upload"
|
3812 |
msgstr ""
|
3813 |
|
3814 |
-
#: views/metabox/video-metabox.php:
|
3815 |
msgid "Video Source"
|
3816 |
msgstr ""
|
3817 |
|
3818 |
-
#: views/metabox/video-metabox.php:
|
3819 |
msgid "Course Intro Video"
|
3820 |
msgstr ""
|
3821 |
|
3822 |
-
#: views/metabox/video-metabox.php:
|
3823 |
msgid "Select Video Source"
|
3824 |
msgstr ""
|
3825 |
|
3826 |
-
#: views/metabox/video-metabox.php:
|
3827 |
msgid "Select your preferred video type."
|
3828 |
msgstr ""
|
3829 |
|
3830 |
-
#: views/metabox/video-metabox.php:
|
3831 |
msgid "Upload Video"
|
3832 |
msgstr ""
|
3833 |
|
3834 |
-
#: views/metabox/video-metabox.php:
|
3835 |
msgid "Media ID"
|
3836 |
msgstr ""
|
3837 |
|
3838 |
-
#: views/metabox/video-metabox.php:
|
3839 |
msgid "Video Poster"
|
3840 |
msgstr ""
|
3841 |
|
3842 |
-
#: views/metabox/video-metabox.php:
|
3843 |
msgid "Thumb Size: 700x430 pixels. File Support: jpg, jpeg, or png"
|
3844 |
msgstr ""
|
3845 |
|
3846 |
-
#: views/metabox/video-metabox.php:
|
3847 |
msgid "External Video URL"
|
3848 |
msgstr ""
|
3849 |
|
3850 |
-
#: views/metabox/video-metabox.php:
|
3851 |
msgid "YouTube Video URL"
|
3852 |
msgstr ""
|
3853 |
|
3854 |
-
#: views/metabox/video-metabox.php:
|
3855 |
msgid "Vimeo Video URL"
|
3856 |
msgstr ""
|
3857 |
|
3858 |
-
#: views/metabox/video-metabox.php:
|
3859 |
msgid "Place your embedded code here"
|
3860 |
msgstr ""
|
3861 |
|
3862 |
-
#: views/metabox/video-metabox.php:
|
3863 |
msgid "Video playback time"
|
3864 |
msgstr ""
|
3865 |
|
3866 |
-
#: views/modal/add_quiz.php:
|
3867 |
msgid "Quiz Info"
|
3868 |
msgstr ""
|
3869 |
|
3870 |
-
#: views/modal/add_quiz.php:
|
3871 |
msgid "Questions"
|
3872 |
msgstr ""
|
3873 |
|
3874 |
-
#: views/modal/add_quiz.php:
|
3875 |
msgid "Advanced Options"
|
3876 |
msgstr ""
|
3877 |
|
3878 |
-
#: views/modal/add_quiz.php:
|
3879 |
msgid "Type your quiz title here"
|
3880 |
msgstr ""
|
3881 |
|
3882 |
-
#: views/modal/add_quiz.php:
|
3883 |
msgid "Save & Next"
|
3884 |
msgstr ""
|
3885 |
|
3886 |
-
#: views/modal/add_quiz.php:
|
3887 |
msgid "Back"
|
3888 |
msgstr ""
|
3889 |
|
3890 |
-
#: views/modal/add_quiz.php:
|
3891 |
msgid "Knowledge Base"
|
3892 |
msgstr ""
|
3893 |
|
3894 |
-
#: views/modal/add_quiz.php:
|
3895 |
msgid "Documentation"
|
3896 |
msgstr ""
|
3897 |
|
3898 |
-
#: views/modal/add_quiz.php:
|
3899 |
-
msgid "Need any Help? Please visit our %s and %s."
|
3900 |
msgstr ""
|
3901 |
|
3902 |
#: views/modal/edit-lesson.php:25
|
@@ -3923,279 +3919,279 @@ msgstr ""
|
|
3923 |
msgid "Update Lesson"
|
3924 |
msgstr ""
|
3925 |
|
3926 |
-
#: views/modal/edit_quiz.php:
|
3927 |
msgid "Add Question"
|
3928 |
msgstr ""
|
3929 |
|
3930 |
-
#: views/modal/edit_quiz.php:
|
3931 |
msgid "Hide quiz time - display"
|
3932 |
msgstr ""
|
3933 |
|
3934 |
-
#: views/modal/edit_quiz.php:
|
3935 |
msgid "Time limit for this quiz. 0 means no time limit."
|
3936 |
msgstr ""
|
3937 |
|
3938 |
-
#: views/modal/edit_quiz.php:
|
3939 |
msgid "Quiz Feedback Mode"
|
3940 |
msgstr ""
|
3941 |
|
3942 |
-
#: views/modal/edit_quiz.php:
|
3943 |
msgid "Pick the quiz system\"s behaviour on choice based questions"
|
3944 |
msgstr ""
|
3945 |
|
3946 |
-
#: views/modal/edit_quiz.php:
|
3947 |
msgid "Default"
|
3948 |
msgstr ""
|
3949 |
|
3950 |
-
#: views/modal/edit_quiz.php:
|
3951 |
msgid "Answers shown after quiz is finished"
|
3952 |
msgstr ""
|
3953 |
|
3954 |
-
#: views/modal/edit_quiz.php:
|
3955 |
msgid "Retry Mode"
|
3956 |
msgstr ""
|
3957 |
|
3958 |
-
#: views/modal/edit_quiz.php:
|
3959 |
msgid "Unlimited attempts on each question."
|
3960 |
msgstr ""
|
3961 |
|
3962 |
-
#: views/modal/edit_quiz.php:
|
3963 |
msgid "Reveal Mode"
|
3964 |
msgstr ""
|
3965 |
|
3966 |
-
#: views/modal/edit_quiz.php:
|
3967 |
msgid "Show result after the attempt."
|
3968 |
msgstr ""
|
3969 |
|
3970 |
-
#: views/modal/edit_quiz.php:
|
3971 |
msgid "Optional"
|
3972 |
msgstr ""
|
3973 |
|
3974 |
-
#: views/modal/edit_quiz.php:
|
3975 |
msgid "Restriction on the number of attempts a student is allowed to take for this quiz. 0 for no limit"
|
3976 |
msgstr ""
|
3977 |
|
3978 |
-
#: views/modal/edit_quiz.php:
|
3979 |
msgid "Passing Grade (%)"
|
3980 |
msgstr ""
|
3981 |
|
3982 |
-
#: views/modal/edit_quiz.php:
|
3983 |
msgid "Set the passing percentage for this quiz"
|
3984 |
msgstr ""
|
3985 |
|
3986 |
-
#: views/modal/edit_quiz.php:
|
3987 |
msgid "Max questions allowed to answer"
|
3988 |
msgstr ""
|
3989 |
|
3990 |
-
#: views/modal/edit_quiz.php:
|
3991 |
msgid "This amount of question will be available for students to answer, and question will comes randomly from all available questions belongs with a quiz, if this amount greater than available question, then all questions will be available for a student to answer."
|
3992 |
msgstr ""
|
3993 |
|
3994 |
-
#: views/modal/edit_quiz.php:
|
3995 |
msgid "Saved"
|
3996 |
msgstr ""
|
3997 |
|
3998 |
-
#: views/modal/edit_quiz.php:
|
3999 |
msgid "Quiz Auto Start"
|
4000 |
msgstr ""
|
4001 |
|
4002 |
-
#: views/modal/edit_quiz.php:
|
4003 |
msgid "If you enable this option, the quiz will start automatically after the page is loaded."
|
4004 |
msgstr ""
|
4005 |
|
4006 |
-
#: views/modal/edit_quiz.php:
|
4007 |
msgid "Question Layout"
|
4008 |
msgstr ""
|
4009 |
|
4010 |
-
#: views/modal/edit_quiz.php:
|
4011 |
msgid "Set question layout view"
|
4012 |
msgstr ""
|
4013 |
|
4014 |
-
#: views/modal/edit_quiz.php:
|
4015 |
msgid "Single Question"
|
4016 |
msgstr ""
|
4017 |
|
4018 |
-
#: views/modal/edit_quiz.php:
|
4019 |
msgid "Question Pagination"
|
4020 |
msgstr ""
|
4021 |
|
4022 |
-
#: views/modal/edit_quiz.php:
|
4023 |
msgid "Question below each other"
|
4024 |
msgstr ""
|
4025 |
|
4026 |
-
#: views/modal/edit_quiz.php:
|
4027 |
msgid "Questions Order"
|
4028 |
msgstr ""
|
4029 |
|
4030 |
-
#: views/modal/edit_quiz.php:
|
4031 |
msgid "Random"
|
4032 |
msgstr ""
|
4033 |
|
4034 |
-
#: views/modal/edit_quiz.php:
|
4035 |
msgid "Sorting"
|
4036 |
msgstr ""
|
4037 |
|
4038 |
-
#: views/modal/edit_quiz.php:
|
4039 |
msgid "Ascending"
|
4040 |
msgstr ""
|
4041 |
|
4042 |
-
#: views/modal/edit_quiz.php:
|
4043 |
msgid "Descending"
|
4044 |
msgstr ""
|
4045 |
|
4046 |
-
#: views/modal/edit_quiz.php:
|
4047 |
msgid "Hide question number"
|
4048 |
msgstr ""
|
4049 |
|
4050 |
-
#: views/modal/edit_quiz.php:
|
4051 |
msgid "Show/hide question number during attempt."
|
4052 |
msgstr ""
|
4053 |
|
4054 |
-
#: views/modal/edit_quiz.php:
|
4055 |
msgid "Short answer characters limit"
|
4056 |
msgstr ""
|
4057 |
|
4058 |
-
#: views/modal/edit_quiz.php:
|
4059 |
msgid "Student will place answer in short answer question type within this characters limit."
|
4060 |
msgstr ""
|
4061 |
|
4062 |
-
#: views/modal/edit_quiz.php:
|
4063 |
msgid "Open-Ended/Essay questions answer character limit"
|
4064 |
msgstr ""
|
4065 |
|
4066 |
-
#: views/modal/edit_quiz.php:
|
4067 |
msgid "Students will place the answer in the Open-Ended/Essay question type within this character limit."
|
4068 |
msgstr ""
|
4069 |
|
4070 |
-
#: views/modal/question_answer_edit_form.php:3, views/modal/question_answer_form.php:
|
4071 |
msgid "No option is necessary for this answer type"
|
4072 |
msgstr ""
|
4073 |
|
4074 |
-
#: views/modal/question_answer_edit_form.php:
|
4075 |
msgid "Answer input value"
|
4076 |
msgstr ""
|
4077 |
|
4078 |
-
#: views/modal/question_answer_edit_form.php:
|
4079 |
msgid "The answers that students enter should match with this text. Write in <strong>small caps</strong>"
|
4080 |
msgstr ""
|
4081 |
|
4082 |
-
#: views/modal/question_answer_edit_form.php:
|
4083 |
msgid "Image matched text"
|
4084 |
msgstr ""
|
4085 |
|
4086 |
-
#: views/modal/question_answer_edit_form.php:
|
4087 |
msgid "Answer title"
|
4088 |
msgstr ""
|
4089 |
|
4090 |
-
#: views/modal/question_answer_edit_form.php:
|
4091 |
msgid "Matched Answer title"
|
4092 |
msgstr ""
|
4093 |
|
4094 |
-
#: views/modal/question_answer_edit_form.php:
|
4095 |
msgid "Display format for options"
|
4096 |
msgstr ""
|
4097 |
|
4098 |
-
#: views/modal/question_answer_edit_form.php:
|
4099 |
msgid "Only text"
|
4100 |
msgstr ""
|
4101 |
|
4102 |
-
#: views/modal/question_answer_edit_form.php:
|
4103 |
msgid "Only Image"
|
4104 |
msgstr ""
|
4105 |
|
4106 |
-
#: views/modal/question_answer_edit_form.php:
|
4107 |
msgid "Text & Image both"
|
4108 |
msgstr ""
|
4109 |
|
4110 |
-
#: views/modal/question_answer_edit_form.php:
|
4111 |
msgid "Question Title"
|
4112 |
msgstr ""
|
4113 |
|
4114 |
-
#: views/modal/question_answer_edit_form.php:
|
4115 |
msgid "Please make sure that <b>{dash}</b> variable contains in your question title to show dash, You can use multiple variable"
|
4116 |
msgstr ""
|
4117 |
|
4118 |
-
#: views/modal/question_answer_edit_form.php:
|
4119 |
msgid "Correct Answer(s)"
|
4120 |
msgstr ""
|
4121 |
|
4122 |
-
#: views/modal/question_answer_edit_form.php:
|
4123 |
msgid "Separate multiple answer by pipe <b>( | )</b> , 1 answer per variable assigned in question"
|
4124 |
msgstr ""
|
4125 |
|
4126 |
-
#: views/modal/question_answer_edit_form.php:
|
4127 |
msgid "Update Answer"
|
4128 |
msgstr ""
|
4129 |
|
4130 |
-
#: views/modal/question_answer_form.php:
|
4131 |
msgid "Please make sure to use the <strong>{dash}</strong> variable in your question title to show the blanks in your question. You can use multiple <strong>{dash}</strong> variables in one question."
|
4132 |
msgstr ""
|
4133 |
|
4134 |
-
#: views/modal/question_answer_form.php:
|
4135 |
msgid "Separate multiple answers by a vertical bar <strong>|</strong>. 1 answer per <strong>{dash}</strong> variable is defined in the question. Example: Apple | Banana | Orange"
|
4136 |
msgstr ""
|
4137 |
|
4138 |
-
#: views/modal/question_answer_form.php:
|
4139 |
msgid "Select the correct option"
|
4140 |
msgstr ""
|
4141 |
|
4142 |
-
#: views/modal/question_answer_form.php:
|
4143 |
msgid "Save Answer"
|
4144 |
msgstr ""
|
4145 |
|
4146 |
-
#: views/modal/question_form.php:
|
4147 |
msgid "Write your question here"
|
4148 |
msgstr ""
|
4149 |
|
4150 |
-
#: views/modal/question_form.php:
|
4151 |
msgid "Type your question here"
|
4152 |
msgstr ""
|
4153 |
|
4154 |
-
#: views/modal/question_form.php:
|
4155 |
msgid "Question Type"
|
4156 |
msgstr ""
|
4157 |
|
4158 |
-
#: views/modal/question_form.php:
|
4159 |
msgid "True or False"
|
4160 |
msgstr ""
|
4161 |
|
4162 |
-
#: views/modal/question_form.php:
|
4163 |
msgid "Pro version required"
|
4164 |
msgstr ""
|
4165 |
|
4166 |
-
#: views/modal/question_form.php:
|
4167 |
msgid "Answer Required"
|
4168 |
msgstr ""
|
4169 |
|
4170 |
-
#: views/modal/question_form.php:
|
4171 |
msgid "Randomize"
|
4172 |
msgstr ""
|
4173 |
|
4174 |
-
#: views/modal/question_form.php:
|
4175 |
msgid "Point(s) for this answer"
|
4176 |
msgstr ""
|
4177 |
|
4178 |
-
#: views/modal/question_form.php:
|
4179 |
msgid "set the mark ex. 10"
|
4180 |
msgstr ""
|
4181 |
|
4182 |
-
#: views/modal/question_form.php:
|
4183 |
msgid "Display Points"
|
4184 |
msgstr ""
|
4185 |
|
4186 |
-
#: views/modal/question_form.php:
|
4187 |
msgid "Input options for the question and select the correct answer."
|
4188 |
msgstr ""
|
4189 |
|
4190 |
-
#: views/modal/question_form.php:
|
4191 |
msgid "Make sure you’re saving the answers in the right order. Students will have to match this order."
|
4192 |
msgstr ""
|
4193 |
|
4194 |
-
#: views/modal/question_form.php:
|
4195 |
msgid "Add An Option"
|
4196 |
msgstr ""
|
4197 |
|
4198 |
-
#: views/modal/question_form.php:
|
4199 |
msgid "Save & Continue"
|
4200 |
msgstr ""
|
4201 |
|
@@ -4219,7 +4215,7 @@ msgstr ""
|
|
4219 |
msgid "Settings Saved"
|
4220 |
msgstr ""
|
4221 |
|
4222 |
-
#: views/options/options_generator.php:
|
4223 |
msgid "Save Settings"
|
4224 |
msgstr ""
|
4225 |
|
@@ -4231,15 +4227,15 @@ msgstr ""
|
|
4231 |
msgid "Themes"
|
4232 |
msgstr ""
|
4233 |
|
4234 |
-
#: views/pages/addons.php:
|
4235 |
msgid "No %s currently avaialable"
|
4236 |
msgstr ""
|
4237 |
|
4238 |
-
#: views/pages/addons.php:59
|
4239 |
msgid "Buy Now"
|
4240 |
msgstr ""
|
4241 |
|
4242 |
-
#: views/pages/addons.php:79, views/pages/enable_disable_addons.php:
|
4243 |
msgid "Version"
|
4244 |
msgstr ""
|
4245 |
|
@@ -4247,43 +4243,43 @@ msgstr ""
|
|
4247 |
msgid "Add new instructor"
|
4248 |
msgstr ""
|
4249 |
|
4250 |
-
#: views/pages/announcements.php:
|
4251 |
msgid "Search Announcements"
|
4252 |
msgstr ""
|
4253 |
|
4254 |
-
#: views/pages/announcements.php:
|
4255 |
msgid "Add new"
|
4256 |
msgstr ""
|
4257 |
|
4258 |
-
#: views/pages/announcements.php:
|
4259 |
msgid "Create New Announcement"
|
4260 |
msgstr ""
|
4261 |
|
4262 |
-
#: views/pages/announcements.php:
|
4263 |
msgid "Announcement Title"
|
4264 |
msgstr ""
|
4265 |
|
4266 |
-
#: views/pages/announcements.php:
|
4267 |
msgid "Announcement title"
|
4268 |
msgstr ""
|
4269 |
|
4270 |
-
#: views/pages/announcements.php:
|
4271 |
msgid "Summary"
|
4272 |
msgstr ""
|
4273 |
|
4274 |
-
#: views/pages/announcements.php:
|
4275 |
msgid "Summary..."
|
4276 |
msgstr ""
|
4277 |
|
4278 |
-
#: views/pages/announcements.php:
|
4279 |
msgid "Publish"
|
4280 |
msgstr ""
|
4281 |
|
4282 |
-
#: views/pages/announcements.php:
|
4283 |
msgid "Update Announcement"
|
4284 |
msgstr ""
|
4285 |
|
4286 |
-
#: views/pages/announcements.php:
|
4287 |
msgid "Update"
|
4288 |
msgstr ""
|
4289 |
|
@@ -4295,7 +4291,7 @@ msgstr ""
|
|
4295 |
msgid "Place answer"
|
4296 |
msgstr ""
|
4297 |
|
4298 |
-
#: views/pages/answer.php:
|
4299 |
msgid "on"
|
4300 |
msgstr ""
|
4301 |
|
@@ -4307,6 +4303,10 @@ msgstr ""
|
|
4307 |
msgid "Required Plugin(s)"
|
4308 |
msgstr ""
|
4309 |
|
|
|
|
|
|
|
|
|
4310 |
#: views/pages/get-pro.php:2
|
4311 |
msgid "Get pro plugin from themeum.com"
|
4312 |
msgstr ""
|
@@ -4331,7 +4331,7 @@ msgstr ""
|
|
4331 |
msgid "Completely Uninstall and erase all data"
|
4332 |
msgstr ""
|
4333 |
|
4334 |
-
#: views/pages/view_attempt.php:7, templates/dashboard/my-quiz-attempts/attempts-details.php:24, templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4335 |
msgid "Attempt not found"
|
4336 |
msgstr ""
|
4337 |
|
@@ -4355,63 +4355,63 @@ msgstr ""
|
|
4355 |
msgid "Quiz Time"
|
4356 |
msgstr ""
|
4357 |
|
4358 |
-
#: views/pages/view_attempt.php:157, templates/dashboard/quiz-attempts/quiz-reviews.php:
|
4359 |
msgid "Reminder:"
|
4360 |
msgstr ""
|
4361 |
|
4362 |
-
#: views/pages/view_attempt.php:157, templates/dashboard/quiz-attempts/quiz-reviews.php:
|
4363 |
msgid "Please review answers for question no. %s"
|
4364 |
msgstr ""
|
4365 |
|
4366 |
-
#: views/pages/view_attempt.php:
|
4367 |
msgid "Manually reviewed at: "
|
4368 |
msgstr ""
|
4369 |
|
4370 |
-
#: views/pages/view_attempt.php:
|
4371 |
msgid "Quiz Overview"
|
4372 |
msgstr ""
|
4373 |
|
4374 |
-
#: views/pages/view_attempt.php:
|
4375 |
msgid "Type"
|
4376 |
msgstr ""
|
4377 |
|
4378 |
-
#: views/pages/view_attempt.php:
|
4379 |
msgid "No."
|
4380 |
msgstr ""
|
4381 |
|
4382 |
-
#: views/pages/view_attempt.php:
|
4383 |
msgid "Given Answers"
|
4384 |
msgstr ""
|
4385 |
|
4386 |
-
#: views/pages/view_attempt.php:
|
4387 |
msgid "Correct/Incorrect"
|
4388 |
msgstr ""
|
4389 |
|
4390 |
-
#: views/pages/view_attempt.php:
|
4391 |
msgid "Manual Review"
|
4392 |
msgstr ""
|
4393 |
|
4394 |
-
#: views/pages/view_attempt.php:
|
4395 |
msgid "Incorrect"
|
4396 |
msgstr ""
|
4397 |
|
4398 |
-
#: views/pages/view_attempt.php:
|
4399 |
msgid "Correct"
|
4400 |
msgstr ""
|
4401 |
|
4402 |
-
#: views/pages/view_attempt.php:
|
4403 |
msgid "Review Required"
|
4404 |
msgstr ""
|
4405 |
|
4406 |
-
#: views/pages/view_attempt.php:
|
4407 |
msgid "Mark as In correct"
|
4408 |
msgstr ""
|
4409 |
|
4410 |
-
#: views/pages/view_attempt.php:
|
4411 |
msgid "Instructor Feedback"
|
4412 |
msgstr ""
|
4413 |
|
4414 |
-
#: views/pages/view_attempt.php:
|
4415 |
msgid "Updated"
|
4416 |
msgstr ""
|
4417 |
|
@@ -4488,7 +4488,7 @@ msgid "Oldest"
|
|
4488 |
msgstr ""
|
4489 |
|
4490 |
#: templates/dashboard/assignments/submitted.php:87
|
4491 |
-
msgid "%s Pending %s"
|
4492 |
msgstr ""
|
4493 |
|
4494 |
#: templates/dashboard/assignments/submitted.php:88
|
@@ -4496,11 +4496,11 @@ msgid "Evaluate"
|
|
4496 |
msgstr ""
|
4497 |
|
4498 |
#: templates/dashboard/assignments/submitted.php:90
|
4499 |
-
msgid "%s Pass %s"
|
4500 |
msgstr ""
|
4501 |
|
4502 |
#: templates/dashboard/assignments/submitted.php:90
|
4503 |
-
msgid "%s Fail %s"
|
4504 |
msgstr ""
|
4505 |
|
4506 |
#: templates/dashboard/earning/earning-report-top-menu.php:12
|
@@ -4535,19 +4535,19 @@ msgstr ""
|
|
4535 |
msgid "My Earning"
|
4536 |
msgstr ""
|
4537 |
|
4538 |
-
#: templates/dashboard/earning/report-date_range.php:56, templates/dashboard/earning/report-date_range.php:58, templates/dashboard/earning/report-last_month.php:55, templates/dashboard/earning/report-last_month.php:57, templates/dashboard/earning/report-last_week.php:59, templates/dashboard/earning/report-last_week.php:61, templates/dashboard/earning/report-last_year.php:55, templates/dashboard/earning/report-last_year.php:57, templates/dashboard/earning/report-this_month.php:
|
4539 |
msgid "Deducted Fees"
|
4540 |
msgstr ""
|
4541 |
|
4542 |
#: templates/dashboard/earning/report-date_range.php:67, templates/dashboard/earning/report-last_week.php:74, templates/dashboard/earning/report-this_week.php:67
|
4543 |
-
msgid "Showing Result from %s to %s"
|
4544 |
msgstr ""
|
4545 |
|
4546 |
-
#: templates/dashboard/earning/report-date_range.php:74, templates/dashboard/earning/report-last_month.php:72, templates/dashboard/earning/report-last_week.php:81, templates/dashboard/earning/report-last_year.php:76, templates/dashboard/earning/report-this_month.php:
|
4547 |
msgid "Sales statements for this period"
|
4548 |
msgstr ""
|
4549 |
|
4550 |
-
#: templates/dashboard/earning/report-last_month.php:65, templates/dashboard/earning/report-this_month.php:
|
4551 |
msgid "Earning Data for the month of %s"
|
4552 |
msgstr ""
|
4553 |
|
@@ -4555,47 +4555,47 @@ msgstr ""
|
|
4555 |
msgid "Earning Data for the year of %s"
|
4556 |
msgstr ""
|
4557 |
|
4558 |
-
#: templates/dashboard/earning/report.php:
|
4559 |
msgid "Earning Report"
|
4560 |
msgstr ""
|
4561 |
|
4562 |
-
#: templates/dashboard/earning/statement.php:
|
4563 |
msgid "There is not enough sales data to generate a statement"
|
4564 |
msgstr ""
|
4565 |
|
4566 |
-
#: templates/dashboard/earning/statement.php:
|
4567 |
msgid "Deduct"
|
4568 |
msgstr ""
|
4569 |
|
4570 |
-
#: templates/dashboard/earning/statement.php:
|
4571 |
msgid "Date:"
|
4572 |
msgstr ""
|
4573 |
|
4574 |
-
#: templates/dashboard/earning/statement.php:
|
4575 |
msgid "Commission"
|
4576 |
msgstr ""
|
4577 |
|
4578 |
-
#: templates/dashboard/earning/statement.php:
|
4579 |
msgid "Rate"
|
4580 |
msgstr ""
|
4581 |
|
4582 |
-
#: templates/dashboard/earning/statement.php:
|
4583 |
msgid "Deducted"
|
4584 |
msgstr ""
|
4585 |
|
4586 |
-
#: templates/dashboard/earning/statements.php:
|
4587 |
msgid "Report"
|
4588 |
msgstr ""
|
4589 |
|
4590 |
-
#: templates/dashboard/earning/statements.php:
|
4591 |
-
msgid "Showing results %d to %d of %d"
|
4592 |
msgstr ""
|
4593 |
|
4594 |
-
#: templates/dashboard/earning/statements.php:
|
4595 |
msgid "Price: "
|
4596 |
msgstr ""
|
4597 |
|
4598 |
-
#: templates/dashboard/earning/statements.php:
|
4599 |
msgid "Purchaser"
|
4600 |
msgstr ""
|
4601 |
|
@@ -4663,43 +4663,43 @@ msgstr ""
|
|
4663 |
msgid "Register as instructor"
|
4664 |
msgstr ""
|
4665 |
|
4666 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4667 |
msgid "You have no access."
|
4668 |
msgstr ""
|
4669 |
|
4670 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4671 |
msgid "Back to Attempt List"
|
4672 |
msgstr ""
|
4673 |
|
4674 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4675 |
msgid "Quiz:"
|
4676 |
msgstr ""
|
4677 |
|
4678 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4679 |
msgid "Course:"
|
4680 |
msgstr ""
|
4681 |
|
4682 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4683 |
msgid "#"
|
4684 |
msgstr ""
|
4685 |
|
4686 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4687 |
msgid "Attempts Date"
|
4688 |
msgstr ""
|
4689 |
|
4690 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4691 |
msgid "Total Marks"
|
4692 |
msgstr ""
|
4693 |
|
4694 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4695 |
msgid "Pass Marks"
|
4696 |
msgstr ""
|
4697 |
|
4698 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4699 |
msgid "Results"
|
4700 |
msgstr ""
|
4701 |
|
4702 |
-
#: templates/dashboard/my-quiz-attempts/attempts-details.php:
|
4703 |
msgid "Correct Answers"
|
4704 |
msgstr ""
|
4705 |
|
@@ -4715,11 +4715,11 @@ msgstr ""
|
|
4715 |
msgid "Set Your"
|
4716 |
msgstr ""
|
4717 |
|
4718 |
-
#: templates/dashboard/notifications/profile-completion.php:
|
4719 |
msgid "% Complete"
|
4720 |
msgstr ""
|
4721 |
|
4722 |
-
#: templates/dashboard/notifications/profile-completion.php:
|
4723 |
msgid "You are almost done!"
|
4724 |
msgstr ""
|
4725 |
|
@@ -4735,11 +4735,11 @@ msgstr ""
|
|
4735 |
msgid "Update Review"
|
4736 |
msgstr ""
|
4737 |
|
4738 |
-
#: templates/dashboard/reviews/given-reviews.php:
|
4739 |
msgid "Edit Feedback"
|
4740 |
msgstr ""
|
4741 |
|
4742 |
-
#: templates/dashboard/reviews/given-reviews.php:
|
4743 |
msgid "Edit Review"
|
4744 |
msgstr ""
|
4745 |
|
@@ -4747,7 +4747,7 @@ msgstr ""
|
|
4747 |
msgid "Reset Password"
|
4748 |
msgstr ""
|
4749 |
|
4750 |
-
#: templates/dashboard/settings/nav-bar.php:
|
4751 |
msgid "Withdraw"
|
4752 |
msgstr ""
|
4753 |
|
@@ -4759,43 +4759,43 @@ msgstr ""
|
|
4759 |
msgid "Upload Cover Photo"
|
4760 |
msgstr ""
|
4761 |
|
4762 |
-
#: templates/dashboard/settings/profile.php:
|
4763 |
msgid "Profile Photo Size"
|
4764 |
msgstr ""
|
4765 |
|
4766 |
-
#: templates/dashboard/settings/profile.php:
|
4767 |
msgid "200x200"
|
4768 |
msgstr ""
|
4769 |
|
4770 |
-
#: templates/dashboard/settings/profile.php:
|
4771 |
msgid "pixels"
|
4772 |
msgstr ""
|
4773 |
|
4774 |
-
#: templates/dashboard/settings/profile.php:
|
4775 |
msgid "Cover Photo Size"
|
4776 |
msgstr ""
|
4777 |
|
4778 |
-
#: templates/dashboard/settings/profile.php:
|
4779 |
msgid "700x430"
|
4780 |
msgstr ""
|
4781 |
|
4782 |
-
#: templates/dashboard/settings/profile.php:
|
4783 |
msgid "Saving..."
|
4784 |
msgstr ""
|
4785 |
|
4786 |
-
#: templates/dashboard/settings/profile.php:
|
4787 |
msgid "Upload Photo"
|
4788 |
msgstr ""
|
4789 |
|
4790 |
-
#: templates/dashboard/settings/profile.php:
|
4791 |
msgid "Display name publicly as"
|
4792 |
msgstr ""
|
4793 |
|
4794 |
-
#: templates/dashboard/settings/profile.php:
|
4795 |
msgid "The display name is shown in all public fields, such as the author name, instructor name, student name, and name that will be printed on the certificate."
|
4796 |
msgstr ""
|
4797 |
|
4798 |
-
#: templates/dashboard/settings/profile.php:
|
4799 |
msgid "Update Profile"
|
4800 |
msgstr ""
|
4801 |
|
@@ -4815,91 +4815,91 @@ msgstr ""
|
|
4815 |
msgid "Select a withdraw method"
|
4816 |
msgstr ""
|
4817 |
|
4818 |
-
#: templates/dashboard/settings/withdraw-settings.php:
|
4819 |
msgid "Min withdraw"
|
4820 |
msgstr ""
|
4821 |
|
4822 |
-
#: templates/dashboard/settings/withdraw-settings.php:
|
4823 |
msgid "Save Withdrawal Account"
|
4824 |
msgstr ""
|
4825 |
|
4826 |
-
#: templates/single/assignment/content.php:
|
4827 |
msgid "Time Duration : "
|
4828 |
msgstr ""
|
4829 |
|
4830 |
-
#: templates/single/assignment/content.php:
|
4831 |
msgid "No limit"
|
4832 |
msgstr ""
|
4833 |
|
4834 |
-
#: templates/single/assignment/content.php:
|
4835 |
msgid "Deadline : "
|
4836 |
msgstr ""
|
4837 |
|
4838 |
-
#: templates/single/assignment/content.php:
|
4839 |
msgid "Expired"
|
4840 |
msgstr ""
|
4841 |
|
4842 |
-
#: templates/single/assignment/content.php:
|
4843 |
msgid "Total Points : "
|
4844 |
msgstr ""
|
4845 |
|
4846 |
-
#: templates/single/assignment/content.php:
|
4847 |
msgid "Minimum Pass Points : "
|
4848 |
msgstr ""
|
4849 |
|
4850 |
-
#: templates/single/assignment/content.php:
|
4851 |
msgid "You have missed the submission deadline. Please contact the instructor for more information."
|
4852 |
msgstr ""
|
4853 |
|
4854 |
-
#: templates/single/assignment/content.php:
|
4855 |
msgid "Submit assignment"
|
4856 |
msgstr ""
|
4857 |
|
4858 |
-
#: templates/single/assignment/content.php:
|
4859 |
-
msgid "You received %s points out of %s"
|
4860 |
msgstr ""
|
4861 |
|
4862 |
-
#: templates/single/assignment/content.php:
|
4863 |
msgid "Your Grade is "
|
4864 |
msgstr ""
|
4865 |
|
4866 |
-
#: templates/single/assignment/content.php:
|
4867 |
msgid "Failed"
|
4868 |
msgstr ""
|
4869 |
|
4870 |
-
#: templates/single/assignment/content.php:
|
4871 |
msgid "Passed"
|
4872 |
msgstr ""
|
4873 |
|
4874 |
-
#: templates/single/assignment/content.php:
|
4875 |
msgid "Your Answers"
|
4876 |
msgstr ""
|
4877 |
|
4878 |
-
#: templates/single/assignment/content.php:
|
4879 |
msgid "Your uploaded file(s)"
|
4880 |
msgstr ""
|
4881 |
|
4882 |
-
#: templates/single/assignment/content.php:
|
4883 |
msgid "Instructor Note"
|
4884 |
msgstr ""
|
4885 |
|
4886 |
-
#: templates/single/assignment/content.php:
|
4887 |
msgid "Assignment answer form"
|
4888 |
msgstr ""
|
4889 |
|
4890 |
-
#: templates/single/assignment/content.php:
|
4891 |
msgid "Write your answer briefly"
|
4892 |
msgstr ""
|
4893 |
|
4894 |
-
#: templates/single/assignment/content.php:
|
4895 |
msgid "Attach assignment files"
|
4896 |
msgstr ""
|
4897 |
|
4898 |
-
#: templates/single/assignment/content.php:
|
4899 |
msgid "Upload file"
|
4900 |
msgstr ""
|
4901 |
|
4902 |
-
#: templates/single/assignment/content.php:
|
4903 |
msgid "Submit Assignment"
|
4904 |
msgstr ""
|
4905 |
|
@@ -4907,15 +4907,15 @@ msgstr ""
|
|
4907 |
msgid "Please make sure that your EDD product exists and valid for this course"
|
4908 |
msgstr ""
|
4909 |
|
4910 |
-
#: templates/single/course/add-to-cart-woocommerce.php:
|
4911 |
msgid "Please make sure that your product exists and valid for this course"
|
4912 |
msgstr ""
|
4913 |
|
4914 |
-
#: templates/single/course/add-to-cart.php:
|
4915 |
msgid "Enroll Now"
|
4916 |
msgstr ""
|
4917 |
|
4918 |
-
#: templates/single/course/add-to-cart.php:
|
4919 |
msgid "Start Learning"
|
4920 |
msgstr ""
|
4921 |
|
@@ -4931,39 +4931,35 @@ msgstr ""
|
|
4931 |
msgid "Complete Course"
|
4932 |
msgstr ""
|
4933 |
|
4934 |
-
#: templates/single/course/continue-lesson.php:
|
4935 |
msgid "Continue to lesson"
|
4936 |
msgstr ""
|
4937 |
|
4938 |
-
#: templates/single/course/course-benefits.php:
|
4939 |
msgid "What Will I Learn?"
|
4940 |
msgstr ""
|
4941 |
|
4942 |
-
#: templates/single/course/course-enrolled-box.php:
|
4943 |
msgid "Start Course"
|
4944 |
msgstr ""
|
4945 |
|
4946 |
-
#: templates/single/course/course-enrolled-box.php:
|
4947 |
msgid "Retake This Course"
|
4948 |
msgstr ""
|
4949 |
|
4950 |
-
#: templates/single/course/course-enrolled-box.php:
|
4951 |
msgid "You have been enrolled on %s."
|
4952 |
msgstr ""
|
4953 |
|
4954 |
-
#: templates/single/course/course-requirements.php:29
|
4955 |
-
msgid "Requirements"
|
4956 |
-
msgstr ""
|
4957 |
-
|
4958 |
#: templates/single/course/course-target-audience.php:28
|
4959 |
msgid "Target Audience"
|
4960 |
msgstr ""
|
4961 |
|
4962 |
-
#: templates/single/course/course-topics.php:
|
4963 |
msgid "Topics for this course"
|
4964 |
msgstr ""
|
4965 |
|
4966 |
-
#: templates/single/course/course-topics.php:
|
4967 |
msgid "Live"
|
4968 |
msgstr ""
|
4969 |
|
@@ -4983,27 +4979,27 @@ msgstr ""
|
|
4983 |
msgid "students"
|
4984 |
msgstr ""
|
4985 |
|
4986 |
-
#: templates/single/course/lead-info.php:
|
4987 |
msgid "Course level:"
|
4988 |
msgstr ""
|
4989 |
|
4990 |
-
#: templates/single/course/lead-info.php:
|
4991 |
msgid "Duration"
|
4992 |
msgstr ""
|
4993 |
|
4994 |
-
#: templates/single/course/lead-info.php:
|
4995 |
msgid "Total Enrolled"
|
4996 |
msgstr ""
|
4997 |
|
4998 |
-
#: templates/single/course/lead-info.php:
|
4999 |
msgid "Last Update"
|
5000 |
msgstr ""
|
5001 |
|
5002 |
-
#: templates/single/course/lead-info.php:
|
5003 |
msgid "About Course"
|
5004 |
msgstr ""
|
5005 |
|
5006 |
-
#: templates/single/course/login.php:
|
5007 |
msgid "Login"
|
5008 |
msgstr ""
|
5009 |
|
@@ -5039,7 +5035,7 @@ msgstr ""
|
|
5039 |
msgid "Complete Lesson"
|
5040 |
msgstr ""
|
5041 |
|
5042 |
-
#: templates/single/lesson/lesson_sidebar.php:
|
5043 |
msgid "Browse Q&A"
|
5044 |
msgstr ""
|
5045 |
|
@@ -5051,59 +5047,59 @@ msgstr ""
|
|
5051 |
msgid "Course name : %s"
|
5052 |
msgstr ""
|
5053 |
|
5054 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5055 |
msgid "No questions yet"
|
5056 |
msgstr ""
|
5057 |
|
5058 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5059 |
msgid "Be the first to ask your question! You’ll be able to add details in the next step."
|
5060 |
msgstr ""
|
5061 |
|
5062 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5063 |
msgid "Add an answer"
|
5064 |
msgstr ""
|
5065 |
|
5066 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5067 |
msgid "Write your answer here..."
|
5068 |
msgstr ""
|
5069 |
|
5070 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5071 |
msgid "Add Answer"
|
5072 |
msgstr ""
|
5073 |
|
5074 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5075 |
msgid "Ask a new question"
|
5076 |
msgstr ""
|
5077 |
|
5078 |
-
#: templates/single/lesson/sidebar_question_and_answer.php:
|
5079 |
msgid "Submit My Question"
|
5080 |
msgstr ""
|
5081 |
|
5082 |
-
#: templates/single/quiz/body.php:
|
5083 |
msgid "Start Quiz"
|
5084 |
msgstr ""
|
5085 |
|
5086 |
-
#: templates/single/quiz/body.php:
|
5087 |
msgid "Time remaining : "
|
5088 |
msgstr ""
|
5089 |
|
5090 |
-
#: templates/single/quiz/body.php:
|
5091 |
msgid "Reattempt"
|
5092 |
msgstr ""
|
5093 |
|
5094 |
-
#: templates/single/quiz/body.php:
|
5095 |
msgid "Marks : "
|
5096 |
msgstr ""
|
5097 |
|
5098 |
-
#: templates/single/quiz/body.php:
|
5099 |
msgid "characters remaining"
|
5100 |
msgstr ""
|
5101 |
|
5102 |
-
#: templates/single/quiz/body.php:
|
5103 |
msgid "Answer & Next Question"
|
5104 |
msgstr ""
|
5105 |
|
5106 |
-
#: templates/single/quiz/body.php:
|
5107 |
msgid "Submit Quiz"
|
5108 |
msgstr ""
|
5109 |
|
@@ -5139,7 +5135,7 @@ msgstr ""
|
|
5139 |
msgid "Passing Grade"
|
5140 |
msgstr ""
|
5141 |
|
5142 |
-
#: views/options/field-types/radio.php:
|
5143 |
msgid "Select Option"
|
5144 |
msgstr ""
|
5145 |
|
@@ -5257,180 +5253,176 @@ msgstr ""
|
|
5257 |
msgid "Server environment"
|
5258 |
msgstr ""
|
5259 |
|
5260 |
-
#: views/pages/tools/status.php:
|
5261 |
msgid "Server info"
|
5262 |
msgstr ""
|
5263 |
|
5264 |
-
#: views/pages/tools/status.php:
|
5265 |
msgid "Information about the web server that is currently hosting your site."
|
5266 |
msgstr ""
|
5267 |
|
5268 |
-
#: views/pages/tools/status.php:
|
5269 |
msgid "PHP version"
|
5270 |
msgstr ""
|
5271 |
|
5272 |
-
#: views/pages/tools/status.php:
|
5273 |
msgid "The version of PHP installed on your hosting server."
|
5274 |
msgstr ""
|
5275 |
|
5276 |
-
#: views/pages/tools/status.php:
|
5277 |
msgid "We recommend using PHP version 7.2 or above for greater performance and security."
|
5278 |
msgstr ""
|
5279 |
|
5280 |
-
#: views/pages/tools/status.php:
|
5281 |
msgid "Tutor will run under this version of PHP, however, it has reached end of life. We recommend using PHP version 7.2 or above for greater performance and security."
|
5282 |
msgstr ""
|
5283 |
|
5284 |
-
#: views/pages/tools/status.php:
|
5285 |
msgid "PHP post max size"
|
5286 |
msgstr ""
|
5287 |
|
5288 |
-
#: views/pages/tools/status.php:
|
5289 |
msgid "The largest filesize that can be contained in one post."
|
5290 |
msgstr ""
|
5291 |
|
5292 |
-
#: views/pages/tools/status.php:
|
5293 |
msgid "PHP time limit"
|
5294 |
msgstr ""
|
5295 |
|
5296 |
-
#: views/pages/tools/status.php:
|
5297 |
msgid "The amount of time (in seconds) that your site will spend on a single operation before timing out (to avoid server lockups)"
|
5298 |
msgstr ""
|
5299 |
|
5300 |
-
#: views/pages/tools/status.php:
|
5301 |
msgid "PHP max input vars"
|
5302 |
msgstr ""
|
5303 |
|
5304 |
-
#: views/pages/tools/status.php:
|
5305 |
msgid "The maximum number of variables your server can use for a single function to avoid overloads."
|
5306 |
msgstr ""
|
5307 |
|
5308 |
-
#: views/pages/tools/status.php:
|
5309 |
msgid "cURL version"
|
5310 |
msgstr ""
|
5311 |
|
5312 |
-
#: views/pages/tools/status.php:
|
5313 |
msgid "The version of cURL installed on your server."
|
5314 |
msgstr ""
|
5315 |
|
5316 |
-
#: views/pages/tools/status.php:
|
5317 |
msgid "SUHOSIN installed"
|
5318 |
msgstr ""
|
5319 |
|
5320 |
-
#: views/pages/tools/status.php:
|
5321 |
msgid "Suhosin is an advanced protection system for PHP installations. It was designed to protect your servers on the one hand against a number of well known problems in PHP applications and on the other hand against potential unknown vulnerabilities within these applications or the PHP core itself. If enabled on your server, Suhosin may need to be configured to increase its data submission limits."
|
5322 |
msgstr ""
|
5323 |
|
5324 |
-
#: views/pages/tools/status.php:
|
5325 |
msgid "MySQL version"
|
5326 |
msgstr ""
|
5327 |
|
5328 |
-
#: views/pages/tools/status.php:
|
5329 |
msgid "The version of MySQL installed on your hosting server."
|
5330 |
msgstr ""
|
5331 |
|
5332 |
-
|
5333 |
-
#: views/pages/tools/status.php:197
|
5334 |
msgid "%1$s - We recommend a minimum MySQL version of 5.6. See: %2$s"
|
5335 |
msgstr ""
|
5336 |
|
5337 |
-
#: views/pages/tools/status.php:
|
5338 |
msgid "WordPress requirements"
|
5339 |
msgstr ""
|
5340 |
|
5341 |
-
#: views/pages/tools/status.php:
|
5342 |
msgid "Max upload size"
|
5343 |
msgstr ""
|
5344 |
|
5345 |
-
#: views/pages/tools/status.php:
|
5346 |
msgid "The largest filesize that can be uploaded to your WordPress installation."
|
5347 |
msgstr ""
|
5348 |
|
5349 |
-
#: views/pages/tools/status.php:
|
5350 |
msgid "Default timezone is UTC"
|
5351 |
msgstr ""
|
5352 |
|
5353 |
-
#: views/pages/tools/status.php:
|
5354 |
msgid "The default timezone for your server."
|
5355 |
msgstr ""
|
5356 |
|
5357 |
#. translators: %s: default timezone..
|
5358 |
-
#: views/pages/tools/status.php:
|
5359 |
msgid "Default timezone is %s - it should be UTC"
|
5360 |
msgstr ""
|
5361 |
|
5362 |
-
#: views/pages/tools/status.php:
|
5363 |
msgid "fsockopen/cURL"
|
5364 |
msgstr ""
|
5365 |
|
5366 |
-
#: views/pages/tools/status.php:
|
5367 |
msgid "Payment gateways can use cURL to communicate with remote servers to authorize payments, other plugins may also use it when communicating with remote services."
|
5368 |
msgstr ""
|
5369 |
|
5370 |
-
#: views/pages/tools/status.php:
|
5371 |
msgid "Your server does not have fsockopen or cURL enabled - PayPal IPN and other scripts which communicate with other servers will not work. Contact your hosting provider."
|
5372 |
msgstr ""
|
5373 |
|
5374 |
-
#: views/pages/tools/status.php:
|
5375 |
msgid "DOMDocument"
|
5376 |
msgstr ""
|
5377 |
|
5378 |
-
#: views/pages/tools/status.php:
|
5379 |
msgid "HTML/Multipart emails use DOMDocument to generate inline CSS in templates."
|
5380 |
msgstr ""
|
5381 |
|
5382 |
-
|
5383 |
-
#: views/pages/tools/status.php:246
|
5384 |
msgid "Your server does not have the %s class enabled - HTML/Multipart emails, and also some extensions, will not work without DOMDocument."
|
5385 |
msgstr ""
|
5386 |
|
5387 |
-
#: views/pages/tools/status.php:
|
5388 |
msgid "GZip"
|
5389 |
msgstr ""
|
5390 |
|
5391 |
-
#: views/pages/tools/status.php:
|
5392 |
msgid "GZip (gzopen) is used to open the GEOIP database from MaxMind."
|
5393 |
msgstr ""
|
5394 |
|
5395 |
-
|
5396 |
-
#: views/pages/tools/status.php:260
|
5397 |
msgid "Your server does not support the %s function - this is required to use the GeoIP database from MaxMind."
|
5398 |
msgstr ""
|
5399 |
|
5400 |
-
#: views/pages/tools/status.php:
|
5401 |
msgid "Multibyte string"
|
5402 |
msgstr ""
|
5403 |
|
5404 |
-
#: views/pages/tools/status.php:
|
5405 |
msgid "Multibyte String (mbstring) is used to convert character encoding, like for emails or converting characters to lowercase."
|
5406 |
msgstr ""
|
5407 |
|
5408 |
-
|
5409 |
-
#: views/pages/tools/status.php:274
|
5410 |
msgid "Your server does not support the %s functions - this is required for better character encoding. Some fallbacks will be used instead for it."
|
5411 |
msgstr ""
|
5412 |
|
5413 |
-
#: views/pages/tools/tutor_pages.php:
|
5414 |
msgid "Page Name"
|
5415 |
msgstr ""
|
5416 |
|
5417 |
-
#: views/pages/tools/tutor_pages.php:
|
5418 |
msgid " Page not set"
|
5419 |
msgstr ""
|
5420 |
|
5421 |
-
#: views/pages/tools/tutor_pages.php:
|
5422 |
msgid " Page deleted, please set new one"
|
5423 |
msgstr ""
|
5424 |
|
5425 |
-
#: views/pages/tools/tutor_pages.php:
|
5426 |
msgid "Page visibility is not public"
|
5427 |
msgstr ""
|
5428 |
|
5429 |
-
#: views/pages/tools/tutor_pages.php:
|
5430 |
msgid "Re-Generate Tutor Pages"
|
5431 |
msgstr ""
|
5432 |
|
5433 |
-
#: views/pages/tools/tutor_pages.php:
|
5434 |
msgid "Note: This tool will install all the missing Tutor pages. Pages already defined and set up will not be replaced."
|
5435 |
msgstr ""
|
5436 |
|
@@ -5450,7 +5442,7 @@ msgstr ""
|
|
5450 |
msgid " Complete"
|
5451 |
msgstr ""
|
5452 |
|
5453 |
-
#: templates/single/course/enrolled/nav.php:
|
5454 |
msgid "Course Page"
|
5455 |
msgstr ""
|
5456 |
|
1 |
+
# Copyright (C) 2022 Tutor LMS
|
2 |
# This file is distributed under the same license as the Tutor LMS package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
17 |
msgid "Tutor Instructor"
|
18 |
msgstr ""
|
19 |
|
20 |
+
#: classes/Addons.php:27
|
21 |
msgid "BuddyPress"
|
22 |
msgstr ""
|
23 |
|
24 |
+
#: classes/Addons.php:31
|
25 |
msgid "Gradebook"
|
26 |
msgstr ""
|
27 |
|
28 |
+
#: classes/Addons.php:35
|
29 |
msgid "Content Drip"
|
30 |
msgstr ""
|
31 |
|
32 |
+
#: classes/Addons.php:39
|
33 |
msgid "Enrollments"
|
34 |
msgstr ""
|
35 |
|
36 |
+
#: classes/Addons.php:43
|
37 |
msgid "WooCommerce Subscriptions"
|
38 |
msgstr ""
|
39 |
|
40 |
+
#: classes/Addons.php:47
|
41 |
msgid "Paid Memberships Pro"
|
42 |
msgstr ""
|
43 |
|
44 |
+
#: classes/Addons.php:51
|
45 |
msgid "Restrict Content Pro"
|
46 |
msgstr ""
|
47 |
|
48 |
+
#: classes/Addons.php:55
|
49 |
msgid "Tutor Assignments"
|
50 |
msgstr ""
|
51 |
|
52 |
+
#: classes/Addons.php:59
|
53 |
msgid "Tutor Certificate"
|
54 |
msgstr ""
|
55 |
|
56 |
+
#: classes/Addons.php:63
|
57 |
msgid "Tutor Course Attachments"
|
58 |
msgstr ""
|
59 |
|
60 |
+
#: classes/Addons.php:67
|
61 |
msgid "Tutor Course Preview"
|
62 |
msgstr ""
|
63 |
|
64 |
+
#: classes/Addons.php:71
|
65 |
msgid "Tutor E-Mail"
|
66 |
msgstr ""
|
67 |
|
68 |
+
#: classes/Addons.php:75
|
69 |
msgid "Tutor Multi Instructors"
|
70 |
msgstr ""
|
71 |
|
72 |
+
#: classes/Addons.php:79
|
73 |
msgid "Tutor Prerequisites"
|
74 |
msgstr ""
|
75 |
|
76 |
+
#: classes/Addons.php:83
|
77 |
msgid "Tutor Report"
|
78 |
msgstr ""
|
79 |
|
80 |
+
#: classes/Addons.php:87
|
81 |
msgid "Quiz Export/Import"
|
82 |
msgstr ""
|
83 |
|
84 |
+
#: classes/Addons.php:88
|
85 |
msgid "Save time by exporting/importing quiz data with easy options."
|
86 |
msgstr ""
|
87 |
|
88 |
+
#: classes/Addons.php:91
|
89 |
msgid "Tutor Zoom Integration"
|
90 |
msgstr ""
|
91 |
|
92 |
+
#: classes/Addons.php:92
|
93 |
msgid "Connect Tutor LMS with Zoom to host live online classes. Students can attend live classes right from the lesson page."
|
94 |
msgstr ""
|
95 |
|
96 |
+
#: classes/Addons.php:95
|
97 |
msgid "Google Classroom Integration"
|
98 |
msgstr ""
|
99 |
|
100 |
+
#: classes/Addons.php:96
|
101 |
msgid "Helps connect Google Classrooms with Tutor LMS courses, allowing you to use features like Classroom streams and files directly from the Tutor LMS course."
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: classes/Addons.php:103
|
105 |
msgid "WPML Multilingual CMS"
|
106 |
msgstr ""
|
107 |
|
108 |
+
#: classes/Addons.php:104
|
109 |
msgid "Create multilingual courses, lessons, dashboard and more for a global audience."
|
110 |
msgstr ""
|
111 |
|
117 |
msgid "Tutor LMS"
|
118 |
msgstr ""
|
119 |
|
120 |
+
#: classes/Admin.php:56, classes/Admin.php:56, templates/single/course/lead-info.php:92, templates/single/course/enrolled/lead-info.php:93
|
121 |
msgid "Categories"
|
122 |
msgstr ""
|
123 |
|
125 |
msgid "Tags"
|
126 |
msgstr ""
|
127 |
|
128 |
+
#: classes/Admin.php:60, classes/Admin.php:60, classes/Course.php:507, classes/Options.php:594, classes/Quiz_Attempts_List.php:117, templates/student-public-profile.php:103, views/pages/students.php:8
|
129 |
msgid "Students"
|
130 |
msgstr ""
|
131 |
|
132 |
+
#: classes/Admin.php:63, classes/Admin.php:63, classes/Course.php:195, classes/Course.php:276, classes/Options.php:555, views/pages/instructors.php:29
|
133 |
msgid "Instructors"
|
134 |
msgstr ""
|
135 |
|
136 |
+
#: classes/Admin.php:66, classes/Admin.php:66, classes/Utils.php:1333, classes/Utils.php:2582, templates/dashboard/announcements.php:124, views/pages/announcements.php:105, views/pages/announcements.php:115
|
137 |
msgid "Announcements"
|
138 |
msgstr ""
|
139 |
|
145 |
msgid "Q & A "
|
146 |
msgstr ""
|
147 |
|
148 |
+
#: classes/Admin.php:70, classes/Admin.php:70, classes/Utils.php:2590, templates/dashboard/quiz-attempts.php:19, views/pages/quiz_attempts.php:29
|
149 |
msgid "Quiz Attempts"
|
150 |
msgstr ""
|
151 |
|
157 |
msgid "Add-ons"
|
158 |
msgstr ""
|
159 |
|
160 |
+
#: classes/Admin.php:80, classes/Admin.php:80, classes/Admin.php:453, classes/Utils.php:2614, templates/dashboard/settings.php:8, views/modal/add_quiz.php:22, views/modal/edit_quiz.php:35, templates/dashboard/notifications/profile-completion.php:14, templates/dashboard/settings/education.php:7, templates/dashboard/settings/skill.php:8
|
161 |
msgid "Settings"
|
162 |
msgstr ""
|
163 |
|
177 |
msgid "Tutor Pages"
|
178 |
msgstr ""
|
179 |
|
180 |
+
#: classes/Admin.php:139, classes/Instructors_List.php:130, templates/dashboard/dashboard.php:92, templates/dashboard/purchase_history.php:23, templates/dashboard/withdraw.php:185, views/pages/view_attempt.php:59, views/pages/tools/tutor_pages.php:11
|
181 |
msgid "Status"
|
182 |
msgstr ""
|
183 |
|
184 |
+
#: classes/Admin.php:245, templates/permission-denied.php:40, templates/dashboard/create-course.php:25, templates/single/lesson/required-enroll.php:5
|
185 |
msgid "Permission Denied"
|
186 |
msgstr ""
|
187 |
|
201 |
msgid "If you like %1$s please leave us a %2$s rating. A huge thanks in advance!"
|
202 |
msgstr ""
|
203 |
|
204 |
+
#: classes/Ajax.php:66, classes/Ajax.php:119, classes/Ajax.php:206, classes/Ajax.php:270, classes/Ajax.php:349, classes/Ajax.php:392, classes/Ajax.php:413, classes/Ajax.php:526, classes/Ajax.php:598, classes/Course.php:447, classes/Course.php:482, classes/Course.php:725, classes/Course.php:778, classes/Course.php:815, classes/Course.php:835, classes/Instructor.php:250, classes/Lesson.php:124, classes/Lesson.php:164, classes/Lesson.php:220, classes/Quiz.php:148, classes/Quiz.php:560, classes/Quiz.php:652, classes/Quiz.php:707, classes/Quiz.php:750, classes/Quiz.php:792, classes/Quiz.php:815, classes/Quiz.php:910, classes/Quiz.php:933, classes/Quiz.php:954, classes/Quiz.php:1082, classes/Quiz.php:1127, classes/Quiz.php:1208, classes/Quiz.php:1268, classes/Quiz.php:1293, classes/Q_and_A.php:71
|
205 |
msgid "Access Denied"
|
206 |
msgstr ""
|
207 |
|
208 |
+
#: classes/Ajax.php:189
|
209 |
msgid "Rating placed success"
|
210 |
msgstr ""
|
211 |
|
212 |
+
#: classes/Ajax.php:211
|
213 |
msgid "Empty question title or body"
|
214 |
msgstr ""
|
215 |
|
216 |
+
#: classes/Ajax.php:249
|
217 |
msgid "Question has been added successfully"
|
218 |
msgstr ""
|
219 |
|
220 |
+
#: classes/Ajax.php:259
|
221 |
msgid "Please write answer"
|
222 |
msgstr ""
|
223 |
|
224 |
+
#: classes/Ajax.php:295
|
225 |
msgid "Answer has been added successfully"
|
226 |
msgstr ""
|
227 |
|
228 |
+
#: classes/Ajax.php:334
|
229 |
msgid "Course added to wish list"
|
230 |
msgstr ""
|
231 |
|
232 |
+
#: classes/Ajax.php:323
|
233 |
msgid "Course removed from wish list"
|
234 |
msgstr ""
|
235 |
|
236 |
+
#: classes/Ajax.php:464, classes/Ajax.php:468
|
237 |
msgid "ERROR:"
|
238 |
msgstr ""
|
239 |
|
240 |
+
#: classes/Ajax.php:468
|
241 |
msgid "Username is required."
|
242 |
msgstr ""
|
243 |
|
244 |
+
#: classes/Ajax.php:512
|
245 |
msgid "Announcement created successfully"
|
246 |
msgstr ""
|
247 |
|
248 |
+
#: classes/Ajax.php:513
|
249 |
msgid "Announcement updated successfully"
|
250 |
msgstr ""
|
251 |
|
252 |
+
#: classes/Ajax.php:514
|
253 |
msgid "Announcement creation failed"
|
254 |
msgstr ""
|
255 |
|
256 |
+
#: classes/Ajax.php:515
|
257 |
msgid "Announcement update failed"
|
258 |
msgstr ""
|
259 |
|
260 |
+
#: classes/Ajax.php:544
|
261 |
msgid "Course name required"
|
262 |
msgstr ""
|
263 |
|
264 |
+
#: classes/Ajax.php:549
|
265 |
msgid "Announcement title required"
|
266 |
msgstr ""
|
267 |
|
268 |
+
#: classes/Ajax.php:553
|
269 |
msgid "Announcement summary required"
|
270 |
msgstr ""
|
271 |
|
272 |
+
#: classes/Ajax.php:611
|
273 |
msgid "Announcement delete failed"
|
274 |
msgstr ""
|
275 |
|
276 |
+
#: classes/Ajax.php:605
|
277 |
msgid "Announcement deleted successfully"
|
278 |
msgstr ""
|
279 |
|
280 |
+
#: classes/Course.php:169
|
281 |
msgid "Fully booked"
|
282 |
msgstr ""
|
283 |
|
284 |
+
#: classes/Course.php:191, classes/Course.php:275
|
285 |
msgid "Course Builder"
|
286 |
msgstr ""
|
287 |
|
288 |
+
#: classes/Course.php:192, classes/Course.php:277
|
289 |
msgid "Additional Data"
|
290 |
msgstr ""
|
291 |
|
292 |
+
#: classes/Course.php:193, classes/Course.php:274
|
293 |
msgid "Video"
|
294 |
msgstr ""
|
295 |
|
296 |
+
#: classes/Course.php:203, classes/Course.php:1380, views/options/options_generator.php:2
|
297 |
msgid "Tutor Settings"
|
298 |
msgstr ""
|
299 |
|
300 |
+
#: classes/Course.php:492
|
301 |
msgid "Topic has been updated"
|
302 |
msgstr ""
|
303 |
|
304 |
+
#: classes/Course.php:506, classes/Options.php:448, classes/Post_types.php:172, templates/single/course/course-topics.php:39
|
305 |
msgid "Lessons"
|
306 |
msgstr ""
|
307 |
|
308 |
+
#: classes/Course.php:508, templates/course-filter/filters.php:74, templates/dashboard/earning/statement.php:29
|
309 |
msgid "Price"
|
310 |
msgstr ""
|
311 |
|
312 |
+
#: classes/Course.php:537
|
313 |
msgid "free"
|
314 |
msgstr ""
|
315 |
|
316 |
+
#: classes/Course.php:587
|
317 |
msgid "Please Sign In first"
|
318 |
msgstr ""
|
319 |
|
320 |
+
#: classes/Course.php:635, classes/Lesson.php:310
|
321 |
msgid "Please Sign-In"
|
322 |
msgstr ""
|
323 |
|
324 |
+
#: classes/Course.php:761
|
325 |
+
msgid "No instructor available or you have already added maximum instructors"
|
326 |
msgstr ""
|
327 |
|
328 |
+
#: classes/Course.php:765
|
329 |
+
msgid "To add unlimited multiple instructors in your course, get %1$sTutor LMS Pro%2$s"
|
330 |
msgstr ""
|
331 |
|
332 |
+
#: classes/Course.php:1210
|
333 |
msgid "complete all lessons to mark this course as complete"
|
334 |
msgstr ""
|
335 |
|
336 |
+
#: classes/Course.php:1247
|
337 |
msgid "You have to pass %s quizzes to complete this course."
|
338 |
msgstr ""
|
339 |
|
340 |
+
#: classes/Course.php:1359
|
341 |
msgid "Make This Course Public"
|
342 |
msgstr ""
|
343 |
|
344 |
+
#: classes/Course.php:1361
|
345 |
msgid "No enrollment required."
|
346 |
msgstr ""
|
347 |
|
348 |
+
#: classes/Course.php:1369
|
349 |
msgid "Disable Q&A"
|
350 |
msgstr ""
|
351 |
|
352 |
+
#: classes/Course.php:1429
|
353 |
msgid "Invalid Course ID or Access Denied."
|
354 |
msgstr ""
|
355 |
|
356 |
+
#: classes/Course_Settings_Tabs.php:32, classes/Options.php:224, classes/Tutor_Setup.php:400, views/metabox/course/settings-tabs.php:13
|
357 |
msgid "Course Settings"
|
358 |
msgstr ""
|
359 |
|
360 |
+
#: classes/Course_Settings_Tabs.php:38, classes/Options.php:121, classes/Options.php:124, classes/Options.php:223, classes/Tutor_Setup.php:561, classes/WooCommerce.php:294
|
361 |
msgid "General"
|
362 |
msgstr ""
|
363 |
|
364 |
+
#: classes/Course_Settings_Tabs.php:39, classes/Options.php:125, classes/Tutor_Setup.php:361
|
365 |
msgid "General Settings"
|
366 |
msgstr ""
|
367 |
|
368 |
+
#: classes/Course_Settings_Tabs.php:45
|
369 |
msgid "Maximum Students"
|
370 |
msgstr ""
|
371 |
|
372 |
+
#: classes/Course_Settings_Tabs.php:46, classes/Options.php:137, classes/Options.php:144, classes/Options.php:164, classes/Options.php:171, classes/Options.php:178, classes/Options.php:185, classes/Options.php:198, classes/Options.php:229, classes/Options.php:247, classes/Options.php:264, classes/Options.php:297, classes/Options.php:315, classes/Options.php:321, classes/Options.php:457, classes/Options.php:564, classes/Options.php:578, classes/Options.php:585, classes/Options.php:610, classes/Options.php:617, classes/Options.php:635, classes/Options.php:659, classes/User.php:193
|
373 |
msgid "Enable"
|
374 |
msgstr ""
|
375 |
|
376 |
+
#: classes/Course_Settings_Tabs.php:48
|
377 |
msgid "Number of students that can enrol in this course. Set 0 for no limits."
|
378 |
msgstr ""
|
379 |
|
380 |
+
#: classes/Course_Widget.php:23
|
381 |
msgid "Tutor Course"
|
382 |
msgstr ""
|
383 |
|
384 |
+
#: classes/Course_Widget.php:24
|
385 |
msgid "Display courses wherever widget support is available."
|
386 |
msgstr ""
|
387 |
|
389 |
msgid "New title"
|
390 |
msgstr ""
|
391 |
|
392 |
+
#: classes/Course_Widget.php:115
|
393 |
+
msgid "Title"
|
394 |
msgstr ""
|
395 |
|
396 |
+
#: classes/Course_Widget.php:122, templates/dashboard/purchase_history.php:20, views/pages/tools/tutor_pages.php:9
|
397 |
+
msgid "ID"
|
398 |
msgstr ""
|
399 |
|
400 |
+
#: classes/Course_Widget.php:126
|
401 |
msgid "Place single course id or comma (,) separated course ids"
|
402 |
msgstr ""
|
403 |
|
404 |
+
#: classes/Course_Widget.php:131
|
405 |
msgid "Exclude IDS:"
|
406 |
msgstr ""
|
407 |
|
408 |
+
#: classes/Course_Widget.php:134
|
409 |
msgid "Place comma (,) separated courses ids which you like to exclude from the query"
|
410 |
msgstr ""
|
411 |
|
412 |
+
#: classes/Course_Widget.php:140, classes/Options.php:113, templates/course-filter/filters.php:33
|
413 |
+
msgid "Category"
|
414 |
msgstr ""
|
415 |
|
416 |
+
#: classes/Course_Widget.php:144
|
417 |
msgid "Place comma (,) separated category ids"
|
418 |
msgstr ""
|
419 |
|
420 |
+
#: classes/Course_Widget.php:150
|
421 |
msgid "OrderBy"
|
422 |
msgstr ""
|
423 |
|
424 |
+
#: classes/Course_Widget.php:165
|
425 |
+
msgid "Order"
|
426 |
msgstr ""
|
427 |
|
428 |
+
#: classes/Course_Widget.php:175
|
429 |
msgid "Count:"
|
430 |
msgstr ""
|
431 |
|
432 |
+
#: classes/Course_Widget.php:178
|
433 |
msgid "Total results you like to show"
|
434 |
msgstr ""
|
435 |
|
436 |
+
#: classes/Dashboard.php:50
|
437 |
msgid "Auto Draft"
|
438 |
msgstr ""
|
439 |
|
449 |
msgid "Check and place necessary information here."
|
450 |
msgstr ""
|
451 |
|
452 |
+
#: classes/Email.php:32, classes/Instructors_List.php:125, classes/Students_List.php:66
|
453 |
msgid "Name"
|
454 |
msgstr ""
|
455 |
|
505 |
msgid "This key is invalid or has already been used. Please reset your password again if needed."
|
506 |
msgstr ""
|
507 |
|
508 |
+
#: classes/FormHandler.php:118
|
509 |
msgid "Please enter your password."
|
510 |
msgstr ""
|
511 |
|
512 |
+
#: classes/FormHandler.php:123
|
513 |
msgid "Passwords do not match."
|
514 |
msgstr ""
|
515 |
|
516 |
+
#: classes/FormHandler.php:165
|
517 |
msgid "Password Reset Request for %s"
|
518 |
msgstr ""
|
519 |
|
565 |
msgid "Instructor has been added successfully"
|
566 |
msgstr ""
|
567 |
|
568 |
+
#: classes/Instructors_List.php:76, classes/Withdraw_Requests_List.php:55, classes/Withdraw_Requests_List.php:66
|
569 |
msgid "Approve"
|
570 |
msgstr ""
|
571 |
|
572 |
+
#: classes/Instructors_List.php:79
|
573 |
msgid "Sure to Block?"
|
574 |
msgstr ""
|
575 |
|
576 |
+
#: classes/Instructors_List.php:79
|
577 |
msgid "Block"
|
578 |
msgstr ""
|
579 |
|
580 |
+
#: classes/Instructors_List.php:82
|
581 |
msgid "Sure to Un Block?"
|
582 |
msgstr ""
|
583 |
|
584 |
+
#: classes/Instructors_List.php:82
|
585 |
msgid "Unblock"
|
586 |
msgstr ""
|
587 |
|
588 |
+
#: classes/Instructors_List.php:92
|
589 |
msgid "Reject"
|
590 |
msgstr ""
|
591 |
|
592 |
+
#: classes/Instructors_List.php:92
|
593 |
msgid "Remove as Instructor"
|
594 |
msgstr ""
|
595 |
|
596 |
+
#: classes/Instructors_List.php:93
|
597 |
msgid "Sure to Reject?"
|
598 |
msgstr ""
|
599 |
|
600 |
+
#: classes/Instructors_List.php:93
|
601 |
msgid "Sure to Remove as Instructor?"
|
602 |
msgstr ""
|
603 |
|
604 |
+
#: classes/Instructors_List.php:126, classes/Students_List.php:67, templates/dashboard/registration.php:81, templates/dashboard/registration.php:83, views/pages/add_new_instructor.php:69, views/pages/add_new_instructor.php:75, templates/dashboard/instructor/registration.php:86, templates/dashboard/instructor/registration.php:89
|
605 |
msgid "E-Mail"
|
606 |
msgstr ""
|
607 |
|
608 |
+
#: classes/Instructors_List.php:127
|
609 |
msgid "Total Course"
|
610 |
msgstr ""
|
611 |
|
612 |
+
#: classes/Instructors_List.php:128
|
613 |
msgid "Instructor Commission"
|
614 |
msgstr ""
|
615 |
|
616 |
+
#: classes/Instructors_List.php:129, classes/Tutor_List_Table.php:438, classes/Tutor_List_Table.php:1368, templates/dashboard/announcements.php:113, templates/dashboard/announcements.php:123, templates/dashboard/purchase_history.php:24, views/pages/announcements.php:95, views/pages/announcements.php:114, templates/dashboard/assignments/submitted.php:71
|
617 |
msgid "Date"
|
618 |
msgstr ""
|
619 |
|
620 |
+
#: classes/Lesson.php:56, views/metabox/lesson-metabox.php:3, views/pages/announcements.php:197, views/pages/announcements.php:279, templates/dashboard/announcements/create.php:19, templates/dashboard/announcements/update.php:20
|
621 |
msgid "Select Course"
|
622 |
msgstr ""
|
623 |
|
624 |
+
#: classes/Lesson.php:57
|
625 |
msgid "Lesson Video"
|
626 |
msgstr ""
|
627 |
|
628 |
+
#: classes/Lesson.php:58, templates/global/attachments.php:25, templates/single/assignment/content.php:155
|
629 |
msgid "Attachments"
|
630 |
msgstr ""
|
631 |
|
632 |
+
#: classes/Lesson.php:134
|
633 |
msgid "Draft Lesson"
|
634 |
msgstr ""
|
635 |
|
636 |
+
#: classes/Lesson.php:189
|
637 |
msgid "Couldn't create lesson."
|
638 |
msgstr ""
|
639 |
|
640 |
+
#: classes/Lesson.php:273, classes/Options.php:220, classes/Question_Answers_List.php:78, classes/Quiz_Attempts_List.php:119, classes/Tutor_Setup.php:562, templates/student-public-profile.php:98, templates/dashboard/assignments.php:95, templates/dashboard/question-answer.php:27, templates/shortcode/tutor-instructor.php:27, views/pages/view_attempt.php:73, templates/dashboard/announcements/details.php:19, templates/dashboard/assignments/review.php:44, templates/dashboard/assignments/submitted.php:30, templates/dashboard/earning/statement.php:12, templates/single/quiz/top.php:27
|
641 |
msgid "Course"
|
642 |
msgstr ""
|
643 |
|
644 |
+
#: classes/Options.php:87
|
645 |
msgid "Option Updated"
|
646 |
msgstr ""
|
647 |
|
648 |
+
#: classes/Options.php:94
|
649 |
msgid "/course/sample-course/<code>lessons</code>/sample-lesson/"
|
650 |
msgstr ""
|
651 |
|
652 |
+
#: classes/Options.php:97
|
653 |
msgctxt "tutor student profile"
|
654 |
msgid "profile"
|
655 |
msgstr ""
|
656 |
|
657 |
+
#: classes/Options.php:100, classes/Tutor_Setup.php:327
|
658 |
msgid "Unlimited"
|
659 |
msgstr ""
|
660 |
|
661 |
+
#: classes/Options.php:104, views/metabox/video-metabox.php:21
|
662 |
msgid "HTML 5 (mp4)"
|
663 |
msgstr ""
|
664 |
|
665 |
+
#: classes/Options.php:105, views/metabox/video-metabox.php:25
|
666 |
msgid "External URL"
|
667 |
msgstr ""
|
668 |
|
669 |
+
#: classes/Options.php:106, views/metabox/video-metabox.php:29
|
670 |
msgid "Youtube"
|
671 |
msgstr ""
|
672 |
|
673 |
+
#: classes/Options.php:107, views/metabox/video-metabox.php:33
|
674 |
msgid "Vimeo"
|
675 |
msgstr ""
|
676 |
|
677 |
+
#: classes/Options.php:108, views/metabox/video-metabox.php:37
|
678 |
msgid "Embedded"
|
679 |
msgstr ""
|
680 |
|
681 |
+
#: classes/Options.php:112
|
682 |
msgid "Keyword Search"
|
683 |
msgstr ""
|
684 |
|
685 |
+
#: classes/Options.php:114, templates/course-filter/filters.php:42
|
|
|
|
|
|
|
|
|
686 |
msgid "Tag"
|
687 |
msgstr ""
|
688 |
|
689 |
+
#: classes/Options.php:115, views/metabox/course-level-metabox.php:10
|
690 |
msgid "Difficulty Level"
|
691 |
msgstr ""
|
692 |
|
693 |
+
#: classes/Options.php:116
|
694 |
msgid "Price Type"
|
695 |
msgstr ""
|
696 |
|
697 |
+
#: classes/Options.php:129, classes/Utils.php:7185
|
698 |
msgid "Dashboard Page"
|
699 |
msgstr ""
|
700 |
|
701 |
+
#: classes/Options.php:132
|
702 |
msgid "This page will be used for student and instructor dashboard"
|
703 |
msgstr ""
|
704 |
|
705 |
+
#: classes/Options.php:136, classes/Tutor_Setup.php:371
|
706 |
msgid "Public Profile"
|
707 |
msgstr ""
|
708 |
|
709 |
+
#: classes/Options.php:139
|
710 |
msgid "Enable this to make a profile publicly visible"
|
711 |
msgstr ""
|
712 |
|
713 |
+
#: classes/Options.php:143
|
714 |
msgid "Profile Completion"
|
715 |
msgstr ""
|
716 |
|
717 |
+
#: classes/Options.php:146
|
718 |
msgid "Enabling this feature will show a notification bar to students and instructors to complete their profile information"
|
719 |
msgstr ""
|
720 |
|
721 |
+
#: classes/Options.php:150
|
722 |
msgid "Tutor Native Login"
|
723 |
msgstr ""
|
724 |
|
725 |
+
#: classes/Options.php:151, classes/Options.php:328, classes/Options.php:335, classes/Options.php:342, classes/Options.php:349, classes/Options.php:356, classes/Options.php:363, classes/Options.php:370, classes/Options.php:377, classes/Options.php:384, classes/Options.php:391, classes/Options.php:398, classes/Options.php:405, classes/Options.php:412, classes/Options.php:419, classes/Options.php:426, classes/Options.php:533
|
726 |
msgid "Disable"
|
727 |
msgstr ""
|
728 |
|
729 |
+
#: classes/Options.php:153
|
730 |
msgid "Disable to use the default WordPress login page"
|
731 |
msgstr ""
|
732 |
|
733 |
+
#: classes/Options.php:157
|
734 |
msgid "Course Visibility"
|
735 |
msgstr ""
|
736 |
|
737 |
+
#: classes/Options.php:158
|
738 |
msgid "Logged in only"
|
739 |
msgstr ""
|
740 |
|
741 |
+
#: classes/Options.php:159
|
742 |
msgid "Students must be logged in to view course"
|
743 |
msgstr ""
|
744 |
|
745 |
+
#: classes/Options.php:163
|
746 |
msgid "Erase upon uninstallation"
|
747 |
msgstr ""
|
748 |
|
749 |
+
#: classes/Options.php:165
|
750 |
msgid "Delete all data during uninstallation"
|
751 |
msgstr ""
|
752 |
|
753 |
+
#: classes/Options.php:170
|
754 |
msgid "Spotlight mode"
|
755 |
msgstr ""
|
756 |
|
757 |
+
#: classes/Options.php:173
|
758 |
msgid "This will hide the header and the footer and enable spotlight (full screen) mode when students view lessons."
|
759 |
msgstr ""
|
760 |
|
761 |
+
#: classes/Options.php:177, classes/Tutor_Setup.php:381
|
762 |
msgid "YouTube Player"
|
763 |
msgstr ""
|
764 |
|
765 |
+
#: classes/Options.php:180, classes/Options.php:187
|
766 |
msgid "Disable this option to use Tutor LMS video player."
|
767 |
msgstr ""
|
768 |
|
769 |
+
#: classes/Options.php:184, classes/Tutor_Setup.php:386
|
770 |
msgid "Vimeo Player"
|
771 |
msgstr ""
|
772 |
|
773 |
+
#: classes/Options.php:191
|
774 |
msgid "Pagination"
|
775 |
msgstr ""
|
776 |
|
777 |
+
#: classes/Options.php:193
|
778 |
msgid "Number of items you would like displayed \"per page\" in the pagination"
|
779 |
msgstr ""
|
780 |
|
781 |
+
#: classes/Options.php:197
|
782 |
msgid "Maintenance Mode"
|
783 |
msgstr ""
|
784 |
|
785 |
+
#: classes/Options.php:200
|
786 |
msgid "Enabling the maintenance mode allows you to display a custom message on the frontend. During this time, visitors can not access the site content. But the wp-admin dashboard will remain accessible."
|
787 |
msgstr ""
|
788 |
|
789 |
+
#: classes/Options.php:204
|
790 |
msgid "Frontend Admin Bar"
|
791 |
msgstr ""
|
792 |
|
793 |
+
#: classes/Options.php:205
|
794 |
msgid "Hide"
|
795 |
msgstr ""
|
796 |
|
797 |
+
#: classes/Options.php:207
|
798 |
msgid "Hide admin bar option allow you to hide WordPress admin bar entirely from the frontend. It will still show to administrator roles user"
|
799 |
msgstr ""
|
800 |
|
801 |
+
#: classes/Options.php:211
|
802 |
msgid "Error message for wrong login credentials"
|
803 |
msgstr ""
|
804 |
|
805 |
+
#: classes/Options.php:213
|
806 |
msgid "Login error message displayed when the user puts wrong login credentials."
|
807 |
msgstr ""
|
808 |
|
809 |
+
#: classes/Options.php:228
|
810 |
msgid "Gutenberg Editor"
|
811 |
msgstr ""
|
812 |
|
813 |
+
#: classes/Options.php:230
|
814 |
msgid "Use Gutenberg editor on course description area."
|
815 |
msgstr ""
|
816 |
|
817 |
+
#: classes/Options.php:234, classes/Options.php:240, classes/Options.php:309, classes/Options.php:462, classes/WooCommerce.php:306
|
818 |
msgid "Enable / Disable"
|
819 |
msgstr ""
|
820 |
|
821 |
+
#: classes/Options.php:235
|
822 |
msgid "Hide course products from shop page"
|
823 |
msgstr ""
|
824 |
|
825 |
+
#: classes/Options.php:236
|
826 |
msgid "Enabling this feature will remove course products from the shop page."
|
827 |
msgstr ""
|
828 |
|
829 |
+
#: classes/Options.php:241
|
830 |
msgid "Course Content Access"
|
831 |
msgstr ""
|
832 |
|
833 |
+
#: classes/Options.php:242
|
834 |
msgid "Allow instructors and admins to view the course content without enrolling"
|
835 |
msgstr ""
|
836 |
|
837 |
+
#: classes/Options.php:246
|
838 |
msgid "Auto redirect to courses"
|
839 |
msgstr ""
|
840 |
|
841 |
+
#: classes/Options.php:248
|
842 |
msgid "When a user's WooCommerce order is auto-completed, they will be redirected to enrolled courses"
|
843 |
msgstr ""
|
844 |
|
845 |
+
#: classes/Options.php:252
|
846 |
msgid "Course Completion Process"
|
847 |
msgstr ""
|
848 |
|
849 |
+
#: classes/Options.php:256
|
850 |
msgid "Flexible"
|
851 |
msgstr ""
|
852 |
|
853 |
+
#: classes/Options.php:257
|
854 |
msgid "Strict Mode"
|
855 |
msgstr ""
|
856 |
|
857 |
+
#: classes/Options.php:259
|
858 |
msgid "Students can complete courses anytime in the Flexible mode. In the Strict mode, students have to complete, pass all the lessons and quizzes (if any) to mark a course as complete."
|
859 |
msgstr ""
|
860 |
|
861 |
+
#: classes/Options.php:263
|
862 |
msgid "Course Retake"
|
863 |
msgstr ""
|
864 |
|
865 |
+
#: classes/Options.php:265
|
866 |
msgid "Enabling this feature will allow students to reset course progress and start over."
|
867 |
msgstr ""
|
868 |
|
869 |
+
#: classes/Options.php:270
|
870 |
msgid "Archive"
|
871 |
msgstr ""
|
872 |
|
873 |
+
#: classes/Options.php:271
|
874 |
msgid "Course Archive Settings"
|
875 |
msgstr ""
|
876 |
|
877 |
+
#: classes/Options.php:275
|
878 |
msgid "Course Archive Page"
|
879 |
msgstr ""
|
880 |
|
881 |
+
#: classes/Options.php:278
|
882 |
msgid "This page will be used to list all the published courses."
|
883 |
msgstr ""
|
884 |
|
885 |
+
#: classes/Options.php:282
|
886 |
msgid "Column Per Row"
|
887 |
msgstr ""
|
888 |
|
889 |
+
#: classes/Options.php:285
|
890 |
msgid "Define how many column you want to use to display courses."
|
891 |
msgstr ""
|
892 |
|
893 |
+
#: classes/Options.php:289, classes/Tutor_Setup.php:419
|
894 |
msgid "Courses Per Page"
|
895 |
msgstr ""
|
896 |
|
897 |
+
#: classes/Options.php:292
|
898 |
msgid "Define how many courses you want to show per page"
|
899 |
msgstr ""
|
900 |
|
901 |
+
#: classes/Options.php:296
|
902 |
msgid "Course Filter"
|
903 |
msgstr ""
|
904 |
|
905 |
+
#: classes/Options.php:298
|
906 |
msgid "Show sorting and filtering options on course archive page"
|
907 |
msgstr ""
|
908 |
|
909 |
+
#: classes/Options.php:302
|
910 |
msgid "Preferred Course Filters"
|
911 |
msgstr ""
|
912 |
|
913 |
+
#: classes/Options.php:304
|
914 |
msgid "Choose preferred filter options you'd like to show in course archive page."
|
915 |
msgstr ""
|
916 |
|
917 |
+
#: classes/Options.php:310
|
918 |
msgid "Course Display Settings"
|
919 |
msgstr ""
|
920 |
|
921 |
+
#: classes/Options.php:314
|
922 |
msgid "Display Instructor Info"
|
923 |
msgstr ""
|
924 |
|
925 |
+
#: classes/Options.php:316
|
926 |
msgid "Show instructor bio on each page"
|
927 |
msgstr ""
|
928 |
|
929 |
+
#: classes/Options.php:320
|
930 |
msgid "Question and Answer"
|
931 |
msgstr ""
|
932 |
|
933 |
+
#: classes/Options.php:323
|
934 |
msgid "Enabling this feature will add a Q&A section on every course."
|
935 |
msgstr ""
|
936 |
|
937 |
+
#: classes/Options.php:327
|
938 |
msgid "Course Author"
|
939 |
msgstr ""
|
940 |
|
941 |
+
#: classes/Options.php:330
|
942 |
msgid "Disabling this feature will be removed course author name from the course page."
|
943 |
msgstr ""
|
944 |
|
945 |
+
#: classes/Options.php:334
|
946 |
msgid "Course Level"
|
947 |
msgstr ""
|
948 |
|
949 |
+
#: classes/Options.php:337
|
950 |
msgid "Disabling this feature will be removed course level from the course page."
|
951 |
msgstr ""
|
952 |
|
953 |
+
#: classes/Options.php:341
|
954 |
msgid "Course Share"
|
955 |
msgstr ""
|
956 |
|
957 |
+
#: classes/Options.php:344
|
958 |
msgid "Disabling this feature will be removed course share option from the course page."
|
959 |
msgstr ""
|
960 |
|
961 |
+
#: classes/Options.php:348
|
962 |
msgid "Course Duration"
|
963 |
msgstr ""
|
964 |
|
965 |
+
#: classes/Options.php:351
|
966 |
msgid "Disabling this feature will be removed course duration from the course page."
|
967 |
msgstr ""
|
968 |
|
969 |
+
#: classes/Options.php:355
|
970 |
msgid "Course Total Enrolled"
|
971 |
msgstr ""
|
972 |
|
973 |
+
#: classes/Options.php:358
|
974 |
msgid "Disabling this feature will be removed course total enrolled from the course page."
|
975 |
msgstr ""
|
976 |
|
977 |
+
#: classes/Options.php:362
|
978 |
msgid "Course Update Date"
|
979 |
msgstr ""
|
980 |
|
981 |
+
#: classes/Options.php:365
|
982 |
msgid "Disabling this feature will be removed course update date from the course page."
|
983 |
msgstr ""
|
984 |
|
985 |
+
#: classes/Options.php:369
|
986 |
msgid "Course Progress Bar"
|
987 |
msgstr ""
|
988 |
|
989 |
+
#: classes/Options.php:372
|
990 |
msgid "Disabling this feature will be removed completing progress bar from the course page."
|
991 |
msgstr ""
|
992 |
|
993 |
+
#: classes/Options.php:376
|
994 |
msgid "Course Material"
|
995 |
msgstr ""
|
996 |
|
997 |
+
#: classes/Options.php:379
|
998 |
msgid "Disabling this feature will be removed course material from the course page."
|
999 |
msgstr ""
|
1000 |
|
1001 |
+
#: classes/Options.php:383
|
1002 |
msgid "Course About"
|
1003 |
msgstr ""
|
1004 |
|
1005 |
+
#: classes/Options.php:386
|
1006 |
msgid "Disabling this feature will be removed course about from the course page."
|
1007 |
msgstr ""
|
1008 |
|
1009 |
+
#: classes/Options.php:390
|
1010 |
msgid "Course Description"
|
1011 |
msgstr ""
|
1012 |
|
1013 |
+
#: classes/Options.php:393
|
1014 |
msgid "Disabling this feature will be removed course description from the course page."
|
1015 |
msgstr ""
|
1016 |
|
1017 |
+
#: classes/Options.php:397
|
1018 |
msgid "Course Benefits"
|
1019 |
msgstr ""
|
1020 |
|
1021 |
+
#: classes/Options.php:400
|
1022 |
msgid "Disabling this feature will be removed course benefits from the course page."
|
1023 |
msgstr ""
|
1024 |
|
1025 |
+
#: classes/Options.php:404
|
1026 |
msgid "Course Requirements"
|
1027 |
msgstr ""
|
1028 |
|
1029 |
+
#: classes/Options.php:407
|
1030 |
msgid "Disabling this feature will be removed course requirements from the course page."
|
1031 |
msgstr ""
|
1032 |
|
1033 |
+
#: classes/Options.php:411
|
1034 |
msgid "Course Target Audience"
|
1035 |
msgstr ""
|
1036 |
|
1037 |
+
#: classes/Options.php:414
|
1038 |
msgid "Disabling this feature will be removed course target audience from the course page."
|
1039 |
msgstr ""
|
1040 |
|
1041 |
+
#: classes/Options.php:418
|
1042 |
msgid "Course Announcements"
|
1043 |
msgstr ""
|
1044 |
|
1045 |
+
#: classes/Options.php:421
|
1046 |
msgid "Disabling this feature will be removed course announcements from the course page."
|
1047 |
msgstr ""
|
1048 |
|
1049 |
+
#: classes/Options.php:425
|
1050 |
msgid "Course Review"
|
1051 |
msgstr ""
|
1052 |
|
1053 |
+
#: classes/Options.php:428
|
1054 |
msgid "Disabling this feature will be removed course review system from the course page."
|
1055 |
msgstr ""
|
1056 |
|
1057 |
+
#: classes/Options.php:432
|
1058 |
msgid "Preferred Video Source"
|
1059 |
msgstr ""
|
1060 |
|
1061 |
+
#: classes/Options.php:434
|
1062 |
msgid "Choose video sources you'd like to support. Unchecking all will not disable video feature."
|
1063 |
msgstr ""
|
1064 |
|
1065 |
+
#: classes/Options.php:438
|
1066 |
msgid "Default Video Source"
|
1067 |
msgstr ""
|
1068 |
|
1069 |
+
#: classes/Options.php:441
|
1070 |
msgid "Choose video source to be selected by default."
|
1071 |
msgstr ""
|
1072 |
|
1073 |
+
#: classes/Options.php:451
|
1074 |
msgid "Lesson Settings"
|
1075 |
msgstr ""
|
1076 |
|
1077 |
+
#: classes/Options.php:452
|
1078 |
msgid "Lesson settings will be here"
|
1079 |
msgstr ""
|
1080 |
|
1081 |
+
#: classes/Options.php:456, views/modal/edit-lesson.php:12
|
1082 |
msgid "Classic Editor"
|
1083 |
msgstr ""
|
1084 |
|
1085 |
+
#: classes/Options.php:458
|
1086 |
msgid "Enable classic editor to get full support of any editor/page builder."
|
1087 |
msgstr ""
|
1088 |
|
1089 |
+
#: classes/Options.php:463
|
1090 |
msgid "Automatically load next course content."
|
1091 |
msgstr ""
|
1092 |
|
1093 |
+
#: classes/Options.php:464
|
1094 |
msgid "Enabling this feature will be load next course content automatically after finishing current video."
|
1095 |
msgstr ""
|
1096 |
|
1097 |
+
#: classes/Options.php:468
|
1098 |
msgid "Lesson Permalink Base"
|
1099 |
msgstr ""
|
1100 |
|
1101 |
+
#: classes/Options.php:474
|
1102 |
msgid "Youtube API Key"
|
1103 |
msgstr ""
|
1104 |
|
1105 |
+
#: classes/Options.php:483, classes/Options.php:486, classes/Quiz_Attempts_List.php:118, classes/Tutor_Setup.php:563, views/metabox/course-contents.php:174, views/metabox/course-topics.php:68, views/pages/view_attempt.php:39, templates/single/quiz/top.php:24
|
1106 |
msgid "Quiz"
|
1107 |
msgstr ""
|
1108 |
|
1109 |
+
#: classes/Options.php:487
|
1110 |
msgid "The values you set here define the default values that are used in the settings form when you create a new quiz."
|
1111 |
msgstr ""
|
1112 |
|
1113 |
+
#: classes/Options.php:491, classes/Tutor_Setup.php:432, views/modal/edit_quiz.php:151
|
1114 |
msgid "Time Limit"
|
1115 |
msgstr ""
|
1116 |
|
1117 |
+
#: classes/Options.php:492
|
1118 |
msgid "0 means unlimited time."
|
1119 |
msgstr ""
|
1120 |
|
1121 |
+
#: classes/Options.php:503, views/modal/edit_quiz.php:163
|
1122 |
msgid "Weeks"
|
1123 |
msgstr ""
|
1124 |
|
1125 |
+
#: classes/Options.php:504, views/modal/edit_quiz.php:162
|
1126 |
msgid "Days"
|
1127 |
msgstr ""
|
1128 |
|
1129 |
+
#: classes/Options.php:505, views/modal/edit_quiz.php:161
|
1130 |
msgid "Hours"
|
1131 |
msgstr ""
|
1132 |
|
1133 |
+
#: classes/Options.php:506, views/modal/edit_quiz.php:160
|
1134 |
msgid "Minutes"
|
1135 |
msgstr ""
|
1136 |
|
1137 |
+
#: classes/Options.php:507, views/modal/edit_quiz.php:159
|
1138 |
msgid "Seconds"
|
1139 |
msgstr ""
|
1140 |
|
1141 |
+
#: classes/Options.php:514
|
1142 |
msgid "When time expires"
|
1143 |
msgstr ""
|
1144 |
|
1145 |
+
#: classes/Options.php:518, classes/Tutor_Setup.php:439
|
1146 |
msgid "The current quiz answers are submitted automatically."
|
1147 |
msgstr ""
|
1148 |
|
1149 |
+
#: classes/Options.php:519, classes/Tutor_Setup.php:440
|
1150 |
msgid "The current quiz answers are submitted by students."
|
1151 |
msgstr ""
|
1152 |
|
1153 |
+
#: classes/Options.php:520, classes/Tutor_Setup.php:441
|
1154 |
msgid "Attempts must be submitted before time expires, otherwise they will not be counted"
|
1155 |
msgstr ""
|
1156 |
|
1157 |
+
#: classes/Options.php:522
|
1158 |
msgid "Choose which action to follow when the quiz time expires."
|
1159 |
msgstr ""
|
1160 |
|
1161 |
+
#: classes/Options.php:526
|
1162 |
msgid "Attempts allowed"
|
1163 |
msgstr ""
|
1164 |
|
1165 |
+
#: classes/Options.php:528
|
1166 |
msgid "The highest number of attempts students are allowed to take for a quiz. 0 means unlimited attempts."
|
1167 |
msgstr ""
|
1168 |
|
1169 |
+
#: classes/Options.php:532
|
1170 |
msgid "Show Previous button"
|
1171 |
msgstr ""
|
1172 |
|
1173 |
+
#: classes/Options.php:535
|
1174 |
msgid "Choose whether to show or hide previous button for single question."
|
1175 |
msgstr ""
|
1176 |
|
1177 |
+
#: classes/Options.php:539
|
1178 |
msgid "Final grade calculation"
|
1179 |
msgstr ""
|
1180 |
|
1181 |
+
#: classes/Options.php:543, classes/Tutor_Setup.php:455
|
1182 |
msgid "Highest Grade"
|
1183 |
msgstr ""
|
1184 |
|
1185 |
+
#: classes/Options.php:544, classes/Tutor_Setup.php:460
|
1186 |
msgid "Average Grade"
|
1187 |
msgstr ""
|
1188 |
|
1189 |
+
#: classes/Options.php:545, classes/Tutor_Setup.php:465
|
1190 |
msgid "First Attempt"
|
1191 |
msgstr ""
|
1192 |
|
1193 |
+
#: classes/Options.php:546, classes/Tutor_Setup.php:470
|
1194 |
msgid "Last Attempt"
|
1195 |
msgstr ""
|
1196 |
|
1197 |
+
#: classes/Options.php:548
|
1198 |
msgid "When multiple attempts are allowed, which method should be used to calculate a student's final grade for the quiz."
|
1199 |
msgstr ""
|
1200 |
|
1201 |
+
#: classes/Options.php:558
|
1202 |
msgid "Instructor Profile Settings"
|
1203 |
msgstr ""
|
1204 |
|
1205 |
+
#: classes/Options.php:559, classes/Options.php:598, classes/Options.php:630
|
1206 |
msgid "Enable Disable Option to on/off notification on various event"
|
1207 |
msgstr ""
|
1208 |
|
1209 |
+
#: classes/Options.php:563
|
1210 |
msgid "Course Marketplace"
|
1211 |
msgstr ""
|
1212 |
|
1213 |
+
#: classes/Options.php:566
|
1214 |
msgid "Allow multiple instructors to upload their courses."
|
1215 |
msgstr ""
|
1216 |
|
1217 |
+
#: classes/Options.php:570, classes/Utils.php:7186
|
1218 |
msgid "Instructor Registration Page"
|
1219 |
msgstr ""
|
1220 |
|
1221 |
+
#: classes/Options.php:573
|
1222 |
msgid "This page will be used to sign up new instructors."
|
1223 |
msgstr ""
|
1224 |
|
1225 |
+
#: classes/Options.php:577
|
1226 |
msgid "Allow publishing course"
|
1227 |
msgstr ""
|
1228 |
|
1229 |
+
#: classes/Options.php:580
|
1230 |
msgid "Enable instructors to publish course directly. <strong>Do not select</strong> if admins want to review courses before publishing."
|
1231 |
msgstr ""
|
1232 |
|
1233 |
+
#: classes/Options.php:584
|
1234 |
msgid "Become Instructor Button"
|
1235 |
msgstr ""
|
1236 |
|
1237 |
+
#: classes/Options.php:587
|
1238 |
msgid "Uncheck this option to hide the button from student dashboard."
|
1239 |
msgstr ""
|
1240 |
|
1241 |
+
#: classes/Options.php:597
|
1242 |
msgid "Student Profile settings"
|
1243 |
msgstr ""
|
1244 |
|
1245 |
+
#: classes/Options.php:602, classes/Utils.php:7187
|
1246 |
msgid "Student Registration Page"
|
1247 |
msgstr ""
|
1248 |
|
1249 |
+
#: classes/Options.php:605
|
1250 |
msgid "Choose the page for student registration page"
|
1251 |
msgstr ""
|
1252 |
|
1253 |
+
#: classes/Options.php:609
|
1254 |
msgid "Show reviews on profile"
|
1255 |
msgstr ""
|
1256 |
|
1257 |
+
#: classes/Options.php:612
|
1258 |
msgid "Enabling this will show the reviews written by each student on their profile"
|
1259 |
msgstr ""
|
1260 |
|
1261 |
+
#: classes/Options.php:616
|
1262 |
msgid "Show completed courses"
|
1263 |
msgstr ""
|
1264 |
|
1265 |
+
#: classes/Options.php:619
|
1266 |
msgid "Completed courses will be shown on student profiles. <br/> For example, you can see this link-"
|
1267 |
msgstr ""
|
1268 |
|
1269 |
+
#: classes/Options.php:626, classes/Options.php:634, classes/Tutor_Setup.php:491, templates/dashboard/earning.php:123, templates/dashboard/earning/chart-body.php:17, templates/dashboard/earning/statement.php:13, templates/dashboard/earning/statements.php:131
|
1270 |
msgid "Earning"
|
1271 |
msgstr ""
|
1272 |
|
1273 |
+
#: classes/Options.php:629
|
1274 |
msgid "Earning and commission allocation"
|
1275 |
msgstr ""
|
1276 |
|
1277 |
+
#: classes/Options.php:637
|
1278 |
msgid "If disabled, the Admin will receive 100% of the earning"
|
1279 |
msgstr ""
|
1280 |
|
1281 |
+
#: classes/Options.php:641
|
1282 |
msgid "Admin Commission Percentage"
|
1283 |
msgstr ""
|
1284 |
|
1285 |
+
#: classes/Options.php:643
|
1286 |
msgid "Define the commission of the Admin from each sale.(after deducting fees)"
|
1287 |
msgstr ""
|
1288 |
|
1289 |
+
#: classes/Options.php:647
|
1290 |
msgid "Instructor Commission Percentage"
|
1291 |
msgstr ""
|
1292 |
|
1293 |
+
#: classes/Options.php:649
|
1294 |
msgid "Define the commission for instructors from each sale.(after deducting fees)"
|
1295 |
msgstr ""
|
1296 |
|
1297 |
+
#: classes/Options.php:653
|
1298 |
msgid "Fee Deduction"
|
1299 |
msgstr ""
|
1300 |
|
1301 |
+
#: classes/Options.php:654
|
1302 |
msgid "Fees are charged from the entire sales amount. The remaining amount will be divided among admin and instructors."
|
1303 |
msgstr ""
|
1304 |
|
1305 |
+
#: classes/Options.php:664
|
1306 |
msgid "Fee Name"
|
1307 |
msgstr ""
|
1308 |
|
1309 |
+
#: classes/Options.php:669
|
1310 |
msgid "Fee Amount"
|
1311 |
msgstr ""
|
1312 |
|
1313 |
+
#: classes/Options.php:677
|
1314 |
msgid "Select Fees Type"
|
1315 |
msgstr ""
|
1316 |
|
1317 |
+
#: classes/Options.php:678
|
1318 |
msgid "Percent"
|
1319 |
msgstr ""
|
1320 |
|
1321 |
+
#: classes/Options.php:679
|
1322 |
msgid "Fixed"
|
1323 |
msgstr ""
|
1324 |
|
1325 |
+
#: classes/Options.php:687
|
1326 |
msgid "Show Statement Per Page"
|
1327 |
msgstr ""
|
1328 |
|
1329 |
+
#: classes/Options.php:689
|
1330 |
msgid "Define the number of statements to show."
|
1331 |
msgstr ""
|
1332 |
|
1333 |
+
#: classes/Options.php:696, templates/dashboard/withdraw.php:42
|
1334 |
msgid "Withdrawal"
|
1335 |
msgstr ""
|
1336 |
|
1337 |
+
#: classes/Options.php:699
|
1338 |
msgid "Withdrawal Settings"
|
1339 |
msgstr ""
|
1340 |
|
1341 |
+
#: classes/Options.php:703
|
1342 |
msgid "Minimum Withdraw Amount"
|
1343 |
msgstr ""
|
1344 |
|
1345 |
+
#: classes/Options.php:705
|
1346 |
msgid "Instructors should earn equal or above this amount to make a withdraw request."
|
1347 |
msgstr ""
|
1348 |
|
1349 |
+
#: classes/Options.php:711
|
1350 |
msgid "Withdraw Methods"
|
1351 |
msgstr ""
|
1352 |
|
1353 |
+
#: classes/Options.php:712
|
1354 |
msgid "Set withdraw settings"
|
1355 |
msgstr ""
|
1356 |
|
1357 |
+
#: classes/Options.php:718
|
1358 |
msgid "Style"
|
1359 |
msgstr ""
|
1360 |
|
1361 |
+
#: classes/Options.php:721
|
1362 |
msgid "Color Style"
|
1363 |
msgstr ""
|
1364 |
|
1365 |
+
#: classes/Options.php:725
|
1366 |
msgid "Primary Color"
|
1367 |
msgstr ""
|
1368 |
|
1369 |
+
#: classes/Options.php:730
|
1370 |
msgid "Primary Hover Color"
|
1371 |
msgstr ""
|
1372 |
|
1373 |
+
#: classes/Options.php:735
|
1374 |
msgid "Text color"
|
1375 |
msgstr ""
|
1376 |
|
1377 |
+
#: classes/Options.php:740
|
1378 |
msgid "Light color"
|
1379 |
msgstr ""
|
1380 |
|
1381 |
+
#: classes/Options.php:747
|
1382 |
msgid "Button Primary Color"
|
1383 |
msgstr ""
|
1384 |
|
1385 |
+
#: classes/Options.php:753
|
1386 |
msgid "Button Danger Color"
|
1387 |
msgstr ""
|
1388 |
|
1389 |
+
#: classes/Options.php:758
|
1390 |
msgid "Button Success Color"
|
1391 |
msgstr ""
|
1392 |
|
1393 |
+
#: classes/Options.php:763
|
1394 |
msgid "Button Warning Color"
|
1395 |
msgstr ""
|
1396 |
|
1397 |
+
#: classes/Options.php:773, classes/Options.php:776
|
1398 |
msgid "Monetization"
|
1399 |
msgstr ""
|
1400 |
|
1401 |
+
#: classes/Options.php:777
|
1402 |
msgid "You can monetize your LMS website by selling courses in a various way."
|
1403 |
msgstr ""
|
1404 |
|
1405 |
+
#: classes/Options.php:782
|
1406 |
msgid "Monetize Option"
|
1407 |
msgstr ""
|
1408 |
|
1409 |
+
#: classes/Options.php:786
|
1410 |
msgid "Disable Monetization"
|
1411 |
msgstr ""
|
1412 |
|
1413 |
+
#: classes/Options.php:788
|
1414 |
msgid "Select a monetization option to generate revenue by selling courses. Supports: WooCommerce, Easy Digital Downloads, Paid Memberships Pro"
|
1415 |
msgstr ""
|
1416 |
|
1451 |
msgid "Edit Course"
|
1452 |
msgstr ""
|
1453 |
|
1454 |
+
#: classes/Post_types.php:48, templates/dashboard/create-course.php:30, templates/single/lesson/required-enroll.php:10
|
1455 |
msgid "View Course"
|
1456 |
msgstr ""
|
1457 |
|
1458 |
+
#: classes/Post_types.php:49, classes/Tutor_List_Table.php:1333, templates/student-public-profile.php:98, templates/student-public-profile.php:158, templates/dashboard/announcements.php:86, templates/dashboard/assignments.php:34, templates/dashboard/purchase_history.php:21, templates/shortcode/tutor-instructor.php:27, views/pages/announcements.php:60, templates/single/course/instructors.php:72
|
1459 |
msgid "Courses"
|
1460 |
msgstr ""
|
1461 |
|
1750 |
msgid "View Assignment"
|
1751 |
msgstr ""
|
1752 |
|
1753 |
+
#: classes/Post_types.php:287, views/metabox/course-topics.php:97
|
1754 |
msgid "Assignments"
|
1755 |
msgstr ""
|
1756 |
|
1820 |
msgid "Preview course"
|
1821 |
msgstr ""
|
1822 |
|
1823 |
+
#: classes/Question_Answers_List.php:47, classes/Question_Answers_List.php:79, classes/Quiz.php:1153, templates/dashboard/question-answer.php:28, views/modal/question_form.php:142, views/pages/answer.php:11, templates/dashboard/question-answer/answers.php:13
|
1824 |
msgid "Answer"
|
1825 |
msgstr ""
|
1826 |
|
1827 |
+
#: classes/Question_Answers_List.php:76, classes/Quiz.php:824, templates/dashboard/question-answer.php:25, views/pages/view_attempt.php:194, templates/dashboard/my-quiz-attempts/attempts-details.php:215, templates/dashboard/quiz-attempts/quiz-reviews.php:232
|
1828 |
msgid "Question"
|
1829 |
msgstr ""
|
1830 |
|
1831 |
+
#: classes/Question_Answers_List.php:77, templates/student-public-profile.php:103, templates/dashboard/question-answer.php:26, templates/dashboard/quiz-attempts.php:31, templates/dashboard/assignments/review.php:50, templates/dashboard/assignments/submitted.php:72
|
1832 |
msgid "Student"
|
1833 |
msgstr ""
|
1834 |
|
1835 |
+
#: classes/Quiz.php:542
|
1836 |
msgid "Quiz has been timeout already"
|
1837 |
msgstr ""
|
1838 |
|
1839 |
+
#: classes/Quiz.php:680, classes/Quiz.php:768, views/metabox/course-contents.php:117, views/metabox/course-contents.php:206
|
1840 |
msgid "QUIZ"
|
1841 |
msgstr ""
|
1842 |
|
1843 |
+
#: classes/Quiz.php:893
|
1844 |
msgid "Please make sure you have added more than one option and saved them"
|
1845 |
msgstr ""
|
1846 |
|
1847 |
+
#: classes/Quiz.php:889
|
1848 |
msgid "Please select the correct answer"
|
1849 |
msgstr ""
|
1850 |
|
1851 |
+
#: classes/Quiz.php:1014, views/modal/question_answer_form.php:22
|
1852 |
msgid "True"
|
1853 |
msgstr ""
|
1854 |
|
1855 |
+
#: classes/Quiz.php:1021, views/modal/question_answer_form.php:26
|
1856 |
msgid "False"
|
1857 |
msgstr ""
|
1858 |
|
1859 |
+
#: classes/Quiz.php:1137
|
1860 |
msgid "Answer options & mark correct"
|
1861 |
msgstr ""
|
1862 |
|
1863 |
+
#: classes/Quiz.php:1140
|
1864 |
msgid "Make sure you’re saving the answers in the right order. Students will have to match this order exactly."
|
1865 |
msgstr ""
|
1866 |
|
1867 |
+
#: classes/Quiz.php:1175, classes/Quiz.php:1169, views/modal/question_form.php:164, views/modal/question_form.php:158, views/pages/view_attempt.php:337, templates/dashboard/quiz-attempts/quiz-reviews.php:404
|
1868 |
msgid "Mark as correct"
|
1869 |
msgstr ""
|
1870 |
|
1871 |
+
#: classes/Quiz.php:1325
|
1872 |
msgid "Access Denied."
|
1873 |
msgstr ""
|
1874 |
|
1875 |
+
#: classes/Quiz_Attempts_List.php:41
|
1876 |
msgid "Review"
|
1877 |
msgstr ""
|
1878 |
|
1879 |
+
#: classes/Quiz_Attempts_List.php:48
|
1880 |
msgid " ago"
|
1881 |
msgstr ""
|
1882 |
|
1883 |
+
#: classes/Quiz_Attempts_List.php:96
|
1884 |
msgid " out of "
|
1885 |
msgstr ""
|
1886 |
|
1887 |
+
#: classes/Quiz_Attempts_List.php:97
|
1888 |
msgid " pass "
|
1889 |
msgstr ""
|
1890 |
|
1891 |
+
#: classes/Quiz_Attempts_List.php:102, templates/dashboard/my-quiz-attempts.php:89, templates/dashboard/quiz-attempts.php:97, views/pages/view_attempt.php:101, templates/dashboard/my-quiz-attempts/attempts-details.php:176, templates/dashboard/quiz-attempts/quiz-reviews.php:162, templates/single/quiz/previous-attempts.php:75
|
1892 |
msgid "Fail"
|
1893 |
msgstr ""
|
1894 |
|
1895 |
+
#: classes/Quiz_Attempts_List.php:100, templates/dashboard/my-quiz-attempts.php:88, templates/dashboard/quiz-attempts.php:96, views/pages/view_attempt.php:99, templates/dashboard/my-quiz-attempts/attempts-details.php:174, templates/dashboard/quiz-attempts/quiz-reviews.php:160, templates/single/quiz/previous-attempts.php:75
|
1896 |
msgid "Pass"
|
1897 |
msgstr ""
|
1898 |
|
1899 |
+
#: classes/Quiz_Attempts_List.php:90, templates/dashboard/my-quiz-attempts.php:85, templates/dashboard/quiz-attempts.php:93, views/pages/view_attempt.php:92, templates/single/quiz/previous-attempts.php:73
|
1900 |
msgid "Under Review"
|
1901 |
msgstr ""
|
1902 |
|
1903 |
+
#: classes/Quiz_Attempts_List.php:120
|
1904 |
msgid "Total Questions"
|
1905 |
msgstr ""
|
1906 |
|
1907 |
+
#: classes/Quiz_Attempts_List.php:121
|
1908 |
msgid "Earned Points"
|
1909 |
msgstr ""
|
1910 |
|
1964 |
msgid "Setup Wizard"
|
1965 |
msgstr ""
|
1966 |
|
1967 |
+
#: classes/Tutor.php:519, classes/Utils.php:2554, templates/dashboard/dashboard.php:9
|
1968 |
msgid "Dashboard"
|
1969 |
msgstr ""
|
1970 |
|
1996 |
msgid "Easy Digital Downloads"
|
1997 |
msgstr ""
|
1998 |
|
1999 |
+
#: classes/TutorEDD.php:106, classes/WooCommerce.php:175
|
2000 |
msgid "Add Product"
|
2001 |
msgstr ""
|
2002 |
|
2003 |
+
#: classes/Tutor_List_Table.php:389, classes/Tutor_List_Table.php:1342, templates/dashboard/announcements.php:90, templates/dashboard/assignments.php:38, views/pages/announcements.php:69
|
2004 |
msgid "All"
|
2005 |
msgstr ""
|
2006 |
|
2007 |
+
#: classes/Tutor_List_Table.php:413, classes/Tutor_List_Table.php:1358, templates/dashboard/announcements.php:105, templates/dashboard/assignments.php:52, views/pages/announcements.php:85
|
2008 |
msgid "Sort By"
|
2009 |
msgstr ""
|
2010 |
|
2011 |
+
#: classes/Tutor_List_Table.php:538
|
2012 |
msgid "Bulk Actions"
|
2013 |
msgstr ""
|
2014 |
|
2015 |
+
#: classes/Tutor_List_Table.php:1351, templates/dashboard/announcements.php:99, templates/dashboard/assignments.php:47, views/pages/announcements.php:78, templates/dashboard/announcements/create.php:29, templates/dashboard/announcements/update.php:30
|
2016 |
msgid "No course found"
|
2017 |
msgstr ""
|
2018 |
|
2019 |
+
#: classes/Tutor_List_Table.php:1376, classes/Tutor_List_Table.php:1378, views/pages/announcements.php:52, views/pages/question_answer.php:23, views/pages/students.php:13, views/pages/withdraw_requests.php:13
|
2020 |
msgid "Search"
|
2021 |
msgstr ""
|
2022 |
|
2060 |
msgid "weeks"
|
2061 |
msgstr ""
|
2062 |
|
2063 |
+
#: classes/Tutor_Setup.php:275, classes/Tutor_Setup.php:564, classes/Utils.php:2568
|
2064 |
msgid "Instructor"
|
2065 |
msgstr ""
|
2066 |
|
2140 |
msgid "What message to display when the quiz time expires?"
|
2141 |
msgstr ""
|
2142 |
|
2143 |
+
#: classes/Tutor_Setup.php:447, views/modal/edit_quiz.php:218, templates/single/quiz/top.php:65
|
2144 |
msgid "Attempts Allowed"
|
2145 |
msgstr ""
|
2146 |
|
2244 |
msgid "Payment"
|
2245 |
msgstr ""
|
2246 |
|
2247 |
+
#: classes/Tutor_Setup.php:567, templates/single/quiz/body.php:436
|
2248 |
msgid "Finish"
|
2249 |
msgstr ""
|
2250 |
|
2276 |
msgid "Skip This Step"
|
2277 |
msgstr ""
|
2278 |
|
2279 |
+
#: classes/Tutor_Setup.php:623, classes/Tutor_Setup.php:730, templates/shortcode/tutor-instructor.php:48, views/modal/add_quiz.php:75, views/modal/add_quiz.php:98, views/modal/edit_quiz.php:137
|
2280 |
msgid "Next"
|
2281 |
msgstr ""
|
2282 |
|
2364 |
msgid "Tutor › Setup Wizard"
|
2365 |
msgstr ""
|
2366 |
|
2367 |
+
#: classes/User.php:195
|
2368 |
msgid "Dismiss"
|
2369 |
msgstr ""
|
2370 |
|
2371 |
+
#: classes/Utils.php:949
|
2372 |
msgid "Nonce not matched"
|
2373 |
msgstr ""
|
2374 |
|
2375 |
+
#: classes/Utils.php:1332
|
2376 |
msgid "Q&A"
|
2377 |
msgstr ""
|
2378 |
|
2379 |
+
#: classes/Utils.php:2223, templates/student-public-profile.php:115
|
2380 |
msgid "Course Enrolled"
|
2381 |
msgstr ""
|
2382 |
|
2383 |
+
#: classes/Utils.php:2555, templates/dashboard/my-profile.php:21
|
2384 |
msgid "My Profile"
|
2385 |
msgstr ""
|
2386 |
|
2387 |
+
#: classes/Utils.php:2556, templates/dashboard/dashboard.php:36, templates/dashboard/enrolled-courses.php:9
|
2388 |
msgid "Enrolled Courses"
|
2389 |
msgstr ""
|
2390 |
|
2391 |
+
#: classes/Utils.php:2557, templates/dashboard/wishlist.php:10
|
2392 |
msgid "Wishlist"
|
2393 |
msgstr ""
|
2394 |
|
2395 |
+
#: classes/Utils.php:2558
|
2396 |
msgid "Reviews"
|
2397 |
msgstr ""
|
2398 |
|
2399 |
+
#: classes/Utils.php:2559, templates/dashboard/my-quiz-attempts.php:25
|
2400 |
msgid "My Quiz Attempts"
|
2401 |
msgstr ""
|
2402 |
|
2403 |
+
#: classes/Utils.php:2560, templates/dashboard/purchase_history.php:9
|
2404 |
msgid "Purchase History"
|
2405 |
msgstr ""
|
2406 |
|
2407 |
+
#: classes/Utils.php:2573
|
2408 |
msgid "Create Course"
|
2409 |
msgstr ""
|
2410 |
|
2411 |
+
#: classes/Utils.php:2578, templates/dashboard/my-courses.php:9
|
2412 |
msgid "My Courses"
|
2413 |
msgstr ""
|
2414 |
|
2415 |
+
#: classes/Utils.php:2586
|
2416 |
msgid "Withdrawals"
|
2417 |
msgstr ""
|
2418 |
|
2419 |
+
#: classes/Utils.php:2594, templates/dashboard/question-answer.php:10, views/pages/question_answer.php:18
|
2420 |
msgid "Question & Answer"
|
2421 |
msgstr ""
|
2422 |
|
2423 |
+
#: classes/Utils.php:2615
|
2424 |
msgid "Logout"
|
2425 |
msgstr ""
|
2426 |
|
2427 |
+
#: classes/Utils.php:2630
|
2428 |
msgid "Retrieve Password"
|
2429 |
msgstr ""
|
2430 |
|
2431 |
+
#: classes/Utils.php:2739, templates/dashboard/dashboard.php:27
|
2432 |
msgid "Pending"
|
2433 |
msgstr ""
|
2434 |
|
2435 |
+
#: classes/Utils.php:2740
|
2436 |
msgid "Approved"
|
2437 |
msgstr ""
|
2438 |
|
2439 |
+
#: classes/Utils.php:2741
|
2440 |
msgid "Blocked"
|
2441 |
msgstr ""
|
2442 |
|
2443 |
+
#: classes/Utils.php:4445
|
2444 |
msgid "True/False"
|
2445 |
msgstr ""
|
2446 |
|
2447 |
+
#: classes/Utils.php:4450
|
2448 |
msgid "Single Choice"
|
2449 |
msgstr ""
|
2450 |
|
2451 |
+
#: classes/Utils.php:4455
|
2452 |
msgid "Multiple Choice"
|
2453 |
msgstr ""
|
2454 |
|
2455 |
+
#: classes/Utils.php:4460
|
2456 |
msgid "Open Ended/Essay"
|
2457 |
msgstr ""
|
2458 |
|
2459 |
+
#: classes/Utils.php:4465
|
2460 |
msgid "Fill In The Blanks"
|
2461 |
msgstr ""
|
2462 |
|
2463 |
+
#: classes/Utils.php:4470
|
2464 |
msgid "Short Answer"
|
2465 |
msgstr ""
|
2466 |
|
2467 |
+
#: classes/Utils.php:4475
|
2468 |
msgid "Matching"
|
2469 |
msgstr ""
|
2470 |
|
2471 |
+
#: classes/Utils.php:4480
|
2472 |
msgid "Image Matching"
|
2473 |
msgstr ""
|
2474 |
|
2475 |
+
#: classes/Utils.php:4485
|
2476 |
msgid "Image Answering"
|
2477 |
msgstr ""
|
2478 |
|
2479 |
+
#: classes/Utils.php:4490
|
2480 |
msgid "Ordering"
|
2481 |
msgstr ""
|
2482 |
|
2483 |
+
#: classes/Utils.php:5374
|
2484 |
msgid "All Levels"
|
2485 |
msgstr ""
|
2486 |
|
2487 |
+
#: classes/Utils.php:5375, templates/course-filter/filters.php:4
|
2488 |
msgid "Beginner"
|
2489 |
msgstr ""
|
2490 |
|
2491 |
+
#: classes/Utils.php:5376, templates/course-filter/filters.php:5
|
2492 |
msgid "Intermediate"
|
2493 |
msgstr ""
|
2494 |
|
2495 |
+
#: classes/Utils.php:5377, templates/course-filter/filters.php:6
|
2496 |
msgid "Expert"
|
2497 |
msgstr ""
|
2498 |
|
2499 |
+
#: classes/Utils.php:5401
|
2500 |
msgid "Courses Taken"
|
2501 |
msgstr ""
|
2502 |
|
2503 |
+
#: classes/Utils.php:5408
|
2504 |
msgid "Enrolled Course"
|
2505 |
msgstr ""
|
2506 |
|
2507 |
+
#: classes/Utils.php:5412
|
2508 |
msgid "Reviews Written"
|
2509 |
msgstr ""
|
2510 |
|
2511 |
+
#: classes/Utils.php:5719
|
2512 |
msgid "Website URL"
|
2513 |
msgstr ""
|
2514 |
|
2515 |
+
#: classes/Utils.php:5724
|
2516 |
msgid "Github URL"
|
2517 |
msgstr ""
|
2518 |
|
2519 |
+
#: classes/Utils.php:5729
|
2520 |
msgid "Facebook URL"
|
2521 |
msgstr ""
|
2522 |
|
2523 |
+
#: classes/Utils.php:5734
|
2524 |
msgid "Twitter URL"
|
2525 |
msgstr ""
|
2526 |
|
2527 |
+
#: classes/Utils.php:5739
|
2528 |
msgid "Linkedin URL"
|
2529 |
msgstr ""
|
2530 |
|
2531 |
+
#: classes/Utils.php:7148
|
2532 |
msgid "Not Taken"
|
2533 |
msgstr ""
|
2534 |
|
2535 |
+
#: classes/Utils.php:7146
|
2536 |
msgid "In Progress"
|
2537 |
msgstr ""
|
2538 |
|
2539 |
+
#: classes/Utils.php:7142
|
2540 |
msgid "Completed"
|
2541 |
msgstr ""
|
2542 |
|
2543 |
+
#: classes/Utils.php:7335, templates/dashboard/my-profile.php:34, templates/dashboard/registration.php:49, templates/dashboard/registration.php:52, views/pages/add_new_instructor.php:29, views/pages/add_new_instructor.php:35, templates/dashboard/instructor/registration.php:51, templates/dashboard/instructor/registration.php:54, templates/dashboard/settings/profile.php:96, templates/dashboard/settings/profile.php:98
|
2544 |
msgid "First Name"
|
2545 |
msgstr ""
|
2546 |
|
2547 |
+
#: classes/Utils.php:7336, templates/dashboard/my-profile.php:44, templates/dashboard/registration.php:59, templates/dashboard/registration.php:62, views/pages/add_new_instructor.php:43, views/pages/add_new_instructor.php:49, templates/dashboard/instructor/registration.php:61, templates/dashboard/instructor/registration.php:64, templates/dashboard/settings/profile.php:105, templates/dashboard/settings/profile.php:107
|
2548 |
msgid "Last Name"
|
2549 |
msgstr ""
|
2550 |
|
2551 |
+
#: classes/Utils.php:7337, views/metabox/user-profile-fields.php:37
|
2552 |
msgid "Profile Photo"
|
2553 |
msgstr ""
|
2554 |
|
2555 |
+
#: classes/Utils.php:7338
|
2556 |
msgid "Withdraw Method"
|
2557 |
msgstr ""
|
2558 |
|
2559 |
+
#: classes/Withdraw.php:38
|
2560 |
msgid "Bank Transfer"
|
2561 |
msgstr ""
|
2562 |
|
2563 |
+
#: classes/Withdraw.php:40
|
2564 |
msgid "Get your payment directly into your bank account"
|
2565 |
msgstr ""
|
2566 |
|
2567 |
+
#: classes/Withdraw.php:45
|
2568 |
msgid "Instruction"
|
2569 |
msgstr ""
|
2570 |
|
2571 |
+
#: classes/Withdraw.php:46
|
2572 |
msgid "Write instruction for the instructor to fill bank information"
|
2573 |
msgstr ""
|
2574 |
|
2575 |
+
#: classes/Withdraw.php:53
|
2576 |
msgid "Account Name"
|
2577 |
msgstr ""
|
2578 |
|
2579 |
+
#: classes/Withdraw.php:58
|
2580 |
msgid "Account Number"
|
2581 |
msgstr ""
|
2582 |
|
2583 |
+
#: classes/Withdraw.php:63
|
2584 |
msgid "Bank Name"
|
2585 |
msgstr ""
|
2586 |
|
2587 |
+
#: classes/Withdraw.php:67
|
2588 |
msgid "IBAN"
|
2589 |
msgstr ""
|
2590 |
|
2591 |
+
#: classes/Withdraw.php:71
|
2592 |
msgid "BIC / SWIFT"
|
2593 |
msgstr ""
|
2594 |
|
2595 |
+
#: classes/Withdraw.php:78
|
2596 |
msgid "E-Check"
|
2597 |
msgstr ""
|
2598 |
|
2599 |
+
#: classes/Withdraw.php:83
|
2600 |
msgid "Your Physical Address"
|
2601 |
msgstr ""
|
2602 |
|
2603 |
+
#: classes/Withdraw.php:84
|
2604 |
msgid "We will send you an E-Check to this address directly."
|
2605 |
msgstr ""
|
2606 |
|
2607 |
+
#: classes/Withdraw.php:90
|
2608 |
msgid "PayPal"
|
2609 |
msgstr ""
|
2610 |
|
2611 |
+
#: classes/Withdraw.php:95
|
2612 |
msgid "PayPal E-Mail Address"
|
2613 |
msgstr ""
|
2614 |
|
2615 |
+
#: classes/Withdraw.php:96
|
2616 |
msgid "We will use this email address to send the money to your Paypal account"
|
2617 |
msgstr ""
|
2618 |
|
2619 |
+
#: classes/Withdraw.php:187
|
2620 |
msgid "Withdrawal account information saved successfully!"
|
2621 |
msgstr ""
|
2622 |
|
2623 |
+
#: classes/Withdraw.php:212
|
2624 |
msgid "Please save withdraw method "
|
2625 |
msgstr ""
|
2626 |
|
2627 |
+
#: classes/Withdraw.php:217
|
2628 |
+
msgid "Minimum withdrawal amount is %1$s %2$s %3$s "
|
2629 |
msgstr ""
|
2630 |
|
2631 |
+
#: classes/Withdraw.php:222
|
2632 |
msgid "Insufficient balance."
|
2633 |
msgstr ""
|
2634 |
|
2635 |
+
#: classes/Withdraw.php:255
|
2636 |
msgid "Withdrawal Request Sent!"
|
2637 |
msgstr ""
|
2638 |
|
2639 |
+
#: classes/Withdraw_Requests_List.php:60, classes/Withdraw_Requests_List.php:63
|
2640 |
msgid "Rejected"
|
2641 |
msgstr ""
|
2642 |
|
2643 |
+
#: classes/Withdraw_Requests_List.php:70
|
2644 |
msgid "Are you Sure? It can not be undone."
|
2645 |
msgstr ""
|
2646 |
|
2647 |
+
#: classes/Withdraw_Requests_List.php:70, templates/dashboard/announcements.php:157, templates/dashboard/my-courses.php:78, templates/dashboard/question-answer.php:41, views/pages/announcements.php:143, templates/dashboard/announcements/details.php:32, templates/dashboard/settings/profile.php:68, views/options/field-types/media.php:29
|
2648 |
msgid "Delete"
|
2649 |
msgstr ""
|
2650 |
|
2651 |
+
#: classes/Withdraw_Requests_List.php:103
|
2652 |
msgid "pending"
|
2653 |
msgstr ""
|
2654 |
|
2655 |
+
#: classes/Withdraw_Requests_List.php:104
|
2656 |
msgid "approved"
|
2657 |
msgstr ""
|
2658 |
|
2659 |
+
#: classes/Withdraw_Requests_List.php:105
|
2660 |
msgid "rejected"
|
2661 |
msgstr ""
|
2662 |
|
2663 |
+
#: classes/Withdraw_Requests_List.php:114
|
2664 |
msgid "Requested By"
|
2665 |
msgstr ""
|
2666 |
|
2667 |
+
#: classes/Withdraw_Requests_List.php:115, templates/dashboard/purchase_history.php:22, templates/dashboard/withdraw.php:138, templates/dashboard/withdraw.php:184
|
2668 |
msgid "Amount"
|
2669 |
msgstr ""
|
2670 |
|
2671 |
+
#: classes/Withdraw_Requests_List.php:116, templates/dashboard/withdraw.php:182
|
2672 |
msgid "Withdrawal Method"
|
2673 |
msgstr ""
|
2674 |
|
2675 |
+
#: classes/Withdraw_Requests_List.php:117
|
2676 |
msgid "Requested Time"
|
2677 |
msgstr ""
|
2678 |
|
2679 |
+
#: classes/WooCommerce.php:108
|
2680 |
msgid ""
|
2681 |
+
" Seems like you don’t have WooCommerce plugin installed on your site. In order to use this functionality, you need to have the\n"
|
2682 |
+
" WooCommerce plugin installed. Get back on this page after installing the plugin and enable the following feature to start selling\n"
|
2683 |
" courses with Tutor."
|
2684 |
msgstr ""
|
2685 |
|
2686 |
+
#: classes/WooCommerce.php:116
|
2687 |
msgid "This notice will disappear after activating <strong>WooCommerce</strong>"
|
2688 |
msgstr ""
|
2689 |
|
2690 |
+
#: classes/WooCommerce.php:166
|
2691 |
msgid "For Tutor"
|
2692 |
msgstr ""
|
2693 |
|
2694 |
+
#: classes/WooCommerce.php:167
|
2695 |
msgid "This checkmark ensure that you will sell a specif course via this product."
|
2696 |
msgstr ""
|
2697 |
|
2698 |
+
#: classes/WooCommerce.php:290, classes/WooCommerce.php:330
|
2699 |
msgid "WooCommerce"
|
2700 |
msgstr ""
|
2701 |
|
2702 |
+
#: classes/WooCommerce.php:295
|
2703 |
msgid "WooCommerce Settings"
|
2704 |
msgstr ""
|
2705 |
|
2706 |
+
#: classes/WooCommerce.php:307
|
2707 |
msgid "Enable add to cart feature for guest users"
|
2708 |
msgstr ""
|
2709 |
|
2710 |
+
#: classes/WooCommerce.php:308
|
2711 |
msgid "Enabling this will let an unregistered user purchase any course from the Course Details page. Head over to Documentation to know how to configure this setting."
|
2712 |
msgstr ""
|
2713 |
|
2714 |
+
#: classes/WooCommerce.php:610
|
2715 |
msgid "Since WooCommerce is disabled, your monetized courses have been set to free. Please make sure to enable Tutor LMS monetization if you decide to re-enable WooCommerce."
|
2716 |
msgstr ""
|
2717 |
|
2761 |
msgid "Count"
|
2762 |
msgstr ""
|
2763 |
|
2764 |
+
#: includes/tutor-general-functions.php:135
|
2765 |
msgid "Search Course Category. ex. Design, Development, Business"
|
2766 |
msgstr ""
|
2767 |
|
2768 |
+
#: includes/tutor-general-functions.php:136
|
2769 |
msgid "Select a category"
|
2770 |
msgstr ""
|
2771 |
|
2772 |
+
#: includes/tutor-general-functions.php:180
|
2773 |
msgid "Search Course Tags. ex. Design, Development, Business"
|
2774 |
msgstr ""
|
2775 |
|
2776 |
+
#: includes/tutor-general-functions.php:181
|
2777 |
msgid "Select a tag"
|
2778 |
msgstr ""
|
2779 |
|
2780 |
+
#: includes/tutor-template-functions.php:436
|
2781 |
msgid "Placeholder"
|
2782 |
msgstr ""
|
2783 |
|
2784 |
+
#: includes/tutor-template-functions.php:1507
|
2785 |
msgid "Share:"
|
2786 |
msgstr ""
|
2787 |
|
2877 |
msgid "Topic not found for given ID"
|
2878 |
msgstr ""
|
2879 |
|
2880 |
+
#: templates/dashboard.php:68, templates/dashboard/index.php:70
|
2881 |
msgid "%d Ratings"
|
2882 |
msgstr ""
|
2883 |
|
2884 |
+
#: templates/dashboard.php:90, templates/dashboard/index.php:93
|
2885 |
msgid "Become an instructor"
|
2886 |
msgstr ""
|
2887 |
|
2888 |
+
#: templates/dashboard.php:108
|
2889 |
msgid "Your Application is pending from"
|
2890 |
msgstr ""
|
2891 |
|
2892 |
+
#: templates/dashboard.php:100, templates/dashboard/index.php:86
|
2893 |
msgid "Add A New Course"
|
2894 |
msgstr ""
|
2895 |
|
2896 |
+
#: templates/dashboard.php:132
|
2897 |
msgid "Your application to become an instructor was rejected on"
|
2898 |
msgstr ""
|
2899 |
|
2900 |
+
#: templates/instructor-setting.php:9
|
2901 |
msgid "Instructor List Layout"
|
2902 |
msgstr ""
|
2903 |
|
2904 |
+
#: templates/instructor-setting.php:29
|
2905 |
msgid "Selected one will be used if layout is not defined as shortcode attribute."
|
2906 |
msgstr ""
|
2907 |
|
2909 |
msgid "Please Sign-In to view this section"
|
2910 |
msgstr ""
|
2911 |
|
2912 |
+
#: templates/permission-denied.php:43
|
2913 |
msgid "You don't have enough privilege to access this page"
|
2914 |
msgstr ""
|
2915 |
|
2916 |
+
#: templates/permission-denied.php:46
|
2917 |
msgid "Please make sure you are logged in to correct account if the content needs authorization."
|
2918 |
msgstr ""
|
2919 |
|
2920 |
+
#: templates/public-profile-setting.php:9
|
2921 |
msgid "Public Profile Layout"
|
2922 |
msgstr ""
|
2923 |
|
2924 |
+
#: templates/public-profile-setting.php:29
|
2925 |
msgid "Selected one will be used as public profile layout."
|
2926 |
msgstr ""
|
2927 |
|
2928 |
+
#: templates/single-preview-lesson.php:72, templates/single/lesson/lesson_sidebar.php:42
|
2929 |
msgid "Lesson List"
|
2930 |
msgstr ""
|
2931 |
|
2932 |
+
#: templates/single-preview-lesson.php:199, templates/single-quiz.php:35, templates/single/assignment/content.php:32, templates/single/lesson/content.php:35, templates/single/quiz/single_quiz_contents.php:14
|
2933 |
msgid "Go to Course Home"
|
2934 |
msgstr ""
|
2935 |
|
2936 |
+
#: templates/student-public-profile.php:115
|
2937 |
msgid "Courses Enrolled"
|
2938 |
msgstr ""
|
2939 |
|
2940 |
+
#: templates/student-public-profile.php:120
|
2941 |
msgid "Courses Completed"
|
2942 |
msgstr ""
|
2943 |
|
2944 |
+
#: templates/student-public-profile.php:120
|
2945 |
msgid "Course Completed"
|
2946 |
msgstr ""
|
2947 |
|
2948 |
+
#: templates/student-public-profile.php:152
|
2949 |
msgid "Biography"
|
2950 |
msgstr ""
|
2951 |
|
2952 |
+
#: templates/course-filter/filters.php:9, templates/dashboard/create-course.php:201, templates/loop/course-continue.php:19, templates/loop/course-in-cart.php:20, templates/loop/course-price-edd.php:19, templates/loop/course-price-woocommerce.php:20, templates/loop/course-price-woocommerce.php:35, templates/loop/course-price.php:19, views/metabox/course-add-edd-product-metabox.php:61, views/metabox/course-add-product-metabox.php:71, templates/single/course/wc-price-html.php:23
|
2953 |
msgid "Free"
|
2954 |
msgstr ""
|
2955 |
|
2956 |
+
#: templates/course-filter/filters.php:10, views/metabox/course-add-edd-product-metabox.php:57, views/metabox/course-add-product-metabox.php:67
|
2957 |
msgid "Paid"
|
2958 |
msgstr ""
|
2959 |
|
2960 |
+
#: templates/course-filter/filters.php:22
|
2961 |
+
msgid "Search..."
|
2962 |
+
msgstr ""
|
2963 |
+
|
2964 |
#: templates/course-filter/filters.php:54
|
2965 |
msgid "Level"
|
2966 |
msgstr ""
|
2967 |
|
2968 |
+
#: templates/dashboard/announcements.php:60
|
2969 |
msgid "Announcement"
|
2970 |
msgstr ""
|
2971 |
|
2972 |
+
#: templates/dashboard/announcements.php:67
|
2973 |
msgid "Create Announcement"
|
2974 |
msgstr ""
|
2975 |
|
2976 |
+
#: templates/dashboard/announcements.php:70
|
2977 |
msgid "Notify all students of your course"
|
2978 |
msgstr ""
|
2979 |
|
2980 |
+
#: templates/dashboard/announcements.php:76
|
2981 |
msgid "Add New Announcement"
|
2982 |
msgstr ""
|
2983 |
|
2984 |
+
#: templates/dashboard/announcements.php:107, templates/dashboard/assignments.php:54
|
2985 |
msgid "ASC"
|
2986 |
msgstr ""
|
2987 |
|
2988 |
+
#: templates/dashboard/announcements.php:108, templates/dashboard/assignments.php:55
|
2989 |
msgid "DESC"
|
2990 |
msgstr ""
|
2991 |
|
2992 |
+
#: templates/dashboard/announcements.php:168, views/pages/announcements.php:153
|
2993 |
msgid "Announcements not found"
|
2994 |
msgstr ""
|
2995 |
|
2996 |
+
#: templates/dashboard/announcements.php:145, templates/dashboard/assignments.php:105, templates/dashboard/quiz-attempts.php:101, templates/dashboard/assignments/submitted.php:91, templates/single/quiz/previous-attempts.php:79
|
2997 |
msgid "Details"
|
2998 |
msgstr ""
|
2999 |
|
3000 |
+
#: templates/dashboard/announcements.php:153, templates/dashboard/my-courses.php:75, views/pages/announcements.php:140, templates/dashboard/announcements/details.php:33
|
3001 |
msgid "Edit"
|
3002 |
msgstr ""
|
3003 |
|
3005 |
msgid "Create Date"
|
3006 |
msgstr ""
|
3007 |
|
3008 |
+
#: templates/dashboard/assignments.php:131
|
3009 |
msgid "No assignment available"
|
3010 |
msgstr ""
|
3011 |
|
3012 |
+
#: templates/dashboard/assignments.php:74, templates/dashboard/dashboard.php:90
|
3013 |
msgid "Course Name"
|
3014 |
msgstr ""
|
3015 |
|
3016 |
+
#: templates/dashboard/assignments.php:75, templates/dashboard/assignments/submitted.php:46, templates/dashboard/assignments/submitted.php:73
|
3017 |
msgid "Total Points"
|
3018 |
msgstr ""
|
3019 |
|
3020 |
+
#: templates/dashboard/assignments.php:76
|
3021 |
msgid "Total Submits"
|
3022 |
msgstr ""
|
3023 |
|
3024 |
+
#: templates/dashboard/create-course.php:26
|
|
|
|
|
|
|
|
|
3025 |
msgid "You don't have the right to edit this course"
|
3026 |
msgstr ""
|
3027 |
|
3028 |
+
#: templates/dashboard/create-course.php:27
|
3029 |
msgid "Please make sure you are logged in to correct account"
|
3030 |
msgstr ""
|
3031 |
|
3032 |
+
#: templates/dashboard/create-course.php:55, views/modal/edit_quiz.php:264, views/modal/edit_quiz.php:351
|
3033 |
msgid "Save"
|
3034 |
msgstr ""
|
3035 |
|
3036 |
+
#: templates/dashboard/create-course.php:61
|
3037 |
msgid "Preview"
|
3038 |
msgstr ""
|
3039 |
|
3040 |
+
#: templates/dashboard/create-course.php:69, templates/dashboard/create-course.php:258
|
3041 |
msgid "Submit for Review"
|
3042 |
msgstr ""
|
3043 |
|
3044 |
+
#: templates/dashboard/create-course.php:65, templates/dashboard/create-course.php:256
|
3045 |
msgid "Publish Course"
|
3046 |
msgstr ""
|
3047 |
|
3048 |
+
#: templates/dashboard/create-course.php:73
|
3049 |
msgid "Exit"
|
3050 |
msgstr ""
|
3051 |
|
3052 |
+
#: templates/dashboard/create-course.php:112, templates/dashboard/my-quiz-attempts.php:32, templates/dashboard/quiz-attempts.php:30, templates/dashboard/earning/statements.php:130, templates/single/quiz/previous-attempts.php:16
|
3053 |
msgid "Course Info"
|
3054 |
msgstr ""
|
3055 |
|
3056 |
+
#: templates/dashboard/create-course.php:119
|
3057 |
msgid "Course Title"
|
3058 |
msgstr ""
|
3059 |
|
3060 |
+
#: templates/dashboard/create-course.php:121
|
3061 |
msgid "ex. Learn photoshop CS6 from scratch"
|
3062 |
msgstr ""
|
3063 |
|
3064 |
+
#: templates/dashboard/create-course.php:128, views/modal/question_form.php:107, templates/single/assignment/content.php:145, templates/single/course/course-content.php:26
|
3065 |
msgid "Description"
|
3066 |
msgstr ""
|
3067 |
|
3068 |
+
#: templates/dashboard/create-course.php:147
|
3069 |
msgid "Choose a category"
|
3070 |
msgstr ""
|
3071 |
|
3072 |
+
#: templates/dashboard/create-course.php:162
|
3073 |
msgid "Choose a tag"
|
3074 |
msgstr ""
|
3075 |
|
3076 |
+
#: templates/dashboard/create-course.php:183
|
3077 |
msgid "Course Price"
|
3078 |
msgstr ""
|
3079 |
|
3080 |
+
#: templates/dashboard/create-course.php:194
|
3081 |
msgid "Set course price"
|
3082 |
msgstr ""
|
3083 |
|
3084 |
+
#: templates/dashboard/create-course.php:212
|
3085 |
msgid "Course Thumbnail"
|
3086 |
msgstr ""
|
3087 |
|
3088 |
+
#: templates/dashboard/create-course.php:236
|
3089 |
msgid "Important Guideline: %1$s 700x430 pixels %2$s %3$s File Support: %1$s jpg, .jpeg,. gif, or .png %2$s no text on the image."
|
3090 |
msgstr ""
|
3091 |
|
3092 |
+
#: templates/dashboard/create-course.php:238, views/metabox/video-metabox.php:125, views/modal/question_answer_edit_form.php:217, views/modal/question_answer_edit_form.php:180, views/modal/question_answer_edit_form.php:127, views/modal/question_answer_edit_form.php:34, views/modal/question_answer_form.php:235, views/modal/question_answer_form.php:205, views/modal/question_answer_form.php:160, views/modal/question_answer_form.php:49
|
3093 |
msgid "Upload Image"
|
3094 |
msgstr ""
|
3095 |
|
3096 |
+
#: templates/dashboard/create-course.php:254
|
3097 |
msgid "Save course as draft"
|
3098 |
msgstr ""
|
3099 |
|
3100 |
+
#: templates/dashboard/create-course.php:268
|
3101 |
msgid "Course Upload Tips"
|
3102 |
msgstr ""
|
3103 |
|
3104 |
+
#: templates/dashboard/create-course.php:270
|
3105 |
msgid "Set the Course Price option or make it free."
|
3106 |
msgstr ""
|
3107 |
|
3108 |
+
#: templates/dashboard/create-course.php:271
|
3109 |
msgid "Standard size for the course thumbnail is 700x430."
|
3110 |
msgstr ""
|
3111 |
|
3112 |
+
#: templates/dashboard/create-course.php:272
|
3113 |
msgid "Video section controls the course overview video."
|
3114 |
msgstr ""
|
3115 |
|
3116 |
+
#: templates/dashboard/create-course.php:273
|
3117 |
msgid "Course Builder is where you create & organize a course."
|
3118 |
msgstr ""
|
3119 |
|
3120 |
+
#: templates/dashboard/create-course.php:274
|
3121 |
msgid "Add Topics in the Course Builder section to create lessons, quizzes, and assignments."
|
3122 |
msgstr ""
|
3123 |
|
3124 |
+
#: templates/dashboard/create-course.php:275
|
3125 |
msgid "Prerequisites refers to the fundamental courses to complete before taking this particular course."
|
3126 |
msgstr ""
|
3127 |
|
3128 |
+
#: templates/dashboard/create-course.php:276
|
3129 |
msgid "Information from the Additional Data section shows up on the course single page."
|
3130 |
msgstr ""
|
3131 |
|
3149 |
msgid "Total Students"
|
3150 |
msgstr ""
|
3151 |
|
3152 |
+
#: templates/dashboard/dashboard.php:66
|
3153 |
msgid "Total Courses"
|
3154 |
msgstr ""
|
3155 |
|
3156 |
+
#: templates/dashboard/dashboard.php:72
|
3157 |
msgid "Total Earnings"
|
3158 |
msgstr ""
|
3159 |
|
3160 |
+
#: templates/dashboard/dashboard.php:86
|
3161 |
msgid "Most Popular Courses"
|
3162 |
msgstr ""
|
3163 |
|
3164 |
+
#: templates/dashboard/dashboard.php:91
|
3165 |
msgid "Enrolled"
|
3166 |
msgstr ""
|
3167 |
|
3177 |
msgid "Reports"
|
3178 |
msgstr ""
|
3179 |
|
3180 |
+
#: templates/dashboard/earning.php:53, templates/dashboard/earning/report.php:37, templates/dashboard/earning/statements.php:33, templates/dashboard/earning/statements.php:114
|
3181 |
msgid "Statements"
|
3182 |
msgstr ""
|
3183 |
|
3193 |
msgid "My Earnings"
|
3194 |
msgstr ""
|
3195 |
|
3196 |
+
#: templates/dashboard/earning.php:72, templates/dashboard/earning/report-date_range.php:41, templates/dashboard/earning/report-last_month.php:40, templates/dashboard/earning/report-last_week.php:44, templates/dashboard/earning/report-last_year.php:40, templates/dashboard/earning/report-this_month.php:44, templates/dashboard/earning/report-this_week.php:42, templates/dashboard/earning/report-this_year.php:38
|
3197 |
msgid "Based on course price"
|
3198 |
msgstr ""
|
3199 |
|
3200 |
+
#: templates/dashboard/earning.php:74, templates/dashboard/earning/report-date_range.php:43, templates/dashboard/earning/report-last_month.php:42, templates/dashboard/earning/report-last_week.php:46, templates/dashboard/earning/report-last_year.php:42, templates/dashboard/earning/report-this_month.php:46, templates/dashboard/earning/report-this_week.php:44, templates/dashboard/earning/report-this_year.php:40
|
3201 |
msgid "All time sales"
|
3202 |
msgstr ""
|
3203 |
|
3209 |
msgid "All time withdrawals"
|
3210 |
msgstr ""
|
3211 |
|
3212 |
+
#: templates/dashboard/earning.php:86, templates/dashboard/earning/report-date_range.php:49, templates/dashboard/earning/report-last_month.php:48, templates/dashboard/earning/report-last_week.php:52, templates/dashboard/earning/report-last_year.php:48, templates/dashboard/earning/report-this_month.php:54, templates/dashboard/earning/report-this_week.php:50, templates/dashboard/earning/report-this_year.php:46
|
3213 |
msgid "Deducted Commissions"
|
3214 |
msgstr ""
|
3215 |
|
3225 |
msgid "All Courses"
|
3226 |
msgstr ""
|
3227 |
|
3228 |
+
#: templates/dashboard/enrolled-courses.php:82
|
3229 |
msgid "You haven't purchased any course"
|
3230 |
msgstr ""
|
3231 |
|
3232 |
+
#: templates/dashboard/enrolled-courses.php:60, templates/dashboard/enrolled-courses/active-courses.php:53, templates/dashboard/enrolled-courses/completed-courses.php:53
|
3233 |
msgid "Total Lessons:"
|
3234 |
msgstr ""
|
3235 |
|
3236 |
+
#: templates/dashboard/enrolled-courses.php:66, templates/dashboard/enrolled-courses/active-courses.php:59, templates/dashboard/enrolled-courses/completed-courses.php:59
|
3237 |
msgid "Completed Lessons:"
|
3238 |
msgstr ""
|
3239 |
|
3241 |
msgid "You are already logged in"
|
3242 |
msgstr ""
|
3243 |
|
3244 |
+
#: templates/dashboard/my-courses.php:91
|
3245 |
msgid "Not Found"
|
3246 |
msgstr ""
|
3247 |
|
3248 |
+
#: templates/dashboard/my-courses.php:92, templates/dashboard/reviews.php:86, templates/dashboard/assignments/review.php:19, templates/dashboard/reviews/given-reviews.php:38
|
3249 |
msgid "Sorry, but you are looking for something that isn't here."
|
3250 |
msgstr ""
|
3251 |
|
3265 |
msgid "View"
|
3266 |
msgstr ""
|
3267 |
|
3268 |
+
#: templates/dashboard/my-courses.php:104
|
3269 |
msgid "Delete This Course?"
|
3270 |
msgstr ""
|
3271 |
|
3272 |
+
#: templates/dashboard/my-courses.php:105
|
3273 |
msgid "You are going to delete this course, it can't be undone"
|
3274 |
msgstr ""
|
3275 |
|
3276 |
+
#: templates/dashboard/my-courses.php:110, templates/dashboard/question-answer.php:75, templates/dashboard/withdraw.php:154, views/modal/add_quiz.php:58, views/modal/add_quiz.php:80, views/modal/add_quiz.php:103, views/modal/edit_quiz.php:73, views/modal/edit_quiz.php:140, views/modal/question_form.php:213, views/modal/review.php:19, views/pages/announcements.php:249, views/pages/announcements.php:331, templates/dashboard/announcements/create.php:53, templates/dashboard/announcements/details.php:29, templates/dashboard/announcements/update.php:52, templates/single/lesson/sidebar_question_and_answer.php:116, templates/single/course/enrolled/question_and_answer.php:52, templates/single/course/enrolled/question_and_answer.php:141
|
3277 |
msgid "Cancel"
|
3278 |
msgstr ""
|
3279 |
|
3280 |
+
#: templates/dashboard/my-courses.php:111
|
3281 |
msgid "Yes, Delete Course"
|
3282 |
msgstr ""
|
3283 |
|
3285 |
msgid "Registration Date"
|
3286 |
msgstr ""
|
3287 |
|
3288 |
+
#: templates/dashboard/my-profile.php:54
|
3289 |
msgid "Username"
|
3290 |
msgstr ""
|
3291 |
|
3292 |
+
#: templates/dashboard/my-profile.php:62
|
3293 |
msgid "Email"
|
3294 |
msgstr ""
|
3295 |
|
3296 |
+
#: templates/dashboard/my-profile.php:70, views/pages/add_new_instructor.php:82, views/pages/add_new_instructor.php:88, templates/dashboard/settings/profile.php:125, templates/dashboard/settings/profile.php:127
|
3297 |
msgid "Phone Number"
|
3298 |
msgstr ""
|
3299 |
|
3300 |
+
#: templates/dashboard/my-profile.php:79, views/pages/add_new_instructor.php:121, templates/dashboard/settings/profile.php:136
|
3301 |
msgid "Bio"
|
3302 |
msgstr ""
|
3303 |
|
3304 |
+
#: templates/dashboard/my-quiz-attempts.php:103
|
3305 |
msgid "You have not attempted any quiz yet"
|
3306 |
msgstr ""
|
3307 |
|
3308 |
+
#: templates/dashboard/my-quiz-attempts.php:33, templates/dashboard/quiz-attempts.php:32, templates/single/quiz/previous-attempts.php:17
|
3309 |
msgid "Correct Answer"
|
3310 |
msgstr ""
|
3311 |
|
3312 |
+
#: templates/dashboard/my-quiz-attempts.php:34, templates/dashboard/quiz-attempts.php:33, templates/single/quiz/previous-attempts.php:18
|
3313 |
msgid "Incorrect Answer"
|
3314 |
msgstr ""
|
3315 |
|
3316 |
+
#: templates/dashboard/my-quiz-attempts.php:35, templates/dashboard/my-quiz-attempts/attempts-details.php:125, templates/dashboard/quiz-attempts/quiz-reviews.php:111, templates/single/quiz/previous-attempts.php:19
|
3317 |
msgid "Earned Marks"
|
3318 |
msgstr ""
|
3319 |
|
3320 |
+
#: templates/dashboard/my-quiz-attempts.php:36, templates/dashboard/quiz-attempts.php:35, views/pages/view_attempt.php:87, templates/dashboard/assignments/submitted.php:74, templates/single/quiz/previous-attempts.php:20
|
3321 |
msgid "Result"
|
3322 |
msgstr ""
|
3323 |
|
3324 |
+
#: templates/dashboard/my-quiz-attempts.php:53, templates/dashboard/quiz-attempts.php:53, templates/single/quiz/previous-attempts.php:41
|
3325 |
msgid "Question: "
|
3326 |
msgstr ""
|
3327 |
|
3328 |
+
#: templates/dashboard/my-quiz-attempts.php:54, templates/dashboard/quiz-attempts.php:54, templates/single/quiz/previous-attempts.php:42
|
3329 |
msgid "Total Marks: "
|
3330 |
msgstr ""
|
3331 |
|
3333 |
msgid "No purchase history available"
|
3334 |
msgstr ""
|
3335 |
|
3336 |
+
#: templates/dashboard/question-answer.php:86
|
|
|
|
|
|
|
|
|
3337 |
msgid "No question is available"
|
3338 |
msgstr ""
|
3339 |
|
3340 |
+
#: templates/dashboard/question-answer.php:69
|
3341 |
msgid "Delete This Question?"
|
3342 |
msgstr ""
|
3343 |
|
3344 |
+
#: templates/dashboard/question-answer.php:70
|
3345 |
msgid "You are going to delete this question, it can't be undone"
|
3346 |
msgstr ""
|
3347 |
|
3348 |
+
#: templates/dashboard/question-answer.php:76
|
3349 |
msgid "Yes, Delete Question"
|
3350 |
msgstr ""
|
3351 |
|
3352 |
+
#: templates/dashboard/quiz-attempts.php:121
|
3353 |
msgid "No quiz attempt yet."
|
3354 |
msgstr ""
|
3355 |
|
3357 |
msgid "Earned Mark"
|
3358 |
msgstr ""
|
3359 |
|
3360 |
+
#: templates/dashboard/registration.php:71, templates/dashboard/registration.php:74, views/pages/add_new_instructor.php:56, views/pages/add_new_instructor.php:62, templates/dashboard/instructor/registration.php:76, templates/dashboard/instructor/registration.php:79, templates/dashboard/settings/profile.php:116
|
3361 |
msgid "User Name"
|
3362 |
msgstr ""
|
3363 |
|
3364 |
+
#: templates/dashboard/registration.php:92, templates/dashboard/registration.php:95, templates/global/login.php:48, templates/template-part/form-retrieve-password.php:25, views/pages/add_new_instructor.php:95, views/pages/add_new_instructor.php:101, templates/dashboard/instructor/registration.php:99, templates/dashboard/instructor/registration.php:102
|
3365 |
msgid "Password"
|
3366 |
msgstr ""
|
3367 |
|
3368 |
+
#: templates/dashboard/registration.php:102, views/pages/add_new_instructor.php:108, templates/dashboard/instructor/registration.php:109
|
3369 |
msgid "Password confirmation"
|
3370 |
msgstr ""
|
3371 |
|
3372 |
+
#: templates/dashboard/registration.php:105, views/pages/add_new_instructor.php:114, templates/dashboard/instructor/registration.php:112
|
3373 |
msgid "Password Confirmation"
|
3374 |
msgstr ""
|
3375 |
|
3376 |
+
#: templates/dashboard/registration.php:128
|
3377 |
msgid "Register"
|
3378 |
msgstr ""
|
3379 |
|
3398 |
msgstr ""
|
3399 |
|
3400 |
#: templates/dashboard/reviews.php:51
|
3401 |
+
msgid "Showing results %1$d to %2$d out of %3$d"
|
3402 |
+
msgstr ""
|
3403 |
+
|
3404 |
+
#: templates/dashboard/reviews.php:64, templates/dashboard/reviews/given-reviews.php:54
|
3405 |
+
msgid "Course: "
|
3406 |
msgstr ""
|
3407 |
|
3408 |
+
#: templates/dashboard/reviews.php:72, templates/profile/reviews_wrote.php:50, views/pages/answer.php:55, views/pages/answer.php:95, templates/dashboard/question-answer/answers.php:25, templates/dashboard/question-answer/answers.php:52, templates/dashboard/reviews/given-reviews.php:68, templates/single/course/reviews.php:94, templates/single/lesson/sidebar_question_and_answer.php:54, templates/single/lesson/sidebar_question_and_answer.php:83, templates/single/course/enrolled/question_and_answer.php:77, templates/single/course/enrolled/question_and_answer.php:108
|
3409 |
msgid "%s ago"
|
3410 |
msgstr ""
|
3411 |
|
3421 |
msgid "Withdrawal request is pending for approval, please hold tight."
|
3422 |
msgstr ""
|
3423 |
|
3424 |
+
#: templates/dashboard/withdraw.php:48, templates/dashboard/withdraw.php:113
|
3425 |
msgid "Current Balance"
|
3426 |
msgstr ""
|
3427 |
|
3428 |
+
#: templates/dashboard/withdraw.php:54
|
3429 |
+
msgid "You currently have %1$s %2$s %3$s and this is insufficient balance to withdraw"
|
3430 |
msgstr ""
|
3431 |
|
3432 |
+
#: templates/dashboard/withdraw.php:52
|
3433 |
+
msgid "You currently have %1$s %2$s %3$s ready to withdraw"
|
3434 |
msgstr ""
|
3435 |
|
3436 |
+
#: templates/dashboard/withdraw.php:64, templates/dashboard/withdraw.php:107
|
3437 |
msgid "Withdrawal Request"
|
3438 |
msgstr ""
|
3439 |
|
3440 |
+
#: templates/dashboard/withdraw.php:76
|
3441 |
msgid "The preferred payment method is selected as %s. "
|
3442 |
msgstr ""
|
3443 |
|
3444 |
+
#: templates/dashboard/withdraw.php:77
|
3445 |
+
msgid "You can change your %1$s withdrawal preference %2$s"
|
3446 |
msgstr ""
|
3447 |
|
3448 |
+
#: templates/dashboard/withdraw.php:95
|
3449 |
msgid "Your withdrawal request has been successfully accepted"
|
3450 |
msgstr ""
|
3451 |
|
3452 |
+
#: templates/dashboard/withdraw.php:96
|
3453 |
msgid "Please check your transaction notification on your connected withdrawal method"
|
3454 |
msgstr ""
|
3455 |
|
3456 |
+
#: templates/dashboard/withdraw.php:108
|
3457 |
msgid "Please enter withdrawal amount and click the submit request button"
|
3458 |
msgstr ""
|
3459 |
|
3460 |
+
#: templates/dashboard/withdraw.php:117
|
3461 |
msgid "Selected Payment Method"
|
3462 |
msgstr ""
|
3463 |
|
3464 |
+
#: templates/dashboard/withdraw.php:148
|
3465 |
msgid "Minimum withdraw amount is"
|
3466 |
msgstr ""
|
3467 |
|
3468 |
+
#: templates/dashboard/withdraw.php:155
|
3469 |
msgid "Submit Request"
|
3470 |
msgstr ""
|
3471 |
|
3472 |
+
#: templates/dashboard/withdraw.php:173
|
3473 |
msgid "Withdrawal History"
|
3474 |
msgstr ""
|
3475 |
|
3476 |
+
#: templates/dashboard/withdraw.php:263
|
3477 |
msgid "No withdrawal yet"
|
3478 |
msgstr ""
|
3479 |
|
3480 |
+
#: templates/dashboard/withdraw.php:183
|
3481 |
msgid "Requested On"
|
3482 |
msgstr ""
|
3483 |
|
3517 |
msgid "Release Date (newest first)"
|
3518 |
msgstr ""
|
3519 |
|
3520 |
+
#: templates/global/course-archive-filter-bar.php:26
|
3521 |
msgid "Release Date (oldest first)"
|
3522 |
msgstr ""
|
3523 |
|
3524 |
+
#: templates/global/course-archive-filter-bar.php:27
|
3525 |
msgid "Course Title (a-z)"
|
3526 |
msgstr ""
|
3527 |
|
3528 |
+
#: templates/global/course-archive-filter-bar.php:28
|
3529 |
msgid "Course Title (z-a)"
|
3530 |
msgstr ""
|
3531 |
|
3532 |
+
#: templates/global/login.php:47
|
3533 |
msgid "Username or Email Address"
|
3534 |
msgstr ""
|
3535 |
|
3536 |
+
#: templates/global/login.php:49
|
3537 |
msgid "Remember Me"
|
3538 |
msgstr ""
|
3539 |
|
3540 |
+
#: templates/global/login.php:50
|
3541 |
msgid "Log In"
|
3542 |
msgstr ""
|
3543 |
|
3544 |
+
#: templates/global/login.php:51
|
3545 |
msgid "Create a new account"
|
3546 |
msgstr ""
|
3547 |
|
3548 |
+
#: templates/global/login.php:61
|
3549 |
msgid "Forgot Password?"
|
3550 |
msgstr ""
|
3551 |
|
3552 |
+
#: templates/loop/course-continue.php:18, templates/single/course/course-enrolled-box.php:54
|
3553 |
msgid "Continue Course"
|
3554 |
msgstr ""
|
3555 |
|
3557 |
msgid "View Cart"
|
3558 |
msgstr ""
|
3559 |
|
3560 |
+
#: templates/loop/course-price-edd.php:18, templates/loop/course-price-woocommerce.php:19, templates/loop/course-price.php:18
|
3561 |
msgid "Get Enrolled"
|
3562 |
msgstr ""
|
3563 |
|
3565 |
msgid "Start Learning "
|
3566 |
msgstr ""
|
3567 |
|
3568 |
+
#: templates/loop/meta.php:40, templates/single/course/lead-info.php:63, templates/single/course/enrolled/lead-info.php:63
|
3569 |
msgid "by"
|
3570 |
msgstr ""
|
3571 |
|
3572 |
+
#: templates/loop/meta.php:49
|
3573 |
msgid "In"
|
3574 |
msgstr ""
|
3575 |
|
3581 |
msgid "No course yet."
|
3582 |
msgstr ""
|
3583 |
|
3584 |
+
#: templates/profile/reviews_wrote.php:25
|
3585 |
msgid "No review yet."
|
3586 |
msgstr ""
|
3587 |
|
3588 |
+
#: templates/profile/reviews_wrote.php:58
|
3589 |
msgid "On"
|
3590 |
msgstr ""
|
3591 |
|
3592 |
+
#: templates/shortcode/instructor-filter.php:30, templates/shortcode/instructor-filter.php:60
|
3593 |
msgid "Clear All"
|
3594 |
msgstr ""
|
3595 |
|
3596 |
+
#: templates/shortcode/instructor-filter.php:43, templates/shortcode/instructor-filter.php:50
|
3597 |
msgid "Search any instructor..."
|
3598 |
msgstr ""
|
3599 |
|
3600 |
+
#: templates/shortcode/instructor-filter.php:68
|
3601 |
msgid "Apply Filter"
|
3602 |
msgstr ""
|
3603 |
|
3633 |
msgid "When selling the course"
|
3634 |
msgstr ""
|
3635 |
|
3636 |
+
#: views/metabox/course-add-edd-product-metabox.php:40
|
3637 |
msgid "Sell your product, process by EDD"
|
3638 |
msgstr ""
|
3639 |
|
3640 |
+
#: views/metabox/course-add-edd-product-metabox.php:50, views/metabox/course-add-product-metabox.php:60
|
3641 |
msgid "Course Type"
|
3642 |
msgstr ""
|
3643 |
|
3644 |
+
#: views/metabox/course-add-product-metabox.php:50
|
3645 |
msgid "Edit attached Product"
|
3646 |
msgstr ""
|
3647 |
|
3648 |
+
#: views/metabox/course-add-product-metabox.php:51
|
3649 |
msgid "Select a product if you want to sell your course. The sale will be handled by your preferred monetization option. (WooCommerce, EDD, Paid Memberships Pro)"
|
3650 |
msgstr ""
|
3651 |
|
3653 |
msgid "Total Course Duration"
|
3654 |
msgstr ""
|
3655 |
|
3656 |
+
#: views/metabox/course-additional-data.php:26, views/metabox/video-metabox.php:169
|
3657 |
msgid "HH"
|
3658 |
msgstr ""
|
3659 |
|
3660 |
+
#: views/metabox/course-additional-data.php:30, views/metabox/video-metabox.php:174
|
3661 |
msgid "MM"
|
3662 |
msgstr ""
|
3663 |
|
3664 |
+
#: views/metabox/course-additional-data.php:35, views/metabox/video-metabox.php:179
|
3665 |
msgid "SS"
|
3666 |
msgstr ""
|
3667 |
|
3669 |
msgid "Benefits of the course"
|
3670 |
msgstr ""
|
3671 |
|
3672 |
+
#: views/metabox/course-additional-data.php:56
|
3673 |
msgid ""
|
3674 |
"List the knowledge and skills that students will learn after completing this course. (One per line)\n"
|
3675 |
""
|
3676 |
msgstr ""
|
3677 |
|
3678 |
+
#: views/metabox/course-additional-data.php:69
|
3679 |
msgid "Requirements/Instructions"
|
3680 |
msgstr ""
|
3681 |
|
3682 |
+
#: views/metabox/course-additional-data.php:76
|
3683 |
msgid "Additional requirements or special instructions for the students (One per line)"
|
3684 |
msgstr ""
|
3685 |
|
3686 |
+
#: views/metabox/course-additional-data.php:84
|
3687 |
msgid "Targeted Audience"
|
3688 |
msgstr ""
|
3689 |
|
3690 |
+
#: views/metabox/course-additional-data.php:91
|
3691 |
msgid "Specify the target audience that will benefit the most from the course. (One line per target audience.)"
|
3692 |
msgstr ""
|
3693 |
|
3694 |
+
#: views/metabox/course-additional-data.php:100
|
3695 |
msgid "Materials Included"
|
3696 |
msgstr ""
|
3697 |
|
3698 |
+
#: views/metabox/course-additional-data.php:107
|
3699 |
msgid "A list of assets you will be providing for the students in this course (One per line)"
|
3700 |
msgstr ""
|
3701 |
|
3702 |
+
#: views/metabox/course-contents.php:28
|
3703 |
msgid "Add a topic to build your course"
|
3704 |
msgstr ""
|
3705 |
|
3706 |
+
#: views/metabox/course-contents.php:45
|
3707 |
msgid "Delete Topic"
|
3708 |
msgstr ""
|
3709 |
|
3710 |
+
#: views/metabox/course-contents.php:58, views/metabox/course-topics.php:36
|
3711 |
msgid "Topic Name"
|
3712 |
msgstr ""
|
3713 |
|
3714 |
+
#: views/metabox/course-contents.php:64
|
3715 |
msgid "Topic title will be publicly show where required, you can call it as a section also in course"
|
3716 |
msgstr ""
|
3717 |
|
3718 |
+
#: views/metabox/course-contents.php:71, views/metabox/course-topics.php:48
|
3719 |
msgid "Topic Summary"
|
3720 |
msgstr ""
|
3721 |
|
3722 |
+
#: views/metabox/course-contents.php:76, views/metabox/course-topics.php:53
|
3723 |
msgid "The idea of a summary is a short text to prepare students for the activities within the topic or week. The text is shown on the course page under the topic name."
|
3724 |
msgstr ""
|
3725 |
|
3726 |
+
#: views/metabox/course-contents.php:80
|
3727 |
msgid "Update Topic"
|
3728 |
msgstr ""
|
3729 |
|
3730 |
+
#: views/metabox/course-contents.php:170, views/metabox/course-topics.php:82
|
3731 |
msgid "Lesson"
|
3732 |
msgstr ""
|
3733 |
|
3734 |
+
#: views/metabox/course-topics.php:16
|
3735 |
msgid "Expand all"
|
3736 |
msgstr ""
|
3737 |
|
3738 |
+
#: views/metabox/course-topics.php:17
|
3739 |
msgid "Collapse all"
|
3740 |
msgstr ""
|
3741 |
|
3742 |
+
#: views/metabox/course-topics.php:28
|
3743 |
msgid "Add new topic"
|
3744 |
msgstr ""
|
3745 |
|
3746 |
+
#: views/metabox/course-topics.php:32, views/metabox/course-topics.php:59
|
3747 |
msgid "Add Topic"
|
3748 |
msgstr ""
|
3749 |
|
3750 |
+
#: views/metabox/course-topics.php:41
|
3751 |
msgid "Topic titles are displayed publicly wherever required. Each topic may contain one or more lessons, quiz and assignments."
|
3752 |
msgstr ""
|
3753 |
|
3754 |
+
#: views/metabox/course-topics.php:111
|
3755 |
msgid "Zoom Meeting"
|
3756 |
msgstr ""
|
3757 |
|
3763 |
msgid "Add More Instructors"
|
3764 |
msgstr ""
|
3765 |
|
3766 |
+
#: views/metabox/instructors-metabox.php:50
|
3767 |
msgid "Add instructors"
|
3768 |
msgstr ""
|
3769 |
|
3770 |
+
#: views/metabox/instructors-metabox.php:59
|
3771 |
msgid "Search instructors..."
|
3772 |
msgstr ""
|
3773 |
|
3774 |
+
#: views/metabox/instructors-metabox.php:64
|
3775 |
msgid "Add Instructors"
|
3776 |
msgstr ""
|
3777 |
|
3783 |
msgid "Select a course"
|
3784 |
msgstr ""
|
3785 |
|
3786 |
+
#: views/metabox/lesson-metabox.php:24
|
3787 |
msgid "Choose the course for this lesson"
|
3788 |
msgstr ""
|
3789 |
|
3807 |
msgid "Upload"
|
3808 |
msgstr ""
|
3809 |
|
3810 |
+
#: views/metabox/video-metabox.php:57
|
3811 |
msgid "Video Source"
|
3812 |
msgstr ""
|
3813 |
|
3814 |
+
#: views/metabox/video-metabox.php:55
|
3815 |
msgid "Course Intro Video"
|
3816 |
msgstr ""
|
3817 |
|
3818 |
+
#: views/metabox/video-metabox.php:66
|
3819 |
msgid "Select Video Source"
|
3820 |
msgstr ""
|
3821 |
|
3822 |
+
#: views/metabox/video-metabox.php:79
|
3823 |
msgid "Select your preferred video type."
|
3824 |
msgstr ""
|
3825 |
|
3826 |
+
#: views/metabox/video-metabox.php:92
|
3827 |
msgid "Upload Video"
|
3828 |
msgstr ""
|
3829 |
|
3830 |
+
#: views/metabox/video-metabox.php:94
|
3831 |
msgid "Media ID"
|
3832 |
msgstr ""
|
3833 |
|
3834 |
+
#: views/metabox/video-metabox.php:116
|
3835 |
msgid "Video Poster"
|
3836 |
msgstr ""
|
3837 |
|
3838 |
+
#: views/metabox/video-metabox.php:117
|
3839 |
msgid "Thumb Size: 700x430 pixels. File Support: jpg, jpeg, or png"
|
3840 |
msgstr ""
|
3841 |
|
3842 |
+
#: views/metabox/video-metabox.php:139
|
3843 |
msgid "External Video URL"
|
3844 |
msgstr ""
|
3845 |
|
3846 |
+
#: views/metabox/video-metabox.php:143
|
3847 |
msgid "YouTube Video URL"
|
3848 |
msgstr ""
|
3849 |
|
3850 |
+
#: views/metabox/video-metabox.php:146
|
3851 |
msgid "Vimeo Video URL"
|
3852 |
msgstr ""
|
3853 |
|
3854 |
+
#: views/metabox/video-metabox.php:149
|
3855 |
msgid "Place your embedded code here"
|
3856 |
msgstr ""
|
3857 |
|
3858 |
+
#: views/metabox/video-metabox.php:162
|
3859 |
msgid "Video playback time"
|
3860 |
msgstr ""
|
3861 |
|
3862 |
+
#: views/modal/add_quiz.php:16, views/modal/edit_quiz.php:29
|
3863 |
msgid "Quiz Info"
|
3864 |
msgstr ""
|
3865 |
|
3866 |
+
#: views/modal/add_quiz.php:19, views/modal/edit_quiz.php:32, templates/dashboard/my-quiz-attempts/attempts-details.php:120, templates/dashboard/quiz-attempts/quiz-reviews.php:106, templates/single/quiz/top.php:38
|
3867 |
msgid "Questions"
|
3868 |
msgstr ""
|
3869 |
|
3870 |
+
#: views/modal/add_quiz.php:25, views/modal/edit_quiz.php:38
|
3871 |
msgid "Advanced Options"
|
3872 |
msgstr ""
|
3873 |
|
3874 |
+
#: views/modal/add_quiz.php:38, views/modal/edit_quiz.php:49
|
3875 |
msgid "Type your quiz title here"
|
3876 |
msgstr ""
|
3877 |
|
3878 |
+
#: views/modal/add_quiz.php:53, views/modal/edit_quiz.php:68
|
3879 |
msgid "Save & Next"
|
3880 |
msgstr ""
|
3881 |
|
3882 |
+
#: views/modal/add_quiz.php:72, views/modal/add_quiz.php:95, views/modal/edit_quiz.php:136, views/modal/edit_quiz.php:263, views/modal/edit_quiz.php:350, views/modal/question_form.php:10, templates/dashboard/assignments/review.php:34, templates/dashboard/assignments/submitted.php:21, templates/single/quiz/body.php:393
|
3883 |
msgid "Back"
|
3884 |
msgstr ""
|
3885 |
|
3886 |
+
#: views/modal/add_quiz.php:121, views/modal/edit_quiz.php:364
|
3887 |
msgid "Knowledge Base"
|
3888 |
msgstr ""
|
3889 |
|
3890 |
+
#: views/modal/add_quiz.php:123, views/modal/edit_quiz.php:366
|
3891 |
msgid "Documentation"
|
3892 |
msgstr ""
|
3893 |
|
3894 |
+
#: views/modal/add_quiz.php:124, views/modal/edit_quiz.php:367
|
3895 |
+
msgid "Need any Help? Please visit our %1$s and %2$s."
|
3896 |
msgstr ""
|
3897 |
|
3898 |
#: views/modal/edit-lesson.php:25
|
3919 |
msgid "Update Lesson"
|
3920 |
msgstr ""
|
3921 |
|
3922 |
+
#: views/modal/edit_quiz.php:128
|
3923 |
msgid "Add Question"
|
3924 |
msgstr ""
|
3925 |
|
3926 |
+
#: views/modal/edit_quiz.php:171
|
3927 |
msgid "Hide quiz time - display"
|
3928 |
msgstr ""
|
3929 |
|
3930 |
+
#: views/modal/edit_quiz.php:174
|
3931 |
msgid "Time limit for this quiz. 0 means no time limit."
|
3932 |
msgstr ""
|
3933 |
|
3934 |
+
#: views/modal/edit_quiz.php:178
|
3935 |
msgid "Quiz Feedback Mode"
|
3936 |
msgstr ""
|
3937 |
|
3938 |
+
#: views/modal/edit_quiz.php:180
|
3939 |
msgid "Pick the quiz system\"s behaviour on choice based questions"
|
3940 |
msgstr ""
|
3941 |
|
3942 |
+
#: views/modal/edit_quiz.php:188
|
3943 |
msgid "Default"
|
3944 |
msgstr ""
|
3945 |
|
3946 |
+
#: views/modal/edit_quiz.php:189
|
3947 |
msgid "Answers shown after quiz is finished"
|
3948 |
msgstr ""
|
3949 |
|
3950 |
+
#: views/modal/edit_quiz.php:198
|
3951 |
msgid "Retry Mode"
|
3952 |
msgstr ""
|
3953 |
|
3954 |
+
#: views/modal/edit_quiz.php:199
|
3955 |
msgid "Unlimited attempts on each question."
|
3956 |
msgstr ""
|
3957 |
|
3958 |
+
#: views/modal/edit_quiz.php:208
|
3959 |
msgid "Reveal Mode"
|
3960 |
msgstr ""
|
3961 |
|
3962 |
+
#: views/modal/edit_quiz.php:209
|
3963 |
msgid "Show result after the attempt."
|
3964 |
msgstr ""
|
3965 |
|
3966 |
+
#: views/modal/edit_quiz.php:218, views/modal/question_form.php:107
|
3967 |
msgid "Optional"
|
3968 |
msgstr ""
|
3969 |
|
3970 |
+
#: views/modal/edit_quiz.php:233
|
3971 |
msgid "Restriction on the number of attempts a student is allowed to take for this quiz. 0 for no limit"
|
3972 |
msgstr ""
|
3973 |
|
3974 |
+
#: views/modal/edit_quiz.php:237
|
3975 |
msgid "Passing Grade (%)"
|
3976 |
msgstr ""
|
3977 |
|
3978 |
+
#: views/modal/edit_quiz.php:243
|
3979 |
msgid "Set the passing percentage for this quiz"
|
3980 |
msgstr ""
|
3981 |
|
3982 |
+
#: views/modal/edit_quiz.php:247
|
3983 |
msgid "Max questions allowed to answer"
|
3984 |
msgstr ""
|
3985 |
|
3986 |
+
#: views/modal/edit_quiz.php:253
|
3987 |
msgid "This amount of question will be available for students to answer, and question will comes randomly from all available questions belongs with a quiz, if this amount greater than available question, then all questions will be available for a student to answer."
|
3988 |
msgstr ""
|
3989 |
|
3990 |
+
#: views/modal/edit_quiz.php:264, views/modal/edit_quiz.php:351
|
3991 |
msgid "Saved"
|
3992 |
msgstr ""
|
3993 |
|
3994 |
+
#: views/modal/edit_quiz.php:281
|
3995 |
msgid "Quiz Auto Start"
|
3996 |
msgstr ""
|
3997 |
|
3998 |
+
#: views/modal/edit_quiz.php:284
|
3999 |
msgid "If you enable this option, the quiz will start automatically after the page is loaded."
|
4000 |
msgstr ""
|
4001 |
|
4002 |
+
#: views/modal/edit_quiz.php:290
|
4003 |
msgid "Question Layout"
|
4004 |
msgstr ""
|
4005 |
|
4006 |
+
#: views/modal/edit_quiz.php:293
|
4007 |
msgid "Set question layout view"
|
4008 |
msgstr ""
|
4009 |
|
4010 |
+
#: views/modal/edit_quiz.php:294
|
4011 |
msgid "Single Question"
|
4012 |
msgstr ""
|
4013 |
|
4014 |
+
#: views/modal/edit_quiz.php:295
|
4015 |
msgid "Question Pagination"
|
4016 |
msgstr ""
|
4017 |
|
4018 |
+
#: views/modal/edit_quiz.php:296
|
4019 |
msgid "Question below each other"
|
4020 |
msgstr ""
|
4021 |
|
4022 |
+
#: views/modal/edit_quiz.php:301
|
4023 |
msgid "Questions Order"
|
4024 |
msgstr ""
|
4025 |
|
4026 |
+
#: views/modal/edit_quiz.php:304
|
4027 |
msgid "Random"
|
4028 |
msgstr ""
|
4029 |
|
4030 |
+
#: views/modal/edit_quiz.php:305
|
4031 |
msgid "Sorting"
|
4032 |
msgstr ""
|
4033 |
|
4034 |
+
#: views/modal/edit_quiz.php:307
|
4035 |
msgid "Ascending"
|
4036 |
msgstr ""
|
4037 |
|
4038 |
+
#: views/modal/edit_quiz.php:308
|
4039 |
msgid "Descending"
|
4040 |
msgstr ""
|
4041 |
|
4042 |
+
#: views/modal/edit_quiz.php:322
|
4043 |
msgid "Hide question number"
|
4044 |
msgstr ""
|
4045 |
|
4046 |
+
#: views/modal/edit_quiz.php:325
|
4047 |
msgid "Show/hide question number during attempt."
|
4048 |
msgstr ""
|
4049 |
|
4050 |
+
#: views/modal/edit_quiz.php:329
|
4051 |
msgid "Short answer characters limit"
|
4052 |
msgstr ""
|
4053 |
|
4054 |
+
#: views/modal/edit_quiz.php:335
|
4055 |
msgid "Student will place answer in short answer question type within this characters limit."
|
4056 |
msgstr ""
|
4057 |
|
4058 |
+
#: views/modal/edit_quiz.php:339
|
4059 |
msgid "Open-Ended/Essay questions answer character limit"
|
4060 |
msgstr ""
|
4061 |
|
4062 |
+
#: views/modal/edit_quiz.php:345
|
4063 |
msgid "Students will place the answer in the Open-Ended/Essay question type within this character limit."
|
4064 |
msgstr ""
|
4065 |
|
4066 |
+
#: views/modal/question_answer_edit_form.php:3, views/modal/question_answer_form.php:4
|
4067 |
msgid "No option is necessary for this answer type"
|
4068 |
msgstr ""
|
4069 |
|
4070 |
+
#: views/modal/question_answer_edit_form.php:242, views/modal/question_answer_form.php:252
|
4071 |
msgid "Answer input value"
|
4072 |
msgstr ""
|
4073 |
|
4074 |
+
#: views/modal/question_answer_edit_form.php:248, views/modal/question_answer_form.php:258
|
4075 |
msgid "The answers that students enter should match with this text. Write in <strong>small caps</strong>"
|
4076 |
msgstr ""
|
4077 |
|
4078 |
+
#: views/modal/question_answer_edit_form.php:205, views/modal/question_answer_form.php:221
|
4079 |
msgid "Image matched text"
|
4080 |
msgstr ""
|
4081 |
|
4082 |
+
#: views/modal/question_answer_edit_form.php:110, views/modal/question_answer_edit_form.php:25, views/modal/question_answer_form.php:141, views/modal/question_answer_form.php:118, views/modal/question_answer_form.php:37
|
4083 |
msgid "Answer title"
|
4084 |
msgstr ""
|
4085 |
|
4086 |
+
#: views/modal/question_answer_edit_form.php:118, views/modal/question_answer_form.php:150, views/modal/question_answer_form.php:127
|
4087 |
msgid "Matched Answer title"
|
4088 |
msgstr ""
|
4089 |
|
4090 |
+
#: views/modal/question_answer_edit_form.php:152, views/modal/question_answer_edit_form.php:58, views/modal/question_answer_form.php:176, views/modal/question_answer_form.php:66
|
4091 |
msgid "Display format for options"
|
4092 |
msgstr ""
|
4093 |
|
4094 |
+
#: views/modal/question_answer_edit_form.php:157, views/modal/question_answer_edit_form.php:63, views/modal/question_answer_form.php:181, views/modal/question_answer_form.php:71
|
4095 |
msgid "Only text"
|
4096 |
msgstr ""
|
4097 |
|
4098 |
+
#: views/modal/question_answer_edit_form.php:163, views/modal/question_answer_edit_form.php:69, views/modal/question_answer_form.php:187, views/modal/question_answer_form.php:77
|
4099 |
msgid "Only Image"
|
4100 |
msgstr ""
|
4101 |
|
4102 |
+
#: views/modal/question_answer_edit_form.php:169, views/modal/question_answer_edit_form.php:75, views/modal/question_answer_form.php:193, views/modal/question_answer_form.php:83
|
4103 |
msgid "Text & Image both"
|
4104 |
msgstr ""
|
4105 |
|
4106 |
+
#: views/modal/question_answer_edit_form.php:84, views/modal/question_answer_form.php:93, templates/single/lesson/sidebar_question_and_answer.php:154, templates/single/course/enrolled/question_and_answer.php:36
|
4107 |
msgid "Question Title"
|
4108 |
msgstr ""
|
4109 |
|
4110 |
+
#: views/modal/question_answer_edit_form.php:91
|
4111 |
msgid "Please make sure that <b>{dash}</b> variable contains in your question title to show dash, You can use multiple variable"
|
4112 |
msgstr ""
|
4113 |
|
4114 |
+
#: views/modal/question_answer_edit_form.php:96, views/modal/question_answer_form.php:103
|
4115 |
msgid "Correct Answer(s)"
|
4116 |
msgstr ""
|
4117 |
|
4118 |
+
#: views/modal/question_answer_edit_form.php:102
|
4119 |
msgid "Separate multiple answer by pipe <b>( | )</b> , 1 answer per variable assigned in question"
|
4120 |
msgstr ""
|
4121 |
|
4122 |
+
#: views/modal/question_answer_edit_form.php:256
|
4123 |
msgid "Update Answer"
|
4124 |
msgstr ""
|
4125 |
|
4126 |
+
#: views/modal/question_answer_form.php:99
|
4127 |
msgid "Please make sure to use the <strong>{dash}</strong> variable in your question title to show the blanks in your question. You can use multiple <strong>{dash}</strong> variables in one question."
|
4128 |
msgstr ""
|
4129 |
|
4130 |
+
#: views/modal/question_answer_form.php:109
|
4131 |
msgid "Separate multiple answers by a vertical bar <strong>|</strong>. 1 answer per <strong>{dash}</strong> variable is defined in the question. Example: Apple | Banana | Orange"
|
4132 |
msgstr ""
|
4133 |
|
4134 |
+
#: views/modal/question_answer_form.php:17
|
4135 |
msgid "Select the correct option"
|
4136 |
msgstr ""
|
4137 |
|
4138 |
+
#: views/modal/question_answer_form.php:266
|
4139 |
msgid "Save Answer"
|
4140 |
msgstr ""
|
4141 |
|
4142 |
+
#: views/modal/question_form.php:20
|
4143 |
msgid "Write your question here"
|
4144 |
msgstr ""
|
4145 |
|
4146 |
+
#: views/modal/question_form.php:23
|
4147 |
msgid "Type your question here"
|
4148 |
msgstr ""
|
4149 |
|
4150 |
+
#: views/modal/question_form.php:29
|
4151 |
msgid "Question Type"
|
4152 |
msgstr ""
|
4153 |
|
4154 |
+
#: views/modal/question_form.php:34
|
4155 |
msgid "True or False"
|
4156 |
msgstr ""
|
4157 |
|
4158 |
+
#: views/modal/question_form.php:52
|
4159 |
msgid "Pro version required"
|
4160 |
msgstr ""
|
4161 |
|
4162 |
+
#: views/modal/question_form.php:73
|
4163 |
msgid "Answer Required"
|
4164 |
msgstr ""
|
4165 |
|
4166 |
+
#: views/modal/question_form.php:80
|
4167 |
msgid "Randomize"
|
4168 |
msgstr ""
|
4169 |
|
4170 |
+
#: views/modal/question_form.php:86
|
4171 |
msgid "Point(s) for this answer"
|
4172 |
msgstr ""
|
4173 |
|
4174 |
+
#: views/modal/question_form.php:89
|
4175 |
msgid "set the mark ex. 10"
|
4176 |
msgstr ""
|
4177 |
|
4178 |
+
#: views/modal/question_form.php:101
|
4179 |
msgid "Display Points"
|
4180 |
msgstr ""
|
4181 |
|
4182 |
+
#: views/modal/question_form.php:120
|
4183 |
msgid "Input options for the question and select the correct answer."
|
4184 |
msgstr ""
|
4185 |
|
4186 |
+
#: views/modal/question_form.php:123
|
4187 |
msgid "Make sure you’re saving the answers in the right order. Students will have to match this order."
|
4188 |
msgstr ""
|
4189 |
|
4190 |
+
#: views/modal/question_form.php:191
|
4191 |
msgid "Add An Option"
|
4192 |
msgstr ""
|
4193 |
|
4194 |
+
#: views/modal/question_form.php:210
|
4195 |
msgid "Save & Continue"
|
4196 |
msgstr ""
|
4197 |
|
4215 |
msgid "Settings Saved"
|
4216 |
msgstr ""
|
4217 |
|
4218 |
+
#: views/options/options_generator.php:88
|
4219 |
msgid "Save Settings"
|
4220 |
msgstr ""
|
4221 |
|
4227 |
msgid "Themes"
|
4228 |
msgstr ""
|
4229 |
|
4230 |
+
#: views/pages/addons.php:97, views/pages/addons.php:91
|
4231 |
msgid "No %s currently avaialable"
|
4232 |
msgstr ""
|
4233 |
|
4234 |
+
#: views/pages/addons.php:59, views/pages/tutor-pro-addons.php:44
|
4235 |
msgid "Buy Now"
|
4236 |
msgstr ""
|
4237 |
|
4238 |
+
#: views/pages/addons.php:79, views/pages/enable_disable_addons.php:111, views/pages/tutor-pro-addons.php:55
|
4239 |
msgid "Version"
|
4240 |
msgstr ""
|
4241 |
|
4243 |
msgid "Add new instructor"
|
4244 |
msgstr ""
|
4245 |
|
4246 |
+
#: views/pages/announcements.php:54
|
4247 |
msgid "Search Announcements"
|
4248 |
msgstr ""
|
4249 |
|
4250 |
+
#: views/pages/announcements.php:107
|
4251 |
msgid "Add new"
|
4252 |
msgstr ""
|
4253 |
|
4254 |
+
#: views/pages/announcements.php:184, templates/dashboard/announcements/create.php:6
|
4255 |
msgid "Create New Announcement"
|
4256 |
msgstr ""
|
4257 |
|
4258 |
+
#: views/pages/announcements.php:219, views/pages/announcements.php:301, templates/dashboard/announcements/create.php:35, templates/dashboard/announcements/update.php:36
|
4259 |
msgid "Announcement Title"
|
4260 |
msgstr ""
|
4261 |
|
4262 |
+
#: views/pages/announcements.php:223, views/pages/announcements.php:305, templates/dashboard/announcements/create.php:37, templates/dashboard/announcements/update.php:38
|
4263 |
msgid "Announcement title"
|
4264 |
msgstr ""
|
4265 |
|
4266 |
+
#: views/pages/announcements.php:229, views/pages/announcements.php:311, templates/dashboard/announcements/create.php:41, templates/dashboard/announcements/update.php:42
|
4267 |
msgid "Summary"
|
4268 |
msgstr ""
|
4269 |
|
4270 |
+
#: views/pages/announcements.php:233, views/pages/announcements.php:315, templates/dashboard/announcements/create.php:43, templates/dashboard/announcements/update.php:44
|
4271 |
msgid "Summary..."
|
4272 |
msgstr ""
|
4273 |
|
4274 |
+
#: views/pages/announcements.php:246, templates/dashboard/announcements/create.php:52
|
4275 |
msgid "Publish"
|
4276 |
msgstr ""
|
4277 |
|
4278 |
+
#: views/pages/announcements.php:264, templates/dashboard/announcements/update.php:6
|
4279 |
msgid "Update Announcement"
|
4280 |
msgstr ""
|
4281 |
|
4282 |
+
#: views/pages/announcements.php:328, views/pages/view_attempt.php:360, templates/dashboard/announcements/update.php:51, templates/dashboard/quiz-attempts/quiz-reviews.php:424
|
4283 |
msgid "Update"
|
4284 |
msgstr ""
|
4285 |
|
4291 |
msgid "Place answer"
|
4292 |
msgstr ""
|
4293 |
|
4294 |
+
#: views/pages/answer.php:65
|
4295 |
msgid "on"
|
4296 |
msgstr ""
|
4297 |
|
4303 |
msgid "Required Plugin(s)"
|
4304 |
msgstr ""
|
4305 |
|
4306 |
+
#: views/pages/enable_disable_addons.php:94, templates/single/course/course-requirements.php:29
|
4307 |
+
msgid "Requirements"
|
4308 |
+
msgstr ""
|
4309 |
+
|
4310 |
#: views/pages/get-pro.php:2
|
4311 |
msgid "Get pro plugin from themeum.com"
|
4312 |
msgstr ""
|
4331 |
msgid "Completely Uninstall and erase all data"
|
4332 |
msgstr ""
|
4333 |
|
4334 |
+
#: views/pages/view_attempt.php:7, templates/dashboard/my-quiz-attempts/attempts-details.php:24, templates/dashboard/my-quiz-attempts/attempts-details.php:88, templates/dashboard/quiz-attempts/quiz-reviews.php:22
|
4335 |
msgid "Attempt not found"
|
4336 |
msgstr ""
|
4337 |
|
4355 |
msgid "Quiz Time"
|
4356 |
msgstr ""
|
4357 |
|
4358 |
+
#: views/pages/view_attempt.php:157, templates/dashboard/quiz-attempts/quiz-reviews.php:198
|
4359 |
msgid "Reminder:"
|
4360 |
msgstr ""
|
4361 |
|
4362 |
+
#: views/pages/view_attempt.php:157, templates/dashboard/quiz-attempts/quiz-reviews.php:198
|
4363 |
msgid "Please review answers for question no. %s"
|
4364 |
msgstr ""
|
4365 |
|
4366 |
+
#: views/pages/view_attempt.php:170, templates/dashboard/quiz-attempts/quiz-reviews.php:209
|
4367 |
msgid "Manually reviewed at: "
|
4368 |
msgstr ""
|
4369 |
|
4370 |
+
#: views/pages/view_attempt.php:187, templates/dashboard/my-quiz-attempts/attempts-details.php:208, templates/dashboard/quiz-attempts/quiz-reviews.php:225
|
4371 |
msgid "Quiz Overview"
|
4372 |
msgstr ""
|
4373 |
|
4374 |
+
#: views/pages/view_attempt.php:192, templates/dashboard/earning/statement.php:53, templates/dashboard/earning/statement.php:60, templates/dashboard/earning/statements.php:181, templates/dashboard/earning/statements.php:188, templates/dashboard/my-quiz-attempts/attempts-details.php:214, templates/dashboard/quiz-attempts/quiz-reviews.php:231
|
4375 |
msgid "Type"
|
4376 |
msgstr ""
|
4377 |
|
4378 |
+
#: views/pages/view_attempt.php:193, templates/dashboard/my-quiz-attempts/attempts-details.php:213, templates/dashboard/quiz-attempts/quiz-reviews.php:230
|
4379 |
msgid "No."
|
4380 |
msgstr ""
|
4381 |
|
4382 |
+
#: views/pages/view_attempt.php:195, templates/dashboard/my-quiz-attempts/attempts-details.php:216, templates/dashboard/quiz-attempts/quiz-reviews.php:233
|
4383 |
msgid "Given Answers"
|
4384 |
msgstr ""
|
4385 |
|
4386 |
+
#: views/pages/view_attempt.php:196, templates/dashboard/my-quiz-attempts/attempts-details.php:218, templates/dashboard/quiz-attempts/quiz-reviews.php:235
|
4387 |
msgid "Correct/Incorrect"
|
4388 |
msgstr ""
|
4389 |
|
4390 |
+
#: views/pages/view_attempt.php:197, templates/dashboard/quiz-attempts/quiz-reviews.php:236
|
4391 |
msgid "Manual Review"
|
4392 |
msgstr ""
|
4393 |
|
4394 |
+
#: views/pages/view_attempt.php:326, views/pages/view_attempt.php:321, templates/dashboard/my-quiz-attempts/attempts-details.php:124, templates/dashboard/my-quiz-attempts/attempts-details.php:389, templates/dashboard/my-quiz-attempts/attempts-details.php:384, templates/dashboard/quiz-attempts/quiz-reviews.php:110, templates/dashboard/quiz-attempts/quiz-reviews.php:397, templates/dashboard/quiz-attempts/quiz-reviews.php:392
|
4395 |
msgid "Incorrect"
|
4396 |
msgstr ""
|
4397 |
|
4398 |
+
#: views/pages/view_attempt.php:323, views/pages/view_attempt.php:312, templates/dashboard/my-quiz-attempts/attempts-details.php:123, templates/dashboard/my-quiz-attempts/attempts-details.php:380, templates/dashboard/quiz-attempts/quiz-reviews.php:109, templates/dashboard/quiz-attempts/quiz-reviews.php:388
|
4399 |
msgid "Correct"
|
4400 |
msgstr ""
|
4401 |
|
4402 |
+
#: views/pages/view_attempt.php:318, templates/dashboard/my-quiz-attempts/attempts-details.php:386, templates/dashboard/quiz-attempts/quiz-reviews.php:394
|
4403 |
msgid "Review Required"
|
4404 |
msgstr ""
|
4405 |
|
4406 |
+
#: views/pages/view_attempt.php:338, templates/dashboard/quiz-attempts/quiz-reviews.php:405
|
4407 |
msgid "Mark as In correct"
|
4408 |
msgstr ""
|
4409 |
|
4410 |
+
#: views/pages/view_attempt.php:356, templates/dashboard/my-quiz-attempts/attempts-details.php:190, templates/dashboard/quiz-attempts/quiz-reviews.php:176, templates/dashboard/quiz-attempts/quiz-reviews.php:420
|
4411 |
msgid "Instructor Feedback"
|
4412 |
msgstr ""
|
4413 |
|
4414 |
+
#: views/pages/view_attempt.php:360, templates/dashboard/quiz-attempts/quiz-reviews.php:424
|
4415 |
msgid "Updated"
|
4416 |
msgstr ""
|
4417 |
|
4488 |
msgstr ""
|
4489 |
|
4490 |
#: templates/dashboard/assignments/submitted.php:87
|
4491 |
+
msgid "%1$s Pending %2$s"
|
4492 |
msgstr ""
|
4493 |
|
4494 |
#: templates/dashboard/assignments/submitted.php:88
|
4496 |
msgstr ""
|
4497 |
|
4498 |
#: templates/dashboard/assignments/submitted.php:90
|
4499 |
+
msgid "%1$s Pass %2$s"
|
4500 |
msgstr ""
|
4501 |
|
4502 |
#: templates/dashboard/assignments/submitted.php:90
|
4503 |
+
msgid "%1$s Fail %2$s"
|
4504 |
msgstr ""
|
4505 |
|
4506 |
#: templates/dashboard/earning/earning-report-top-menu.php:12
|
4535 |
msgid "My Earning"
|
4536 |
msgstr ""
|
4537 |
|
4538 |
+
#: templates/dashboard/earning/report-date_range.php:56, templates/dashboard/earning/report-date_range.php:58, templates/dashboard/earning/report-last_month.php:55, templates/dashboard/earning/report-last_month.php:57, templates/dashboard/earning/report-last_week.php:59, templates/dashboard/earning/report-last_week.php:61, templates/dashboard/earning/report-last_year.php:55, templates/dashboard/earning/report-last_year.php:57, templates/dashboard/earning/report-this_month.php:62, templates/dashboard/earning/report-this_month.php:64, templates/dashboard/earning/report-this_week.php:57, templates/dashboard/earning/report-this_week.php:59, templates/dashboard/earning/report-this_year.php:53, templates/dashboard/earning/report-this_year.php:55
|
4539 |
msgid "Deducted Fees"
|
4540 |
msgstr ""
|
4541 |
|
4542 |
#: templates/dashboard/earning/report-date_range.php:67, templates/dashboard/earning/report-last_week.php:74, templates/dashboard/earning/report-this_week.php:67
|
4543 |
+
msgid "Showing Result from %1$s to %2$s"
|
4544 |
msgstr ""
|
4545 |
|
4546 |
+
#: templates/dashboard/earning/report-date_range.php:74, templates/dashboard/earning/report-last_month.php:72, templates/dashboard/earning/report-last_week.php:81, templates/dashboard/earning/report-last_year.php:76, templates/dashboard/earning/report-this_month.php:84, templates/dashboard/earning/report-this_week.php:74, templates/dashboard/earning/report-this_year.php:74
|
4547 |
msgid "Sales statements for this period"
|
4548 |
msgstr ""
|
4549 |
|
4550 |
+
#: templates/dashboard/earning/report-last_month.php:65, templates/dashboard/earning/report-this_month.php:77
|
4551 |
msgid "Earning Data for the month of %s"
|
4552 |
msgstr ""
|
4553 |
|
4555 |
msgid "Earning Data for the year of %s"
|
4556 |
msgstr ""
|
4557 |
|
4558 |
+
#: templates/dashboard/earning/report.php:28
|
4559 |
msgid "Earning Report"
|
4560 |
msgstr ""
|
4561 |
|
4562 |
+
#: templates/dashboard/earning/statement.php:71, templates/dashboard/earning/statements.php:199
|
4563 |
msgid "There is not enough sales data to generate a statement"
|
4564 |
msgstr ""
|
4565 |
|
4566 |
+
#: templates/dashboard/earning/statement.php:14, templates/dashboard/earning/statements.php:133
|
4567 |
msgid "Deduct"
|
4568 |
msgstr ""
|
4569 |
|
4570 |
+
#: templates/dashboard/earning/statement.php:36, templates/dashboard/earning/statements.php:144
|
4571 |
msgid "Date:"
|
4572 |
msgstr ""
|
4573 |
|
4574 |
+
#: templates/dashboard/earning/statement.php:51, templates/dashboard/earning/statements.php:132
|
4575 |
msgid "Commission"
|
4576 |
msgstr ""
|
4577 |
|
4578 |
+
#: templates/dashboard/earning/statement.php:52, templates/dashboard/earning/statements.php:180
|
4579 |
msgid "Rate"
|
4580 |
msgstr ""
|
4581 |
|
4582 |
+
#: templates/dashboard/earning/statement.php:56
|
4583 |
msgid "Deducted"
|
4584 |
msgstr ""
|
4585 |
|
4586 |
+
#: templates/dashboard/earning/statements.php:30
|
4587 |
msgid "Report"
|
4588 |
msgstr ""
|
4589 |
|
4590 |
+
#: templates/dashboard/earning/statements.php:123
|
4591 |
+
msgid "Showing results %1$d to %2$d of %3$d"
|
4592 |
msgstr ""
|
4593 |
|
4594 |
+
#: templates/dashboard/earning/statements.php:155
|
4595 |
msgid "Price: "
|
4596 |
msgstr ""
|
4597 |
|
4598 |
+
#: templates/dashboard/earning/statements.php:167
|
4599 |
msgid "Purchaser"
|
4600 |
msgstr ""
|
4601 |
|
4663 |
msgid "Register as instructor"
|
4664 |
msgstr ""
|
4665 |
|
4666 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:97
|
4667 |
msgid "You have no access."
|
4668 |
msgstr ""
|
4669 |
|
4670 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:107, templates/dashboard/quiz-attempts/quiz-reviews.php:92
|
4671 |
msgid "Back to Attempt List"
|
4672 |
msgstr ""
|
4673 |
|
4674 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:112, templates/dashboard/quiz-attempts/quiz-reviews.php:98
|
4675 |
msgid "Quiz:"
|
4676 |
msgstr ""
|
4677 |
|
4678 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:113, templates/dashboard/quiz-attempts/quiz-reviews.php:99
|
4679 |
msgid "Course:"
|
4680 |
msgstr ""
|
4681 |
|
4682 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:118, templates/dashboard/quiz-attempts/quiz-reviews.php:104
|
4683 |
msgid "#"
|
4684 |
msgstr ""
|
4685 |
|
4686 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:119, templates/dashboard/quiz-attempts/quiz-reviews.php:105
|
4687 |
msgid "Attempts Date"
|
4688 |
msgstr ""
|
4689 |
|
4690 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:121, templates/dashboard/quiz-attempts/quiz-reviews.php:107
|
4691 |
msgid "Total Marks"
|
4692 |
msgstr ""
|
4693 |
|
4694 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:122, templates/dashboard/quiz-attempts/quiz-reviews.php:108
|
4695 |
msgid "Pass Marks"
|
4696 |
msgstr ""
|
4697 |
|
4698 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:126, templates/dashboard/quiz-attempts/quiz-reviews.php:112
|
4699 |
msgid "Results"
|
4700 |
msgstr ""
|
4701 |
|
4702 |
+
#: templates/dashboard/my-quiz-attempts/attempts-details.php:217, templates/dashboard/quiz-attempts/quiz-reviews.php:234
|
4703 |
msgid "Correct Answers"
|
4704 |
msgstr ""
|
4705 |
|
4715 |
msgid "Set Your"
|
4716 |
msgstr ""
|
4717 |
|
4718 |
+
#: templates/dashboard/notifications/profile-completion.php:26
|
4719 |
msgid "% Complete"
|
4720 |
msgstr ""
|
4721 |
|
4722 |
+
#: templates/dashboard/notifications/profile-completion.php:28
|
4723 |
msgid "You are almost done!"
|
4724 |
msgstr ""
|
4725 |
|
4735 |
msgid "Update Review"
|
4736 |
msgstr ""
|
4737 |
|
4738 |
+
#: templates/dashboard/reviews/given-reviews.php:60
|
4739 |
msgid "Edit Feedback"
|
4740 |
msgstr ""
|
4741 |
|
4742 |
+
#: templates/dashboard/reviews/given-reviews.php:86
|
4743 |
msgid "Edit Review"
|
4744 |
msgstr ""
|
4745 |
|
4747 |
msgid "Reset Password"
|
4748 |
msgstr ""
|
4749 |
|
4750 |
+
#: templates/dashboard/settings/nav-bar.php:32
|
4751 |
msgid "Withdraw"
|
4752 |
msgstr ""
|
4753 |
|
4759 |
msgid "Upload Cover Photo"
|
4760 |
msgstr ""
|
4761 |
|
4762 |
+
#: templates/dashboard/settings/profile.php:50
|
4763 |
msgid "Profile Photo Size"
|
4764 |
msgstr ""
|
4765 |
|
4766 |
+
#: templates/dashboard/settings/profile.php:50
|
4767 |
msgid "200x200"
|
4768 |
msgstr ""
|
4769 |
|
4770 |
+
#: templates/dashboard/settings/profile.php:50, templates/dashboard/settings/profile.php:51
|
4771 |
msgid "pixels"
|
4772 |
msgstr ""
|
4773 |
|
4774 |
+
#: templates/dashboard/settings/profile.php:51
|
4775 |
msgid "Cover Photo Size"
|
4776 |
msgstr ""
|
4777 |
|
4778 |
+
#: templates/dashboard/settings/profile.php:51
|
4779 |
msgid "700x430"
|
4780 |
msgstr ""
|
4781 |
|
4782 |
+
#: templates/dashboard/settings/profile.php:52
|
4783 |
msgid "Saving..."
|
4784 |
msgstr ""
|
4785 |
|
4786 |
+
#: templates/dashboard/settings/profile.php:65
|
4787 |
msgid "Upload Photo"
|
4788 |
msgstr ""
|
4789 |
|
4790 |
+
#: templates/dashboard/settings/profile.php:147
|
4791 |
msgid "Display name publicly as"
|
4792 |
msgstr ""
|
4793 |
|
4794 |
+
#: templates/dashboard/settings/profile.php:185
|
4795 |
msgid "The display name is shown in all public fields, such as the author name, instructor name, student name, and name that will be printed on the certificate."
|
4796 |
msgstr ""
|
4797 |
|
4798 |
+
#: templates/dashboard/settings/profile.php:215
|
4799 |
msgid "Update Profile"
|
4800 |
msgstr ""
|
4801 |
|
4815 |
msgid "Select a withdraw method"
|
4816 |
msgstr ""
|
4817 |
|
4818 |
+
#: templates/dashboard/settings/withdraw-settings.php:37
|
4819 |
msgid "Min withdraw"
|
4820 |
msgstr ""
|
4821 |
|
4822 |
+
#: templates/dashboard/settings/withdraw-settings.php:107
|
4823 |
msgid "Save Withdrawal Account"
|
4824 |
msgstr ""
|
4825 |
|
4826 |
+
#: templates/single/assignment/content.php:89
|
4827 |
msgid "Time Duration : "
|
4828 |
msgstr ""
|
4829 |
|
4830 |
+
#: templates/single/assignment/content.php:90, templates/single/quiz/top.php:66, templates/single/quiz/top.php:81
|
4831 |
msgid "No limit"
|
4832 |
msgstr ""
|
4833 |
|
4834 |
+
#: templates/single/assignment/content.php:102
|
4835 |
msgid "Deadline : "
|
4836 |
msgstr ""
|
4837 |
|
4838 |
+
#: templates/single/assignment/content.php:103, templates/single/course/course-topics.php:143
|
4839 |
msgid "Expired"
|
4840 |
msgstr ""
|
4841 |
|
4842 |
+
#: templates/single/assignment/content.php:115
|
4843 |
msgid "Total Points : "
|
4844 |
msgstr ""
|
4845 |
|
4846 |
+
#: templates/single/assignment/content.php:119
|
4847 |
msgid "Minimum Pass Points : "
|
4848 |
msgstr ""
|
4849 |
|
4850 |
+
#: templates/single/assignment/content.php:137
|
4851 |
msgid "You have missed the submission deadline. Please contact the instructor for more information."
|
4852 |
msgstr ""
|
4853 |
|
4854 |
+
#: templates/single/assignment/content.php:323
|
4855 |
msgid "Submit assignment"
|
4856 |
msgstr ""
|
4857 |
|
4858 |
+
#: templates/single/assignment/content.php:239
|
4859 |
+
msgid "You received %1$s points out of %2$s"
|
4860 |
msgstr ""
|
4861 |
|
4862 |
+
#: templates/single/assignment/content.php:241
|
4863 |
msgid "Your Grade is "
|
4864 |
msgstr ""
|
4865 |
|
4866 |
+
#: templates/single/assignment/content.php:252
|
4867 |
msgid "Failed"
|
4868 |
msgstr ""
|
4869 |
|
4870 |
+
#: templates/single/assignment/content.php:246
|
4871 |
msgid "Passed"
|
4872 |
msgstr ""
|
4873 |
|
4874 |
+
#: templates/single/assignment/content.php:266
|
4875 |
msgid "Your Answers"
|
4876 |
msgstr ""
|
4877 |
|
4878 |
+
#: templates/single/assignment/content.php:278
|
4879 |
msgid "Your uploaded file(s)"
|
4880 |
msgstr ""
|
4881 |
|
4882 |
+
#: templates/single/assignment/content.php:298
|
4883 |
msgid "Instructor Note"
|
4884 |
msgstr ""
|
4885 |
|
4886 |
+
#: templates/single/assignment/content.php:179
|
4887 |
msgid "Assignment answer form"
|
4888 |
msgstr ""
|
4889 |
|
4890 |
+
#: templates/single/assignment/content.php:189
|
4891 |
msgid "Write your answer briefly"
|
4892 |
msgstr ""
|
4893 |
|
4894 |
+
#: templates/single/assignment/content.php:196
|
4895 |
msgid "Attach assignment files"
|
4896 |
msgstr ""
|
4897 |
|
4898 |
+
#: templates/single/assignment/content.php:202
|
4899 |
msgid "Upload file"
|
4900 |
msgstr ""
|
4901 |
|
4902 |
+
#: templates/single/assignment/content.php:214
|
4903 |
msgid "Submit Assignment"
|
4904 |
msgstr ""
|
4905 |
|
4907 |
msgid "Please make sure that your EDD product exists and valid for this course"
|
4908 |
msgstr ""
|
4909 |
|
4910 |
+
#: templates/single/course/add-to-cart-woocommerce.php:44
|
4911 |
msgid "Please make sure that your product exists and valid for this course"
|
4912 |
msgstr ""
|
4913 |
|
4914 |
+
#: templates/single/course/add-to-cart.php:77
|
4915 |
msgid "Enroll Now"
|
4916 |
msgstr ""
|
4917 |
|
4918 |
+
#: templates/single/course/add-to-cart.php:62
|
4919 |
msgid "Start Learning"
|
4920 |
msgstr ""
|
4921 |
|
4931 |
msgid "Complete Course"
|
4932 |
msgstr ""
|
4933 |
|
4934 |
+
#: templates/single/course/continue-lesson.php:43
|
4935 |
msgid "Continue to lesson"
|
4936 |
msgstr ""
|
4937 |
|
4938 |
+
#: templates/single/course/course-benefits.php:30
|
4939 |
msgid "What Will I Learn?"
|
4940 |
msgstr ""
|
4941 |
|
4942 |
+
#: templates/single/course/course-enrolled-box.php:52
|
4943 |
msgid "Start Course"
|
4944 |
msgstr ""
|
4945 |
|
4946 |
+
#: templates/single/course/course-enrolled-box.php:50
|
4947 |
msgid "Retake This Course"
|
4948 |
msgstr ""
|
4949 |
|
4950 |
+
#: templates/single/course/course-enrolled-box.php:78
|
4951 |
msgid "You have been enrolled on %s."
|
4952 |
msgstr ""
|
4953 |
|
|
|
|
|
|
|
|
|
4954 |
#: templates/single/course/course-target-audience.php:28
|
4955 |
msgid "Target Audience"
|
4956 |
msgstr ""
|
4957 |
|
4958 |
+
#: templates/single/course/course-topics.php:31
|
4959 |
msgid "Topics for this course"
|
4960 |
msgstr ""
|
4961 |
|
4962 |
+
#: templates/single/course/course-topics.php:145
|
4963 |
msgid "Live"
|
4964 |
msgstr ""
|
4965 |
|
4979 |
msgid "students"
|
4980 |
msgstr ""
|
4981 |
|
4982 |
+
#: templates/single/course/lead-info.php:71, templates/single/course/enrolled/lead-info.php:71
|
4983 |
msgid "Course level:"
|
4984 |
msgstr ""
|
4985 |
|
4986 |
+
#: templates/single/course/lead-info.php:112, templates/single/course/enrolled/lead-info.php:113
|
4987 |
msgid "Duration"
|
4988 |
msgstr ""
|
4989 |
|
4990 |
+
#: templates/single/course/lead-info.php:121, templates/single/course/enrolled/lead-info.php:122
|
4991 |
msgid "Total Enrolled"
|
4992 |
msgstr ""
|
4993 |
|
4994 |
+
#: templates/single/course/lead-info.php:130, templates/single/course/enrolled/lead-info.php:131
|
4995 |
msgid "Last Update"
|
4996 |
msgstr ""
|
4997 |
|
4998 |
+
#: templates/single/course/lead-info.php:146, templates/single/course/enrolled/lead-info.php:169
|
4999 |
msgid "About Course"
|
5000 |
msgstr ""
|
5001 |
|
5002 |
+
#: templates/single/course/login.php:21
|
5003 |
msgid "Login"
|
5004 |
msgstr ""
|
5005 |
|
5035 |
msgid "Complete Lesson"
|
5036 |
msgstr ""
|
5037 |
|
5038 |
+
#: templates/single/lesson/lesson_sidebar.php:44
|
5039 |
msgid "Browse Q&A"
|
5040 |
msgstr ""
|
5041 |
|
5047 |
msgid "Course name : %s"
|
5048 |
msgstr ""
|
5049 |
|
5050 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:133
|
5051 |
msgid "No questions yet"
|
5052 |
msgstr ""
|
5053 |
|
5054 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:134
|
5055 |
msgid "Be the first to ask your question! You’ll be able to add details in the next step."
|
5056 |
msgstr ""
|
5057 |
|
5058 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:103, templates/single/course/enrolled/question_and_answer.php:128
|
5059 |
msgid "Add an answer"
|
5060 |
msgstr ""
|
5061 |
|
5062 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:112, templates/single/course/enrolled/question_and_answer.php:137
|
5063 |
msgid "Write your answer here..."
|
5064 |
msgstr ""
|
5065 |
|
5066 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:118, templates/single/course/enrolled/question_and_answer.php:143
|
5067 |
msgid "Add Answer"
|
5068 |
msgstr ""
|
5069 |
|
5070 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:145, templates/single/course/enrolled/question_and_answer.php:25
|
5071 |
msgid "Ask a new question"
|
5072 |
msgstr ""
|
5073 |
|
5074 |
+
#: templates/single/lesson/sidebar_question_and_answer.php:170
|
5075 |
msgid "Submit My Question"
|
5076 |
msgstr ""
|
5077 |
|
5078 |
+
#: templates/single/quiz/body.php:456
|
5079 |
msgid "Start Quiz"
|
5080 |
msgstr ""
|
5081 |
|
5082 |
+
#: templates/single/quiz/body.php:51
|
5083 |
msgid "Time remaining : "
|
5084 |
msgstr ""
|
5085 |
|
5086 |
+
#: templates/single/quiz/body.php:95
|
5087 |
msgid "Reattempt"
|
5088 |
msgstr ""
|
5089 |
|
5090 |
+
#: templates/single/quiz/body.php:150
|
5091 |
msgid "Marks : "
|
5092 |
msgstr ""
|
5093 |
|
5094 |
+
#: templates/single/quiz/body.php:335, templates/single/quiz/body.php:344
|
5095 |
msgid "characters remaining"
|
5096 |
msgstr ""
|
5097 |
|
5098 |
+
#: templates/single/quiz/body.php:399
|
5099 |
msgid "Answer & Next Question"
|
5100 |
msgstr ""
|
5101 |
|
5102 |
+
#: templates/single/quiz/body.php:399, templates/single/quiz/body.php:416
|
5103 |
msgid "Submit Quiz"
|
5104 |
msgstr ""
|
5105 |
|
5135 |
msgid "Passing Grade"
|
5136 |
msgstr ""
|
5137 |
|
5138 |
+
#: views/options/field-types/radio.php:3, views/options/field-types/select.php:4, views/metabox/course/field-types/select.php:4, views/options/field-types/groups/select.php:5, views/metabox/course/field-types/groups/select.php:5
|
5139 |
msgid "Select Option"
|
5140 |
msgstr ""
|
5141 |
|
5253 |
msgid "Server environment"
|
5254 |
msgstr ""
|
5255 |
|
5256 |
+
#: views/pages/tools/status.php:133
|
5257 |
msgid "Server info"
|
5258 |
msgstr ""
|
5259 |
|
5260 |
+
#: views/pages/tools/status.php:134
|
5261 |
msgid "Information about the web server that is currently hosting your site."
|
5262 |
msgstr ""
|
5263 |
|
5264 |
+
#: views/pages/tools/status.php:138
|
5265 |
msgid "PHP version"
|
5266 |
msgstr ""
|
5267 |
|
5268 |
+
#: views/pages/tools/status.php:139
|
5269 |
msgid "The version of PHP installed on your hosting server."
|
5270 |
msgstr ""
|
5271 |
|
5272 |
+
#: views/pages/tools/status.php:150
|
5273 |
msgid "We recommend using PHP version 7.2 or above for greater performance and security."
|
5274 |
msgstr ""
|
5275 |
|
5276 |
+
#: views/pages/tools/status.php:148
|
5277 |
msgid "Tutor will run under this version of PHP, however, it has reached end of life. We recommend using PHP version 7.2 or above for greater performance and security."
|
5278 |
msgstr ""
|
5279 |
|
5280 |
+
#: views/pages/tools/status.php:161
|
5281 |
msgid "PHP post max size"
|
5282 |
msgstr ""
|
5283 |
|
5284 |
+
#: views/pages/tools/status.php:162
|
5285 |
msgid "The largest filesize that can be contained in one post."
|
5286 |
msgstr ""
|
5287 |
|
5288 |
+
#: views/pages/tools/status.php:166
|
5289 |
msgid "PHP time limit"
|
5290 |
msgstr ""
|
5291 |
|
5292 |
+
#: views/pages/tools/status.php:167
|
5293 |
msgid "The amount of time (in seconds) that your site will spend on a single operation before timing out (to avoid server lockups)"
|
5294 |
msgstr ""
|
5295 |
|
5296 |
+
#: views/pages/tools/status.php:171
|
5297 |
msgid "PHP max input vars"
|
5298 |
msgstr ""
|
5299 |
|
5300 |
+
#: views/pages/tools/status.php:172
|
5301 |
msgid "The maximum number of variables your server can use for a single function to avoid overloads."
|
5302 |
msgstr ""
|
5303 |
|
5304 |
+
#: views/pages/tools/status.php:176
|
5305 |
msgid "cURL version"
|
5306 |
msgstr ""
|
5307 |
|
5308 |
+
#: views/pages/tools/status.php:177
|
5309 |
msgid "The version of cURL installed on your server."
|
5310 |
msgstr ""
|
5311 |
|
5312 |
+
#: views/pages/tools/status.php:181
|
5313 |
msgid "SUHOSIN installed"
|
5314 |
msgstr ""
|
5315 |
|
5316 |
+
#: views/pages/tools/status.php:182
|
5317 |
msgid "Suhosin is an advanced protection system for PHP installations. It was designed to protect your servers on the one hand against a number of well known problems in PHP applications and on the other hand against potential unknown vulnerabilities within these applications or the PHP core itself. If enabled on your server, Suhosin may need to be configured to increase its data submission limits."
|
5318 |
msgstr ""
|
5319 |
|
5320 |
+
#: views/pages/tools/status.php:196
|
5321 |
msgid "MySQL version"
|
5322 |
msgstr ""
|
5323 |
|
5324 |
+
#: views/pages/tools/status.php:197
|
5325 |
msgid "The version of MySQL installed on your hosting server."
|
5326 |
msgstr ""
|
5327 |
|
5328 |
+
#: views/pages/tools/status.php:204
|
|
|
5329 |
msgid "%1$s - We recommend a minimum MySQL version of 5.6. See: %2$s"
|
5330 |
msgstr ""
|
5331 |
|
5332 |
+
#: views/pages/tools/status.php:204
|
5333 |
msgid "WordPress requirements"
|
5334 |
msgstr ""
|
5335 |
|
5336 |
+
#: views/pages/tools/status.php:214
|
5337 |
msgid "Max upload size"
|
5338 |
msgstr ""
|
5339 |
|
5340 |
+
#: views/pages/tools/status.php:215
|
5341 |
msgid "The largest filesize that can be uploaded to your WordPress installation."
|
5342 |
msgstr ""
|
5343 |
|
5344 |
+
#: views/pages/tools/status.php:219
|
5345 |
msgid "Default timezone is UTC"
|
5346 |
msgstr ""
|
5347 |
|
5348 |
+
#: views/pages/tools/status.php:220
|
5349 |
msgid "The default timezone for your server."
|
5350 |
msgstr ""
|
5351 |
|
5352 |
#. translators: %s: default timezone..
|
5353 |
+
#: views/pages/tools/status.php:225
|
5354 |
msgid "Default timezone is %s - it should be UTC"
|
5355 |
msgstr ""
|
5356 |
|
5357 |
+
#: views/pages/tools/status.php:233
|
5358 |
msgid "fsockopen/cURL"
|
5359 |
msgstr ""
|
5360 |
|
5361 |
+
#: views/pages/tools/status.php:234
|
5362 |
msgid "Payment gateways can use cURL to communicate with remote servers to authorize payments, other plugins may also use it when communicating with remote services."
|
5363 |
msgstr ""
|
5364 |
|
5365 |
+
#: views/pages/tools/status.php:242
|
5366 |
msgid "Your server does not have fsockopen or cURL enabled - PayPal IPN and other scripts which communicate with other servers will not work. Contact your hosting provider."
|
5367 |
msgstr ""
|
5368 |
|
5369 |
+
#: views/pages/tools/status.php:249
|
5370 |
msgid "DOMDocument"
|
5371 |
msgstr ""
|
5372 |
|
5373 |
+
#: views/pages/tools/status.php:250
|
5374 |
msgid "HTML/Multipart emails use DOMDocument to generate inline CSS in templates."
|
5375 |
msgstr ""
|
5376 |
|
5377 |
+
#: views/pages/tools/status.php:259
|
|
|
5378 |
msgid "Your server does not have the %s class enabled - HTML/Multipart emails, and also some extensions, will not work without DOMDocument."
|
5379 |
msgstr ""
|
5380 |
|
5381 |
+
#: views/pages/tools/status.php:266
|
5382 |
msgid "GZip"
|
5383 |
msgstr ""
|
5384 |
|
5385 |
+
#: views/pages/tools/status.php:267
|
5386 |
msgid "GZip (gzopen) is used to open the GEOIP database from MaxMind."
|
5387 |
msgstr ""
|
5388 |
|
5389 |
+
#: views/pages/tools/status.php:276
|
|
|
5390 |
msgid "Your server does not support the %s function - this is required to use the GeoIP database from MaxMind."
|
5391 |
msgstr ""
|
5392 |
|
5393 |
+
#: views/pages/tools/status.php:283
|
5394 |
msgid "Multibyte string"
|
5395 |
msgstr ""
|
5396 |
|
5397 |
+
#: views/pages/tools/status.php:284
|
5398 |
msgid "Multibyte String (mbstring) is used to convert character encoding, like for emails or converting characters to lowercase."
|
5399 |
msgstr ""
|
5400 |
|
5401 |
+
#: views/pages/tools/status.php:295
|
|
|
5402 |
msgid "Your server does not support the %s functions - this is required for better character encoding. Some fallbacks will be used instead for it."
|
5403 |
msgstr ""
|
5404 |
|
5405 |
+
#: views/pages/tools/tutor_pages.php:10
|
5406 |
msgid "Page Name"
|
5407 |
msgstr ""
|
5408 |
|
5409 |
+
#: views/pages/tools/tutor_pages.php:37
|
5410 |
msgid " Page not set"
|
5411 |
msgstr ""
|
5412 |
|
5413 |
+
#: views/pages/tools/tutor_pages.php:44
|
5414 |
msgid " Page deleted, please set new one"
|
5415 |
msgstr ""
|
5416 |
|
5417 |
+
#: views/pages/tools/tutor_pages.php:51
|
5418 |
msgid "Page visibility is not public"
|
5419 |
msgstr ""
|
5420 |
|
5421 |
+
#: views/pages/tools/tutor_pages.php:78
|
5422 |
msgid "Re-Generate Tutor Pages"
|
5423 |
msgstr ""
|
5424 |
|
5425 |
+
#: views/pages/tools/tutor_pages.php:83
|
5426 |
msgid "Note: This tool will install all the missing Tutor pages. Pages already defined and set up will not be replaced."
|
5427 |
msgstr ""
|
5428 |
|
5442 |
msgid " Complete"
|
5443 |
msgstr ""
|
5444 |
|
5445 |
+
#: templates/single/course/enrolled/nav.php:27
|
5446 |
msgid "Course Page"
|
5447 |
msgstr ""
|
5448 |
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: lms, course, elearning, education, learning management system
|
|
5 |
Requires at least: 5.3
|
6 |
Tested up to: 5.8
|
7 |
Requires PHP: 7.0
|
8 |
-
Stable tag: 1.9.
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -241,6 +241,10 @@ Tutor enables you to use any third party plugins without facing any compatibilit
|
|
241 |
|
242 |
== Changelog ==
|
243 |
|
|
|
|
|
|
|
|
|
244 |
= 1.9.12 - December 14, 2021 =
|
245 |
|
246 |
Update: Security Update
|
5 |
Requires at least: 5.3
|
6 |
Tested up to: 5.8
|
7 |
Requires PHP: 7.0
|
8 |
+
Stable tag: 1.9.13
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
241 |
|
242 |
== Changelog ==
|
243 |
|
244 |
+
= 1.9.13 - January 10, 2022 =
|
245 |
+
|
246 |
+
Update: Security Update
|
247 |
+
|
248 |
= 1.9.12 - December 14, 2021 =
|
249 |
|
250 |
Update: Security Update
|
templates/archive-course.php
CHANGED
@@ -24,7 +24,7 @@ if ($course_filter && count($supported_filters)) {
|
|
24 |
<?php tutor_load_template('course-filter.filters'); ?>
|
25 |
</div>
|
26 |
<div>
|
27 |
-
<div id="tutor-course-filter-loop-container" class="<?php tutor_container_classes(); ?> tutor-course-filter-loop-container" data-column_per_row="<?php echo tutor_utils()->get_option( 'courses_col_per_row', 4 ); ?>">
|
28 |
<?php tutor_load_template('archive-course-init'); ?>
|
29 |
</div><!-- .wrap -->
|
30 |
</div>
|
24 |
<?php tutor_load_template('course-filter.filters'); ?>
|
25 |
</div>
|
26 |
<div>
|
27 |
+
<div id="tutor-course-filter-loop-container" class="<?php tutor_container_classes(); ?> tutor-course-filter-loop-container" data-column_per_row="<?php echo esc_attr( tutor_utils()->get_option( 'courses_col_per_row', 4 ) ); ?>">
|
28 |
<?php tutor_load_template('archive-course-init'); ?>
|
29 |
</div><!-- .wrap -->
|
30 |
</div>
|
templates/course-filter/filters.php
CHANGED
@@ -19,7 +19,7 @@
|
|
19 |
if ( in_array( 'search', $supported_filters ) ) {
|
20 |
?>
|
21 |
<div class="tutor-course-search-field">
|
22 |
-
<input type="text" name="keyword" placeholder="<?php
|
23 |
<i class="tutor-icon-magnifying-glass-1"></i>
|
24 |
</div>
|
25 |
<?php
|
@@ -71,13 +71,13 @@
|
|
71 |
if ( ! $is_membership && in_array( 'price_type', $supported_filters ) ) {
|
72 |
?>
|
73 |
<div>
|
74 |
-
<h4><?php
|
75 |
<?php
|
76 |
foreach ( $filter_prices as $value => $title ) {
|
77 |
?>
|
78 |
<label>
|
79 |
<input type="checkbox" name="tutor-course-filter-price" value="<?php echo esc_attr( $value ); ?>"/>
|
80 |
-
<?php echo
|
81 |
</label>
|
82 |
<?php
|
83 |
}
|
19 |
if ( in_array( 'search', $supported_filters ) ) {
|
20 |
?>
|
21 |
<div class="tutor-course-search-field">
|
22 |
+
<input type="text" name="keyword" placeholder="<?php _e( 'Search...', 'tutor' ); ?>"/>
|
23 |
<i class="tutor-icon-magnifying-glass-1"></i>
|
24 |
</div>
|
25 |
<?php
|
71 |
if ( ! $is_membership && in_array( 'price_type', $supported_filters ) ) {
|
72 |
?>
|
73 |
<div>
|
74 |
+
<h4><?php _e( 'Price', 'tutor' ); ?></h4>
|
75 |
<?php
|
76 |
foreach ( $filter_prices as $value => $title ) {
|
77 |
?>
|
78 |
<label>
|
79 |
<input type="checkbox" name="tutor-course-filter-price" value="<?php echo esc_attr( $value ); ?>"/>
|
80 |
+
<?php echo $title; ?>
|
81 |
</label>
|
82 |
<?php
|
83 |
}
|
templates/dashboard.php
CHANGED
@@ -11,206 +11,214 @@
|
|
11 |
* @version 1.4.3
|
12 |
*/
|
13 |
|
14 |
-
$is_by_short_code = isset($is_shortcode) && $is_shortcode===true;
|
15 |
-
if(
|
16 |
-
|
17 |
}
|
18 |
|
19 |
global $wp_query;
|
20 |
|
21 |
$dashboard_page_slug = '';
|
22 |
$dashboard_page_name = '';
|
23 |
-
if (isset($wp_query->query_vars['tutor_dashboard_page']) && $wp_query->query_vars['tutor_dashboard_page']) {
|
24 |
-
|
25 |
-
|
26 |
}
|
27 |
/**
|
28 |
* Getting dashboard sub pages
|
29 |
*/
|
30 |
-
if (isset($wp_query->query_vars['tutor_dashboard_sub_page']) && $wp_query->query_vars['tutor_dashboard_sub_page']) {
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
}
|
36 |
|
37 |
-
$user_id
|
38 |
-
$user
|
39 |
-
$enable_profile_completion = tutils()->get_option('enable_profile_completion');
|
40 |
|
41 |
-
do_action('tutor_dashboard/before/wrap');
|
42 |
?>
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
|
213 |
<?php
|
214 |
-
if(
|
215 |
-
|
216 |
-
}
|
11 |
* @version 1.4.3
|
12 |
*/
|
13 |
|
14 |
+
$is_by_short_code = isset( $is_shortcode ) && $is_shortcode === true;
|
15 |
+
if ( ! $is_by_short_code && ! defined( 'OTLMS_VERSION' ) ) {
|
16 |
+
get_header();
|
17 |
}
|
18 |
|
19 |
global $wp_query;
|
20 |
|
21 |
$dashboard_page_slug = '';
|
22 |
$dashboard_page_name = '';
|
23 |
+
if ( isset( $wp_query->query_vars['tutor_dashboard_page'] ) && $wp_query->query_vars['tutor_dashboard_page'] ) {
|
24 |
+
$dashboard_page_slug = $wp_query->query_vars['tutor_dashboard_page'];
|
25 |
+
$dashboard_page_name = $wp_query->query_vars['tutor_dashboard_page'];
|
26 |
}
|
27 |
/**
|
28 |
* Getting dashboard sub pages
|
29 |
*/
|
30 |
+
if ( isset( $wp_query->query_vars['tutor_dashboard_sub_page'] ) && $wp_query->query_vars['tutor_dashboard_sub_page'] ) {
|
31 |
+
$dashboard_page_name = $wp_query->query_vars['tutor_dashboard_sub_page'];
|
32 |
+
if ( $dashboard_page_slug ) {
|
33 |
+
$dashboard_page_name = $dashboard_page_slug . '/' . $dashboard_page_name;
|
34 |
+
}
|
35 |
}
|
36 |
|
37 |
+
$user_id = get_current_user_id();
|
38 |
+
$user = get_user_by( 'ID', $user_id );
|
39 |
+
$enable_profile_completion = tutils()->get_option( 'enable_profile_completion' );
|
40 |
|
41 |
+
do_action( 'tutor_dashboard/before/wrap' );
|
42 |
?>
|
43 |
|
44 |
+
<div class="tutor-wrap tutor-dashboard tutor-dashboard-student">
|
45 |
+
<div class="tutor-container">
|
46 |
+
<div class="tutor-row">
|
47 |
+
<div class="tutor-col-12">
|
48 |
+
<div class="tutor-dashboard-header">
|
49 |
+
<div class="tutor-dashboard-header-avatar">
|
50 |
+
<img src="<?php echo esc_url( get_avatar_url( $user_id, array( 'size' => 150 ) ) ); ?>" />
|
51 |
+
</div>
|
52 |
+
<div class="tutor-dashboard-header-info">
|
53 |
+
<div class="tutor-dashboard-header-display-name">
|
54 |
+
<h4>
|
55 |
+
<strong>
|
56 |
+
<?php echo $user->display_name; ?>
|
57 |
+
</strong>
|
58 |
+
</h4>
|
59 |
+
</div>
|
60 |
+
<?php $instructor_rating = tutils()->get_instructor_ratings( $user->ID ); ?>
|
61 |
+
<?php
|
62 |
+
if ( current_user_can( tutor()->instructor_role ) ) {
|
63 |
+
?>
|
64 |
+
<div class="tutor-dashboard-header-stats">
|
65 |
+
<div class="tutor-dashboard-header-ratings">
|
66 |
+
<?php tutils()->star_rating_generator( $instructor_rating->rating_avg ); ?>
|
67 |
+
<span><?php echo esc_html( $instructor_rating->rating_avg ); ?></span>
|
68 |
+
<span> (<?php echo sprintf( __( '%d Ratings', 'tutor' ), $instructor_rating->rating_count ); ?>) </span>
|
69 |
+
</div>
|
70 |
+
<!--<div class="tutor-dashboard-header-notifications">
|
71 |
+
<?php /*_e('Notification'); */ ?> <span>9</span>
|
72 |
+
</div>-->
|
73 |
+
</div>
|
74 |
+
<?php } ?>
|
75 |
+
</div>
|
76 |
+
|
77 |
+
<div class="tutor-dashboard-header-button">
|
78 |
+
<?php
|
79 |
+
do_action( 'tutor_dashboard/before_header_button' );
|
80 |
+
$instructor_status = tutor_utils()->instructor_status();
|
81 |
+
$instructor_status = is_string( $instructor_status ) ? strtolower( $instructor_status ) : '';
|
82 |
+
$rejected_on = get_user_meta( $user->ID, '_is_tutor_instructor_rejected', true );
|
83 |
+
$info_style = 'vertical-align: middle; margin-right: 7px;';
|
84 |
+
$info_message_style = 'display:inline-block; color:#7A7A7A; font-size: 15px;';
|
85 |
+
|
86 |
+
ob_start();
|
87 |
+
if ( tutils()->get_option( 'enable_become_instructor_btn' ) ) {
|
88 |
+
?>
|
89 |
+
<a id="tutor-become-instructor-button" style="vertical-align:middle" class="tutor-btn bordered-btn" href="<?php echo esc_url( tutils()->instructor_register_url() ); ?>">
|
90 |
+
<i class="tutor-icon-man-user"></i> <?php _e( 'Become an instructor', 'tutor' ); ?>
|
91 |
+
</a>
|
92 |
+
<?php
|
93 |
+
}
|
94 |
+
$become_button = ob_get_clean();
|
95 |
+
|
96 |
+
if ( current_user_can( tutor()->instructor_role ) ) {
|
97 |
+
$course_type = tutor()->course_post_type;
|
98 |
+
?>
|
99 |
+
<a class="tutor-btn bordered-btn" href="<?php echo esc_url( apply_filters( 'frontend_course_create_url', admin_url( 'post-new.php?post_type=' . tutor()->course_post_type ) ) ); ?>">
|
100 |
+
<i class="tutor-icon-checkbox-pen-outline"></i> <?php _e( 'Add A New Course', 'tutor' ); ?>
|
101 |
+
</a>
|
102 |
+
<?php
|
103 |
+
} elseif ( $instructor_status == 'pending' ) {
|
104 |
+
$on = get_user_meta( $user->ID, '_is_tutor_instructor', true );
|
105 |
+
$on = date( 'd F, Y', $on );
|
106 |
+
echo '<span style="' . $info_message_style . '">
|
107 |
+
<i class="dashicons dashicons-info" style="color:#E53935; ' . $info_style . '"></i>'.
|
108 |
+
__( 'Your Application is pending from', 'tutor' ).
|
109 |
+
' <b>'.
|
110 |
+
$on.
|
111 |
+
'</b>'.
|
112 |
+
'</span>';
|
113 |
+
} elseif ( $rejected_on || $instructor_status !== 'blocked' ) {
|
114 |
+
echo $become_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
115 |
+
}
|
116 |
+
?>
|
117 |
+
</div>
|
118 |
+
|
119 |
+
<?php
|
120 |
+
if ( $instructor_status != 'approved'
|
121 |
+
&& $instructor_status != 'pending'
|
122 |
+
&& $rejected_on
|
123 |
+
&& get_user_meta( get_current_user_id(), 'tutor_instructor_show_rejection_message', true )
|
124 |
+
) {
|
125 |
+
?>
|
126 |
+
<div class="tutor-instructor-rejection-notice">
|
127 |
+
<?php
|
128 |
+
$on = date( 'd F, Y', $rejected_on );
|
129 |
+
|
130 |
+
echo '<span>
|
131 |
+
<i class="dashicons dashicons-info"></i>',
|
132 |
+
__( 'Your application to become an instructor was rejected on', 'tutor' ) . ' ' . $on .
|
133 |
+
'</span>
|
134 |
+
<a href="?tutor_action=hide_instructor_notice">
|
135 |
+
✕
|
136 |
+
</a>';
|
137 |
+
?>
|
138 |
+
</div>
|
139 |
+
<?php
|
140 |
+
}
|
141 |
+
?>
|
142 |
+
</div>
|
143 |
+
</div>
|
144 |
+
<?php do_action( 'tutor_dashboard/notification_area' ); ?>
|
145 |
+
</div>
|
146 |
+
|
147 |
+
<div class="tutor-row">
|
148 |
+
<div class="tutor-col-3 tutor-dashboard-left-menu">
|
149 |
+
<ul class="tutor-dashboard-permalinks">
|
150 |
+
<?php
|
151 |
+
$dashboard_pages = tutils()->tutor_dashboard_nav_ui_items();
|
152 |
+
foreach ( $dashboard_pages as $dashboard_key => $dashboard_page ) {
|
153 |
+
$menu_title = $dashboard_page;
|
154 |
+
$menu_link = tutils()->get_tutor_dashboard_page_permalink( $dashboard_key );
|
155 |
+
$separator = false;
|
156 |
+
if ( is_array( $dashboard_page ) ) {
|
157 |
+
$menu_title = tutils()->array_get( 'title', $dashboard_page );
|
158 |
+
// Add new menu item property "url" for custom link
|
159 |
+
if ( isset( $dashboard_page['url'] ) ) {
|
160 |
+
$menu_link = $dashboard_page['url'];
|
161 |
+
}
|
162 |
+
if ( isset( $dashboard_page['type'] ) && $dashboard_page['type'] == 'separator' ) {
|
163 |
+
$separator = true;
|
164 |
+
}
|
165 |
+
}
|
166 |
+
if ( $separator ) {
|
167 |
+
echo '<li class="tutor-dashboard-menu-divider"></li>';
|
168 |
+
if ( $menu_title ) {
|
169 |
+
echo '<li class="tutor-dashboard-menu-divider-header">' . $menu_title . '</li>';
|
170 |
+
}
|
171 |
+
} else {
|
172 |
+
$li_class = 'tutor-dashboard-menu-' . $dashboard_key;
|
173 |
+
if ( $dashboard_key === 'index' ) {
|
174 |
+
$dashboard_key = '';
|
175 |
+
}
|
176 |
+
$active_class = $dashboard_key == $dashboard_page_slug ? 'active' : '';
|
177 |
+
echo '<li class="' . $li_class . ' ' . $active_class . '"><a href="' . esc_url( $menu_link ) . '"> ' . $menu_title . ' </a> </li>';
|
178 |
+
}
|
179 |
+
}
|
180 |
+
?>
|
181 |
+
</ul>
|
182 |
+
</div>
|
183 |
+
|
184 |
+
<div class="tutor-col-9">
|
185 |
+
<div class="tutor-dashboard-content">
|
186 |
+
<?php
|
187 |
+
|
188 |
+
if ( $dashboard_page_name ) {
|
189 |
+
do_action( 'tutor_load_dashboard_template_before', $dashboard_page_name );
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Load dashboard template part from other location
|
193 |
+
*
|
194 |
+
* this filter is basically added for adding templates from respective addons
|
195 |
+
*
|
196 |
+
* @since version 1.9.3
|
197 |
+
*/
|
198 |
+
$other_location = '';
|
199 |
+
$from_other_location = apply_filters( 'load_dashboard_template_part_from_other_location', $other_location );
|
200 |
+
|
201 |
+
if ( $from_other_location == '' ) {
|
202 |
+
tutor_load_template( 'dashboard.' . $dashboard_page_name );
|
203 |
+
} else {
|
204 |
+
// load template from other location full abspath
|
205 |
+
include_once $from_other_location;
|
206 |
+
}
|
207 |
+
|
208 |
+
do_action( 'tutor_load_dashboard_template_before', $dashboard_page_name );
|
209 |
+
} else {
|
210 |
+
tutor_load_template( 'dashboard.dashboard' );
|
211 |
+
}
|
212 |
+
?>
|
213 |
+
</div>
|
214 |
+
</div>
|
215 |
+
</div>
|
216 |
+
</div>
|
217 |
+
</div>
|
218 |
+
|
219 |
+
<?php do_action( 'tutor_dashboard/after/wrap' ); ?>
|
220 |
|
221 |
<?php
|
222 |
+
if ( ! $is_by_short_code && ! defined( 'OTLMS_VERSION' ) ) {
|
223 |
+
get_footer();
|
224 |
+
}
|
templates/dashboard/announcements.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
-
if (!defined('ABSPATH'))
|
3 |
-
|
|
|
4 |
/**
|
5 |
* Template for displaying Announcements
|
6 |
*
|
@@ -12,185 +13,187 @@ if (!defined('ABSPATH'))
|
|
12 |
* @package TutorLMS/Templates
|
13 |
* @version 1.7.9
|
14 |
*/
|
15 |
-
$per_page
|
16 |
-
$paged
|
17 |
|
18 |
-
$order_filter
|
19 |
-
$search_filter
|
20 |
-
//announcement's parent
|
21 |
-
$course_id
|
22 |
-
$date_filter
|
23 |
|
24 |
-
$year
|
25 |
-
$month
|
26 |
-
$day
|
27 |
|
28 |
$args = array(
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
|
38 |
);
|
39 |
-
if (!empty($date_filter)) {
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
}
|
48 |
-
if (!current_user_can('administrator')) {
|
49 |
-
|
50 |
}
|
51 |
-
$the_query = new WP_Query($args);
|
52 |
|
53 |
-
//get courses
|
54 |
-
$courses
|
55 |
$image_base = tutor()->url . '/assets/images/';
|
56 |
?>
|
57 |
|
58 |
<div class="tutor-dashboard-content-inner">
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
</div>
|
81 |
<!--sorting-->
|
82 |
<div class="tutor-dashboard-announcement-sorting-wrap">
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
</div>
|
117 |
<!--sorting end-->
|
118 |
<div class="tutor-announcement-table-wrap">
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
|
174 |
</div>
|
175 |
|
176 |
<!--pagination-->
|
177 |
<div class="tutor-pagination">
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
189 |
</div>
|
190 |
<!--pagination end-->
|
191 |
|
192 |
<?php
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
?>
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
/**
|
6 |
* Template for displaying Announcements
|
7 |
*
|
13 |
* @package TutorLMS/Templates
|
14 |
* @version 1.7.9
|
15 |
*/
|
16 |
+
$per_page = 10;
|
17 |
+
$paged = max( 1, tutor_utils()->avalue_dot( 'current_page', tutor_sanitize_data($_GET) ) );
|
18 |
|
19 |
+
$order_filter = isset( $_GET['order'] ) ? sanitize_text_field( $_GET['order'] ) : 'DESC';
|
20 |
+
$search_filter = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
|
21 |
+
// announcement's parent
|
22 |
+
$course_id = isset( $_GET['course-id'] ) ? sanitize_text_field( $_GET['course-id'] ) : '';
|
23 |
+
$date_filter = isset( $_GET['date'] ) ? sanitize_text_field( $_GET['date'] ) : '';
|
24 |
|
25 |
+
$year = date( 'Y', strtotime( $date_filter ) );
|
26 |
+
$month = date( 'm', strtotime( $date_filter ) );
|
27 |
+
$day = date( 'd', strtotime( $date_filter ) );
|
28 |
|
29 |
$args = array(
|
30 |
+
'post_type' => 'tutor_announcements',
|
31 |
+
'post_status' => 'publish',
|
32 |
+
's' => sanitize_text_field( $search_filter ),
|
33 |
+
'post_parent' => sanitize_text_field( $course_id ),
|
34 |
+
'posts_per_page' => sanitize_text_field( $per_page ),
|
35 |
+
'paged' => sanitize_text_field( $paged ),
|
36 |
+
'orderBy' => 'ID',
|
37 |
+
'order' => sanitize_text_field( $order_filter ),
|
38 |
|
39 |
);
|
40 |
+
if ( ! empty( $date_filter ) ) {
|
41 |
+
$args['date_query'] = array(
|
42 |
+
array(
|
43 |
+
'year' => $year,
|
44 |
+
'month' => $month,
|
45 |
+
'day' => $day,
|
46 |
+
),
|
47 |
+
);
|
48 |
}
|
49 |
+
if ( ! current_user_can( 'administrator' ) ) {
|
50 |
+
$args['author'] = get_current_user_id();
|
51 |
}
|
52 |
+
$the_query = new WP_Query( $args );
|
53 |
|
54 |
+
// get courses
|
55 |
+
$courses = ( current_user_can( 'administrator' ) ) ? tutils()->get_courses() : tutils()->get_courses_by_instructor();
|
56 |
$image_base = tutor()->url . '/assets/images/';
|
57 |
?>
|
58 |
|
59 |
<div class="tutor-dashboard-content-inner">
|
60 |
+
<h4><?php echo __( 'Announcement', 'tutor' ); ?></h4>
|
61 |
+
<!--notice-->
|
62 |
+
<div class="tutor-component-three-col-action new-announcement-wrap">
|
63 |
+
<div class="tutor-announcement-big-icon">
|
64 |
+
<i class="tutor-icon-speaker"></i>
|
65 |
+
</div>
|
66 |
+
<div>
|
67 |
+
<small><?php _e( 'Create Announcement', 'tutor' ); ?></small>
|
68 |
+
<p>
|
69 |
+
<strong>
|
70 |
+
<?php _e( 'Notify all students of your course', 'tutor' ); ?>
|
71 |
+
</strong>
|
72 |
+
</p>
|
73 |
+
</div>
|
74 |
+
<div class="new-announcement-button">
|
75 |
+
<button type="button" class="tutor-btn tutor-announcement-add-new">
|
76 |
+
<?php _e( 'Add New Announcement', 'tutor' ); ?>
|
77 |
+
</button>
|
78 |
+
</div>
|
79 |
+
</div>
|
80 |
+
<!--notice end-->
|
81 |
</div>
|
82 |
<!--sorting-->
|
83 |
<div class="tutor-dashboard-announcement-sorting-wrap">
|
84 |
+
<div class="tutor-form-group">
|
85 |
+
<label for="">
|
86 |
+
<?php _e( 'Courses', 'tutor' ); ?>
|
87 |
+
</label>
|
88 |
+
<select class="tutor-report-category tutor-announcement-course-sorting ignore-nice-select">
|
89 |
+
|
90 |
+
<option value=""><?php _e( 'All', 'tutor' ); ?></option>
|
91 |
+
|
92 |
+
<?php if ( $courses ) : ?>
|
93 |
+
<?php foreach ( $courses as $course ) : ?>
|
94 |
+
<option value="<?php echo $course->ID; ?>" <?php selected( $course_id, $course->ID, 'selected' ); ?>>
|
95 |
+
<?php echo $course->post_title; ?>
|
96 |
+
</option>
|
97 |
+
<?php endforeach; ?>
|
98 |
+
<?php else : ?>
|
99 |
+
<option value=""><?php _e( 'No course found', 'tutor' ); ?></option>
|
100 |
+
<?php endif; ?>
|
101 |
+
</select>
|
102 |
+
</div>
|
103 |
+
|
104 |
+
<div class="tutor-form-group">
|
105 |
+
<label><?php _e( 'Sort By', 'tutor' ); ?></label>
|
106 |
+
<select class="tutor-announcement-order-sorting ignore-nice-select">
|
107 |
+
<option <?php selected( $order_filter, 'ASC' ); ?>><?php _e( 'ASC', 'tutor' ); ?></option>
|
108 |
+
<option <?php selected( $order_filter, 'DESC' ); ?>><?php _e( 'DESC', 'tutor' ); ?></option>
|
109 |
+
</select>
|
110 |
+
</div>
|
111 |
+
|
112 |
+
<div class="tutor-form-group tutor-announcement-datepicker">
|
113 |
+
<label><?php _e( 'Date', 'tutor' ); ?></label>
|
114 |
+
<input type="text" class="tutor_date_picker tutor-announcement-date-sorting" id="tutor-announcement-datepicker" value="<?php echo '' !== $date_filter ? tutor_get_formated_date( get_option( 'date_format' ), $date_filter ) : ''; ?>" placeholder="<?php echo get_option( 'date_format' ); ?>" autocomplete="off" />
|
115 |
+
<i class="tutor-icon-calendar"></i>
|
116 |
+
</div>
|
117 |
</div>
|
118 |
<!--sorting end-->
|
119 |
<div class="tutor-announcement-table-wrap">
|
120 |
+
<table class="tutor-dashboard-announcement-table" width="100%">
|
121 |
+
<thead>
|
122 |
+
<tr>
|
123 |
+
<th style="width:24%"><?php _e( 'Date', 'tutor' ); ?></th>
|
124 |
+
<th style="text-align:left"><?php _e( 'Announcements', 'tutor' ); ?></th>
|
125 |
+
</tr>
|
126 |
+
</thead>
|
127 |
+
<tbody>
|
128 |
+
<?php if ( $the_query->have_posts() ) : ?>
|
129 |
+
<?php foreach ( $the_query->posts as $post ) : ?>
|
130 |
+
<?php
|
131 |
+
$course = get_post( $post->post_parent );
|
132 |
+
$dateObj = date_create( $post->post_date );
|
133 |
+
$date_format = date_format( $dateObj, 'j M, Y,<\b\r>h:i a' );
|
134 |
+
?>
|
135 |
+
<tr id="tutor-announcement-tr-<?php echo $post->ID; ?>">
|
136 |
+
<td class="tutor-announcement-date"><?php echo $date_format; ?></td>
|
137 |
+
<td class="tutor-announcement-content-wrap">
|
138 |
+
<div class="tutor-announcement-content">
|
139 |
+
<h4><?php echo esc_html( $post->post_title ); ?></h4>
|
140 |
+
<p><?php echo $course ? esc_attr( $course->post_title ) : ''; ?></p>
|
141 |
+
</div>
|
142 |
+
<div class="tutor-announcement-buttons">
|
143 |
+
<li>
|
144 |
+
<button type="button" course-name="<?php echo esc_attr( $course->post_title ); ?>" announcement-date="<?php echo esc_attr( $date_format ); ?>" announcement-title="<?php echo esc_attr( $post->post_title ); ?>" announcement-summary="<?php echo esc_attr( $post->post_content ); ?>" course-id="<?php echo $post->post_parent; ?>" announcement-id="<?php echo $post->ID; ?>" class="tutor-btn bordered-btn tutor-announcement-details">
|
145 |
+
<?php _e( 'Details', 'tutor' ); ?>
|
146 |
+
</button>
|
147 |
+
</li>
|
148 |
+
<li class="tutor-dropdown">
|
149 |
+
<i class="tutor-icon-action"></i>
|
150 |
+
<ul class="tutor-dropdown-menu">
|
151 |
+
<li announcement-title="<?php echo esc_attr( $post->post_title ); ?>" announcement-summary="<?php echo esc_attr( $post->post_content ); ?>" course-id="<?php echo $post->post_parent; ?>" announcement-id="<?php echo $post->ID; ?>" class="tutor-announcement-edit">
|
152 |
+
<i class="tutor-icon-pencil"></i>
|
153 |
+
<?php _e( 'Edit', 'tutor' ); ?>
|
154 |
+
</li>
|
155 |
+
<li class="tutor-announcement-delete" announcement-id="<?php echo $post->ID; ?>">
|
156 |
+
<i class="tutor-icon-garbage"></i>
|
157 |
+
<?php _e( 'Delete', 'tutor' ); ?>
|
158 |
+
</li>
|
159 |
+
</ul>
|
160 |
+
</li>
|
161 |
+
</div>
|
162 |
+
</td>
|
163 |
+
</tr>
|
164 |
+
<?php endforeach; ?>
|
165 |
+
<?php else : ?>
|
166 |
+
<tr>
|
167 |
+
<td colspan="2">
|
168 |
+
<?php _e( 'Announcements not found', 'tutor' ); ?>
|
169 |
+
</td>
|
170 |
+
</tr>
|
171 |
+
<?php endif; ?>
|
172 |
+
</tbody>
|
173 |
+
</table>
|
174 |
|
175 |
</div>
|
176 |
|
177 |
<!--pagination-->
|
178 |
<div class="tutor-pagination">
|
179 |
+
<?php
|
180 |
+
$big = 999999999; // need an unlikely integer
|
181 |
+
|
182 |
+
echo paginate_links(
|
183 |
+
array(
|
184 |
+
|
185 |
+
'format' => '?current_page=%#%',
|
186 |
+
'current' => $paged,
|
187 |
+
'total' => $the_query->max_num_pages,
|
188 |
+
)
|
189 |
+
);
|
190 |
+
|
191 |
+
?>
|
192 |
</div>
|
193 |
<!--pagination end-->
|
194 |
|
195 |
<?php
|
196 |
+
require 'announcements/create.php';
|
197 |
+
require 'announcements/update.php';
|
198 |
+
require 'announcements/details.php';
|
199 |
?>
|
templates/dashboard/announcements/create.php
CHANGED
@@ -21,12 +21,12 @@
|
|
21 |
<select class="ignore-nice-select" name="tutor_announcement_course" id="" required>
|
22 |
<?php if ( $courses ) : ?>
|
23 |
<?php foreach ( $courses as $course ) : ?>
|
24 |
-
<option value="<?php echo
|
25 |
<?php echo esc_html( $course->post_title ); ?>
|
26 |
</option>
|
27 |
<?php endforeach; ?>
|
28 |
<?php else : ?>
|
29 |
-
<option value=""><?php echo
|
30 |
<?php endif; ?>
|
31 |
</select>
|
32 |
</div>
|
@@ -34,13 +34,13 @@
|
|
34 |
<label>
|
35 |
<?php esc_html_e( 'Announcement Title', 'tutor' ); ?>
|
36 |
</label>
|
37 |
-
<input type="text" name="tutor_announcement_title" value="" placeholder="<?php echo
|
38 |
</div>
|
39 |
<div class="tutor-form-group">
|
40 |
<label for="tutor_announcement_course">
|
41 |
<?php esc_html_e( 'Summary', 'tutor' ); ?>
|
42 |
</label>
|
43 |
-
<textarea rows="6" type="text" name="tutor_announcement_summary" value="" placeholder="<?php echo
|
44 |
</div>
|
45 |
|
46 |
<?php do_action( 'tutor_announcement_editor/after' ); ?>
|
21 |
<select class="ignore-nice-select" name="tutor_announcement_course" id="" required>
|
22 |
<?php if ( $courses ) : ?>
|
23 |
<?php foreach ( $courses as $course ) : ?>
|
24 |
+
<option value="<?php echo $course->ID; ?>">
|
25 |
<?php echo esc_html( $course->post_title ); ?>
|
26 |
</option>
|
27 |
<?php endforeach; ?>
|
28 |
<?php else : ?>
|
29 |
+
<option value=""><?php echo __( 'No course found', 'tutor' ); ?></option>
|
30 |
<?php endif; ?>
|
31 |
</select>
|
32 |
</div>
|
34 |
<label>
|
35 |
<?php esc_html_e( 'Announcement Title', 'tutor' ); ?>
|
36 |
</label>
|
37 |
+
<input type="text" name="tutor_announcement_title" value="" placeholder="<?php echo __( 'Announcement title', 'tutor' ); ?>" required>
|
38 |
</div>
|
39 |
<div class="tutor-form-group">
|
40 |
<label for="tutor_announcement_course">
|
41 |
<?php esc_html_e( 'Summary', 'tutor' ); ?>
|
42 |
</label>
|
43 |
+
<textarea rows="6" type="text" name="tutor_announcement_summary" value="" placeholder="<?php echo __( 'Summary...', 'tutor' ); ?>" required></textarea>
|
44 |
</div>
|
45 |
|
46 |
<?php do_action( 'tutor_announcement_editor/after' ); ?>
|
templates/dashboard/announcements/update.php
CHANGED
@@ -22,7 +22,7 @@
|
|
22 |
<select class="ignore-nice-select" name="tutor_announcement_course" id="tutor-announcement-course-id" required>
|
23 |
<?php if ( $courses ) : ?>
|
24 |
<?php foreach ( $courses as $course ) : ?>
|
25 |
-
<option value="<?php echo
|
26 |
<?php echo esc_html( $course->post_title ); ?>
|
27 |
</option>
|
28 |
<?php endforeach; ?>
|
22 |
<select class="ignore-nice-select" name="tutor_announcement_course" id="tutor-announcement-course-id" required>
|
23 |
<?php if ( $courses ) : ?>
|
24 |
<?php foreach ( $courses as $course ) : ?>
|
25 |
+
<option value="<?php echo $course->ID; ?>">
|
26 |
<?php echo esc_html( $course->post_title ); ?>
|
27 |
</option>
|
28 |
<?php endforeach; ?>
|
templates/dashboard/assignments.php
CHANGED
@@ -14,110 +14,119 @@
|
|
14 |
|
15 |
global $wpdb;
|
16 |
|
17 |
-
$per_page
|
18 |
-
$current_page
|
19 |
-
$offset
|
20 |
|
21 |
-
$course_id
|
22 |
-
$order_filter
|
23 |
-
$date_filter
|
24 |
|
25 |
-
$current_user
|
26 |
-
$assignments
|
27 |
-
$courses
|
28 |
|
29 |
?>
|
30 |
|
31 |
<div class="tutor-dashboard-announcement-sorting-wrap">
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
</div>
|
64 |
|
65 |
<?php
|
66 |
|
67 |
-
if ($assignments->count) {
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
<tr>
|
91 |
-
<td>
|
92 |
-
<h4><?php echo esc_html($item->post_title); ?></h4>
|
93 |
-
<p><?php echo __('Course: ', 'tutor'); ?><a href='<?php echo get_the_permalink($course_id) ?>' target="_blank"><?php echo get_the_title($course_id); ?> </a></p>
|
94 |
-
</td>
|
95 |
-
<td><?php echo $max_mark ?></td>
|
96 |
-
<td><?php echo $comment_count ?></td>
|
97 |
-
<td>
|
98 |
-
<a href="<?php echo esc_url($submitted_url . '?assignment=' . $item->ID); ?>" class="tutor-btn bordered-btn tutor-announcement-details">
|
99 |
-
<?php _e('Details', 'tutor'); ?>
|
100 |
-
</a>
|
101 |
-
</td>
|
102 |
-
</tr>
|
103 |
-
<?php
|
104 |
-
}
|
105 |
-
?>
|
106 |
-
</tbody>
|
107 |
-
</table>
|
108 |
-
</div>
|
109 |
-
|
110 |
-
<div class="tutor-pagination">
|
111 |
-
<?php
|
112 |
-
|
113 |
-
echo paginate_links(array(
|
114 |
-
'format' => '?current_page=%#%',
|
115 |
-
'current' => $current_page,
|
116 |
-
'total' => ceil($assignments->count / $per_page)
|
117 |
-
));
|
118 |
-
?>
|
119 |
-
</div>
|
120 |
-
|
121 |
-
<?php } else {
|
122 |
-
echo '<p>' . __('No assignment available', 'tutor') . '</p>';
|
14 |
|
15 |
global $wpdb;
|
16 |
|
17 |
+
$per_page = 10;
|
18 |
+
$current_page = max( 1, tutor_utils()->avalue_dot( 'current_page', tutor_sanitize_data($_GET) ) );
|
19 |
+
$offset = ( $current_page - 1 ) * $per_page;
|
20 |
|
21 |
+
$course_id = isset( $_GET['course-id'] ) ? sanitize_text_field( $_GET['course-id'] ) : '';
|
22 |
+
$order_filter = isset( $_GET['order'] ) ? $_GET['order'] : 'DESC';
|
23 |
+
$date_filter = isset( $_GET['date'] ) ? $_GET['date'] : '';
|
24 |
|
25 |
+
$current_user = get_current_user_id();
|
26 |
+
$assignments = tutor_utils()->get_assignments_by_instructor( null, compact( 'course_id', 'order_filter', 'date_filter', 'per_page', 'offset' ) );
|
27 |
+
$courses = ( current_user_can( 'administrator' ) ) ? tutils()->get_courses() : tutils()->get_courses_by_instructor();
|
28 |
|
29 |
?>
|
30 |
|
31 |
<div class="tutor-dashboard-announcement-sorting-wrap">
|
32 |
+
<div class="tutor-form-group">
|
33 |
+
<label for="">
|
34 |
+
<?php _e( 'Courses', 'tutor' ); ?>
|
35 |
+
</label>
|
36 |
+
<select class="tutor-report-category tutor-announcement-course-sorting ignore-nice-select">
|
37 |
+
|
38 |
+
<option value=""><?php _e( 'All', 'tutor' ); ?></option>
|
39 |
+
|
40 |
+
<?php if ( $courses ) : ?>
|
41 |
+
<?php foreach ( $courses as $course ) : ?>
|
42 |
+
<option value="<?php echo $course->ID; ?>" <?php selected( $course_id, $course->ID, 'selected' ); ?>>
|
43 |
+
<?php echo $course->post_title; ?>
|
44 |
+
</option>
|
45 |
+
<?php endforeach; ?>
|
46 |
+
<?php else : ?>
|
47 |
+
<option value=""><?php _e( 'No course found', 'tutor' ); ?></option>
|
48 |
+
<?php endif; ?>
|
49 |
+
</select>
|
50 |
+
</div>
|
51 |
+
<div class="tutor-form-group">
|
52 |
+
<label><?php _e( 'Sort By', 'tutor' ); ?></label>
|
53 |
+
<select class="tutor-announcement-order-sorting ignore-nice-select">
|
54 |
+
<option <?php selected( $order_filter, 'ASC' ); ?>><?php _e( 'ASC', 'tutor' ); ?></option>
|
55 |
+
<option <?php selected( $order_filter, 'DESC' ); ?>><?php _e( 'DESC', 'tutor' ); ?></option>
|
56 |
+
</select>
|
57 |
+
</div>
|
58 |
+
<div class="tutor-form-group tutor-announcement-datepicker">
|
59 |
+
<label><?php _e( 'Create Date', 'tutor' ); ?></label>
|
60 |
+
<input type="text" class="tutor_date_picker tutor-announcement-date-sorting" value="<?php echo '' !== $date_filter ? tutor_get_formated_date( get_option( 'date_format' ), $date_filter ) : ''; ?>" placeholder="<?php echo get_option( 'date_format' ); ?>" autocomplete="off" />
|
61 |
+
<i class="tutor-icon-calendar"></i>
|
62 |
+
</div>
|
63 |
</div>
|
64 |
|
65 |
<?php
|
66 |
|
67 |
+
if ( $assignments->count ) {
|
68 |
+
?>
|
69 |
+
|
70 |
+
<div class="tutor-announcement-table-wrap">
|
71 |
+
<table class="tutor-dashboard-announcement-table" width="100%">
|
72 |
+
<thead>
|
73 |
+
<tr>
|
74 |
+
<th><?php _e( 'Course Name', 'tutor' ); ?></th>
|
75 |
+
<th width="15%"><?php _e( 'Total Points', 'tutor' ); ?></th>
|
76 |
+
<th width="15%"><?php _e( 'Total Submits', 'tutor' ); ?></th>
|
77 |
+
<th width="10%"> </th>
|
78 |
+
</tr>
|
79 |
+
</thead>
|
80 |
+
<tbody>
|
81 |
+
<?php
|
82 |
+
|
83 |
+
$submitted_url = tutor_utils()->get_tutor_dashboard_page_permalink( 'assignments/submitted' );
|
84 |
+
|
85 |
+
foreach ( $assignments->results as $item ) {
|
86 |
+
$max_mark = tutor_utils()->get_assignment_option( $item->ID, 'total_mark' );
|
87 |
+
$course_id = tutor_utils()->get_course_id_by( 'assignment', $item->ID );
|
88 |
+
$comment_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE comment_type = 'tutor_assignment' AND comment_post_ID = %d", $item->ID ) );
|
89 |
+
// @TODO: assi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|