PluginProbe
Tutor LMS – eLearning and online course solution / 2.0.1
Tutor LMS – eLearning and online course solution v2.0.1
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 All 191 releases
tutor / classes / Admin.php

Admin.php in Tutor LMS – eLearning and online course solution 2.0.1, at classes/Admin.php

493 lines 17.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TUTOR;
4
5 /**
6 * Class Admin
7 * @package TUTOR
8 *
9 * @since v.1.0.0
10 */
11
12 if (!defined('ABSPATH'))
13 exit;
14
15 class Admin {
16 public function __construct() {
17 add_action('admin_menu', array($this, 'register_menu'));
18 //Force activate menu for necessary
19 add_filter('parent_file', array($this, 'parent_menu_active'));
20 add_filter('submenu_file', array($this, 'submenu_file_active'), 10, 2);
21
22 add_action('admin_init', array($this, 'filter_posts_for_instructors'));
23 add_action('load-post.php', array($this, 'check_if_current_users_post'));
24
25 add_action('admin_action_uninstall_tutor_and_erase', array($this, 'erase_tutor_data'));
26 add_filter('plugin_action_links_' . plugin_basename(TUTOR_FILE), array($this, 'plugin_action_links'));
27
28 //Plugin Row Meta
29 add_filter('plugin_row_meta', array($this, 'plugin_row_meta'), 10, 2);
30
31 //Admin Footer Text
32 add_filter('admin_footer_text', array($this, 'admin_footer_text'), 1);
33 //Register Course Widget
34 add_action('widgets_init', array($this, 'register_course_widget'));
35 }
36
37 public function register_menu() {
38 $hasPro = tutor()->has_pro;
39
40 $unanswered_questions = tutor_utils()->unanswered_question_count();
41 $unanswered_bubble = '';
42 if ($unanswered_questions) {
43 $unanswered_bubble = '<span class="update-plugins count-' . $unanswered_questions . '"><span class="plugin-count">' . $unanswered_questions . '</span></span>';
44 }
45
46 $course_post_type = tutor()->course_post_type;
47
48 $pro_text = '';
49 if ($hasPro) {
50 $pro_text = ' ' . __('Pro', 'tutor');
51 }
52
53 $enable_course_marketplace = (bool) tutor_utils()->get_option('enable_course_marketplace');
54
55 $welcome = Tutor_Setup::is_welcome_page_visited();
56 add_menu_page(
57 __( 'Tutor LMS', 'tutor' ) . $pro_text,
58 __( 'Tutor LMS', 'tutor' ) . $pro_text,
59 'manage_tutor_instructor',
60 'tutor',
61 false === $welcome && isset( $_GET['page'] ) && 'tutor' === $_GET['page'] && isset( $_GET['welcome' ] ) ? array( $this, 'welcome_page' ) : array( $this, 'tutor_course_list' ),
62 'data:image/svg+xml;base64,' . base64_encode('<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1139"><defs/><path fill-rule="evenodd" clip-rule="evenodd" d="M341.652 622.4c-23.412 0-43.222-19.8-43.222-43.2v-99c0-23.4 19.81-43.2 43.222-43.2 23.412 0 43.222 19.8 43.222 43.2v99c0 23.4-18.009 43.2-43.222 43.2 1.801 0 1.801 0 0 0zM655.01 622.4c-23.412 0-43.222-18-43.222-43.2v-99c0-23.4 19.81-43.2 43.222-43.2 23.412 0 43.222 19.8 43.222 43.2v99c0 25.2-19.81 43.2-43.222 43.2z" fill="#9DA2A8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M255.204 406.4c18.009-37.8 54.028-63 95.449-63 61.231 1.8 108.055 52.2 106.254 113.4v203.4c3.602 21.6 23.412 37.8 45.023 34.2 18.009-1.8 32.416-16.2 34.217-34.2V455c-1.801-61.2 46.824-111.6 106.254-113.4 39.621 0 75.639 21.6 93.648 59.4 68.435 133.2 14.407 295.2-117.06 363.6C487.523 833 325.44 779 258.806 647.6c-39.62-75.6-39.62-165.6-3.602-241.2zM426.291 140h151.277v59.4c-25.212-5.4-52.226-9-77.439-9-25.213 0-50.426 3.6-75.639 7.2l1.801-57.6zm414.211 388.8c0-122.4-66.634-235.8-172.888-295.2V140h64.833c25.213 0 45.023-19.8 45.023-45s-21.611-45-45.023-45H271.413C246.2 51.8 226.39 71.6 226.39 96.8c0 25.2 19.81 45 45.023 45h66.633v91.8c-163.883 90-230.517 298.8-135.068 459 3.602 5.4-3.602-5.4 0 0C338.046 930.2 687.424 948.2 802.683 950c10.805 0 19.81-3.6 27.014-10.8 7.203-7.2 10.805-18 10.805-27V528.8z" fill="#9DA2A8"/></svg>'),
63 2
64 );
65 // @since v2.0.0
66 add_submenu_page( 'tutor', __( 'Courses', 'tutor' ), __( 'Courses', 'tutor' ), 'manage_tutor_instructor', 'tutor', array( $this, 'tutor_course_list' ) );
67
68 add_submenu_page('tutor', __('Categories', 'tutor'), __('Categories', 'tutor'), 'manage_tutor', 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type, null);
69
70 add_submenu_page('tutor', __('Tags', 'tutor'), __('Tags', 'tutor'), 'manage_tutor', 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type, null);
71
72 add_submenu_page('tutor', __('Students', 'tutor'), __('Students', 'tutor'), 'manage_tutor', Students_List::STUDENTS_LIST_PAGE, array($this, 'tutor_students'));
73
74 if ($enable_course_marketplace) {
75 add_submenu_page('tutor', __('Instructors', 'tutor'), __('Instructors', 'tutor'), 'manage_tutor', Instructors_List::INSTRUCTOR_LIST_PAGE, array($this, 'tutor_instructors'));
76 }
77
78 add_submenu_page('tutor', __('Announcements', 'tutor'), __('Announcements', 'tutor'), 'manage_tutor_instructor', 'tutor_announcements', array($this, 'tutor_announcements'));
79
80 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'));
81
82 add_submenu_page('tutor', __('Quiz Attempts', 'tutor'), __('Quiz Attempts', 'tutor'), 'manage_tutor_instructor', Quiz_Attempts_List::QUIZ_ATTEMPT_PAGE, array($this, 'quiz_attempts'));
83
84 if ($enable_course_marketplace){
85 add_submenu_page('tutor', __('Withdraw Requests', 'tutor'), __('Withdraw Requests', 'tutor'), 'manage_tutor', Withdraw_Requests_List::WITHDRAW_REQUEST_LIST_PAGE, array($this, 'withdraw_requests') );
86 }
87
88 add_submenu_page('tutor', __('Add-ons', 'tutor'), __('Add-ons', 'tutor'), 'manage_tutor', 'tutor-addons', array($this, 'enable_disable_addons'));
89
90 do_action('tutor_admin_register');
91
92 add_submenu_page('tutor', __('Tools', 'tutor'), __('Tools', 'tutor'), 'manage_tutor', 'tutor-tools', array($this, 'tutor_tools'));
93
94 add_submenu_page('tutor', __('Settings', 'tutor'), __('Settings', 'tutor'), 'manage_tutor', 'tutor_settings', array($this, 'tutor_settings_page_content'));
95
96 if (!$hasPro) {
97 add_submenu_page('tutor', __('Get Pro', 'tutor'), __('<span class="dashicons dashicons-awards tutor-get-pro-text"></span> Get Pro', 'tutor'), 'manage_options', 'tutor-get-pro', array($this, 'tutor_get_pro'));
98 }
99 }
100
101 public function tutor_tools() {
102 (new Tools_V2)->load_tools_page();
103 }
104
105 public function tutor_settings_page_content() {
106 (new Options_V2)->load_settings_page();
107 }
108
109 public function tutor_students() {
110 include tutor()->path . 'views/pages/students.php';
111 }
112
113 public function tutor_instructors() {
114 include tutor()->path . 'views/pages/instructors.php';
115 }
116
117 public function tutor_announcements() {
118 include tutor()->path . 'views/pages/announcements.php';
119 }
120
121 public function question_answer() {
122 include tutor()->path . 'views/pages/question_answer.php';
123 }
124
125 public function quiz_attempts() {
126 include tutor()->path . 'views/pages/quiz_attempts.php';
127 }
128
129 /**
130 * Show the withdraw requests table
131 *
132 * @since v.1.2.0
133 */
134 public function withdraw_requests() {
135 include tutor()->path . 'views/pages/withdraw_requests.php';
136 }
137
138 public function enable_disable_addons() {
139
140 if (defined('TUTOR_PRO_VERSION')) {
141 include tutor()->path . 'views/pages/enable_disable_addons.php';
142 } else {
143 include tutor()->path . 'views/pages/tutor-pro-addons.php';
144 }
145 }
146
147 public function tutor_tools_old() {
148 $tutor_admin_tools_page = tutor_utils()->array_get('tutor_admin_tools_page', tutor_sanitize_data($_GET));
149 if ($tutor_admin_tools_page) {
150 include apply_filters('tutor_admin_tools_page', tutor()->path . "views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page);
151 } else {
152 $pages = apply_filters('tutor_tool_pages', array(
153 'tutor_pages' => array('title' => __('Tutor Pages', 'tutor')),
154 'status' => __('Status', 'tutor'),
155 ));
156
157 $current_page = 'tutor_pages';
158 $requested_page = sanitize_text_field(tutor_utils()->array_get('sub_page', tutor_sanitize_data($_GET)));
159 if ($requested_page) {
160 $current_page = $requested_page;
161 }
162
163 $current_page = str_replace('/', '', $current_page);
164 $current_page = str_replace('.', '', $current_page);
165 $current_page = str_replace('\\', '', $current_page);
166 $current_page = trim($current_page);
167
168 include tutor()->path . 'views/pages/tools.php';
169 }
170 }
171
172 public function tutor_get_pro() {
173 include tutor()->path . 'views/pages/get-pro.php';
174 }
175
176 public function parent_menu_active($parent_file) {
177 $taxonomy = tutor_utils()->avalue_dot('taxonomy', tutor_sanitize_data($_GET));
178 if ($taxonomy === 'course-category' || $taxonomy === 'course-tag') {
179 return 'tutor';
180 }
181
182 return $parent_file;
183 }
184
185 public function submenu_file_active($submenu_file, $parent_file) {
186 $taxonomy = tutor_utils()->avalue_dot('taxonomy', tutor_sanitize_data($_GET));
187 $course_post_type = tutor()->course_post_type;
188
189 if ($taxonomy === 'course-category') {
190 return 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type;
191 }
192 if ($taxonomy === 'course-tag') {
193 return 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type;
194 }
195
196
197 return $submenu_file;
198 }
199
200 /**
201 * Filter posts for instructor
202 */
203 public function filter_posts_for_instructors() {
204 if (!current_user_can('administrator') && current_user_can(tutor()->instructor_role)) {
205 @remove_menu_page('edit-comments.php'); //Comments
206 add_filter('posts_clauses_request', array($this, 'posts_clauses_request'));
207 }
208 }
209
210 public function posts_clauses_request($clauses) {
211
212 if (!is_admin() || (!isset($_GET['post_type']) || $_GET['post_type'] != 'courses') || tutor_utils()->has_user_role(array('administrator', 'editor'))) {
213 return $clauses;
214 }
215
216 // Need multi instructor check
217 global $wpdb;
218
219 $user_id = get_current_user_id();
220
221 $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));
222 $own_courses = is_array($get_assigned_courses_ids) ? $get_assigned_courses_ids : array();
223
224 $in_query_pre = count($own_courses) ? implode(',', $own_courses) : null;
225 $in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
226
227 $custom_author_query = " AND ({$wpdb->posts}.post_type!='courses' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
228
229 $clauses['where'] .= $custom_author_query;
230
231 return $clauses;
232 }
233
234 /**
235 * Prevent unauthorised course/lesson edit page by direct URL
236 *
237 * @since v.1.0.0
238 */
239 public function check_if_current_users_post() {
240 if (current_user_can('administrator') || !current_user_can(tutor()->instructor_role)) {
241 return;
242 }
243
244 if (! empty($_GET['post']) ) {
245 $get_post_id = (int) $_GET['post'];
246 $get_post = get_post($get_post_id);
247 $tutor_post_types = array(tutor()->course_post_type, tutor()->lesson_post_type);
248
249 $current_user = get_current_user_id();
250
251 if (in_array($get_post->post_type, $tutor_post_types) && $get_post->post_author != $current_user) {
252 global $wpdb;
253
254 $get_assigned_courses_ids = (int) $wpdb->get_var($wpdb->prepare(
255 "SELECT user_id
256 from {$wpdb->usermeta}
257 WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ",
258 $current_user,
259 $get_post_id
260 ));
261
262 if (!$get_assigned_courses_ids) {
263 wp_die(__('Permission Denied', 'tutor'));
264 }
265 }
266 }
267 }
268
269 /**
270 * Status
271 */
272
273 public static function scan_template_files($template_path = null) {
274 if (!$template_path) {
275 $template_path = tutor()->path . 'templates/';
276 }
277
278 $files = @scandir($template_path); // @codingStandardsIgnoreLine.
279 $result = array();
280
281 if (!empty($files)) {
282 foreach ($files as $key => $value) {
283 if (!in_array($value, array('.', '..', '.DS_Store'), true)) {
284 if (is_dir($template_path . DIRECTORY_SEPARATOR . $value)) {
285 $sub_files = self::scan_template_files($template_path . DIRECTORY_SEPARATOR . $value);
286 foreach ($sub_files as $sub_file) {
287 $result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
288 }
289 } else {
290 $result[] = $value;
291 }
292 }
293 }
294 }
295 return $result;
296 }
297
298 /**
299 * @return array
300 *
301 *
302 */
303 public static function template_overridden_files() {
304 $template_files = self::scan_template_files();
305
306 $override_files = array();
307 foreach ($template_files as $file) {
308 $file_path = null;
309 if (file_exists(trailingslashit(get_stylesheet_directory()) . tutor()->template_path . $file)) {
310 $file_path = $file;
311 } elseif (file_exists(trailingslashit(get_template_directory()) . tutor()->template_path . $file)) {
312 $file_path = $file;
313 }
314
315 if ($file_path) {
316 $override_files[] = str_replace(WP_CONTENT_DIR . '/themes/', '', $file_path);
317 }
318 }
319
320 return $override_files;
321 }
322
323 public function erase_tutor_data() {
324 global $wpdb;
325
326 $is_erase_data = tutor_utils()->get_option('delete_on_uninstall');
327 //=> Deleting Data
328
329 $plugin_file = tutor()->basename;
330 if ($is_erase_data && current_user_can('deactivate_plugin', $plugin_file)) {
331 /**
332 * Deleting Post Type, Meta Data, taxonomy
333 */
334 $course_post_type = tutor()->course_post_type;
335 $lesson_post_type = tutor()->lesson_post_type;
336
337 $post_types = array(
338 $course_post_type,
339 $lesson_post_type,
340 'tutor_quiz',
341 'tutor_enrolled',
342 'topics',
343 'tutor_enrolled',
344 'tutor_announcements',
345 );
346
347 $post_type_strings = "'" . implode("','", $post_types) . "'";
348 $tutor_posts = $wpdb->get_col("SELECT ID from {$wpdb->posts} WHERE post_type in({$post_type_strings}) ;");
349
350 if (is_array($tutor_posts) && count($tutor_posts)) {
351 foreach ($tutor_posts as $post_id) {
352 //Delete categories
353 $terms = wp_get_object_terms($post_id, 'course-category');
354 foreach ($terms as $term) {
355 wp_remove_object_terms($post_id, array($term->term_id), 'course-category');
356 }
357
358 //Delete tags if available
359 $terms = wp_get_object_terms($post_id, 'course-tag');
360 foreach ($terms as $term) {
361 wp_remove_object_terms($post_id, array($term->term_id), 'course-tag');
362 }
363
364 //Delete All Meta
365 $wpdb->delete($wpdb->postmeta, array('post_id' => $post_id));
366 $wpdb->delete($wpdb->posts, array('ID' => $post_id));
367 }
368 }
369
370 /**
371 * Deleting Comments (reviews, questions, quiz_answers, etc)
372 */
373 $tutor_comments = $wpdb->get_col("SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;");
374 $comments_ids_strings = "'" . implode("','", $tutor_comments) . "'";
375 if (is_array($tutor_comments) && count($tutor_comments)) {
376 $wpdb->query("DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$comments_ids_strings}) ");
377 }
378 $wpdb->delete($wpdb->comments, array('comment_agent' => 'comment_agent'));
379
380 /**
381 * Delete Options
382 */
383
384 delete_option('tutor_option');
385 $wpdb->delete($wpdb->usermeta, array('meta_key' => '_is_tutor_student'));
386 $wpdb->delete($wpdb->usermeta, array('meta_key' => '_tutor_instructor_approved'));
387 $wpdb->delete($wpdb->usermeta, array('meta_key' => '_tutor_instructor_status'));
388 $wpdb->delete($wpdb->usermeta, array('meta_key' => '_is_tutor_instructor'));
389 $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' ");
390
391 //Deleting Table
392 $prefix = $wpdb->prefix;
393 $wpdb->query("DROP TABLE IF EXISTS {$prefix}tutor_quiz_attempts, {$prefix}tutor_quiz_attempt_answers, {$prefix}tutor_quiz_questions, {$prefix}tutor_quiz_question_answers, {$prefix}tutor_earnings, {$prefix}tutor_withdraws ");
394
395 deactivate_plugins($plugin_file);
396 }
397
398 wp_redirect('plugins.php');
399 die();
400 }
401
402 public function plugin_action_links($actions) {
403 $hasPro = tutor()->has_pro;
404
405 if (!$hasPro) {
406 $actions['tutor_pro_link'] = '<a href="https://www.themeum.com/product/tutor-lms/#pricing?utm_source=tutor_plugin_action_link&utm_medium=wordpress_dashboard&utm_campaign=go_premium" target="_blank"><span
407 style="color: #ff7742; font-weight: bold;">' . __('Upgrade to Pro', 'wp-megamenu') . '</span></a>';
408 }
409
410 $is_erase_data = tutor_utils()->get_option('delete_on_uninstall');
411
412 if ($is_erase_data) {
413 $plugin_file = tutor()->basename;
414 if (current_user_can('deactivate_plugin', $plugin_file)) {
415 if (isset($actions['deactivate'])) {
416 $actions['deactivate'] = '<a href="admin.php?page=tutor-tools&tutor_admin_tools_page=uninstall">' . __('Uninstall', 'tutor') . '</a>';
417 }
418 }
419 }
420
421 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __('Settings', 'tutor') . '</a>';
422 return $actions;
423 }
424
425 public function plugin_row_meta($plugin_meta, $plugin_file) {
426
427 if ($plugin_file === tutor()->basename) {
428 $plugin_meta[] = sprintf(
429 '<a href="%s">%s</a>',
430 esc_url('https://docs.themeum.com/tutor-lms/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link'),
431 __('<strong style="color: #03bd24">Documentation</strong>', 'tutor')
432 );
433 $plugin_meta[] = sprintf(
434 '<a href="%s">%s</a>',
435 esc_url('https://www.themeum.com/contact-us/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link'),
436 __('<strong style="color: #03bd24">Get Support</strong>', 'tutor')
437 );
438 }
439
440 return $plugin_meta;
441 }
442
443 /**
444 * @param $footer_text
445 *
446 * @return string
447 *
448 * Add footer text only on tutor pages
449 */
450 public function admin_footer_text($footer_text) {
451 $current_screen = get_current_screen();
452
453 /**
454 * We are making sure that this message will be only on Tutor Admin page
455 */
456 if (apply_filters('tutor_display_admin_footer_text', (tutor_utils()->array_get('parent_base', $current_screen) === 'tutor'))) {
457 $footer_text = sprintf(
458 __('If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor'),
459 sprintf('<strong>%s</strong>', esc_html__('Tutor LMS', 'tutor')),
460 '<a href="https://wordpress.org/support/plugin/tutor/reviews?rate=5#new-post" target="_blank" class="tutor-rating-link">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
461 );
462 }
463
464 return $footer_text;
465 }
466
467
468 public function register_course_widget() {
469 register_widget('Tutor\Course_Widget');
470 }
471
472 /**
473 * Tutor Course List
474 *
475 * @package Course List
476 * @since v2.0.0
477 */
478 public function tutor_course_list() {
479 include tutor()->path . 'views/pages/course-list.php';
480 }
481
482 /**
483 * Show welcome page
484 *
485 * @return void
486 */
487 public function welcome_page() {
488 Tutor_Setup::mark_as_visited();
489 include tutor()->path . 'views/pages/welcome.php';
490 exit;
491 }
492 }
493