PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.3.0
Tutor LMS – eLearning and online course solution v2.3.0
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Admin.php
tutor / classes Last commit date
Addons.php 2 years ago Admin.php 2 years ago Ajax.php 2 years ago Announcements.php 3 years ago Assets.php 2 years ago Backend_Page_Trait.php 3 years ago Course.php 2 years ago Course_Embed.php 3 years ago Course_Filter.php 3 years ago Course_List.php 2 years ago Course_Settings_Tabs.php 3 years ago Course_Widget.php 3 years ago Custom_Validation.php 3 years ago Dashboard.php 3 years ago FormHandler.php 2 years ago Frontend.php 3 years ago Gutenberg.php 3 years ago Input.php 3 years ago Instructor.php 2 years ago Instructors_List.php 3 years ago Lesson.php 2 years ago Options_V2.php 2 years ago Post_types.php 2 years ago Private_Course_Access.php 3 years ago Q_and_A.php 3 years ago Question_Answers_List.php 3 years ago Quiz.php 2 years ago Quiz_Attempts_List.php 2 years ago RestAPI.php 3 years ago Reviews.php 3 years ago Rewrite_Rules.php 3 years ago Shortcode.php 2 years ago Student.php 2 years ago Students_List.php 3 years ago Taxonomies.php 3 years ago Template.php 2 years ago Theme_Compatibility.php 3 years ago Tools.php 3 years ago Tools_V2.php 3 years ago Tutor.php 3 years ago TutorEDD.php 2 years ago Tutor_Base.php 3 years ago Tutor_Setup.php 3 years ago Upgrader.php 3 years ago User.php 3 years ago Utils.php 2 years ago Video_Stream.php 3 years ago Withdraw.php 2 years ago Withdraw_Requests_List.php 3 years ago WooCommerce.php 2 years ago
Admin.php
694 lines
1 <?php
2 /**
3 * Manage admin menu and plugin related logic
4 *
5 * @package Tutor
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.0.0
9 */
10
11 namespace TUTOR;
12
13 use TUTOR\Input;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Admin Class
21 *
22 * @since 1.0.0
23 */
24 class Admin {
25 /**
26 * Constructor
27 *
28 * @since 1.0.0
29 * @return void
30 */
31 public function __construct() {
32 add_action( 'admin_menu', array( $this, 'register_menu' ) );
33 // Force activate menu for necessary.
34 add_filter( 'parent_file', array( $this, 'parent_menu_active' ) );
35 add_filter( 'submenu_file', array( $this, 'submenu_file_active' ), 10, 2 );
36
37 add_action( 'admin_init', array( $this, 'filter_posts_for_instructors' ) );
38 add_action( 'load-post.php', array( $this, 'check_if_current_users_post' ) );
39
40 add_action( 'admin_action_uninstall_tutor_and_erase', array( $this, 'erase_tutor_data' ) );
41 add_filter( 'plugin_action_links_' . plugin_basename( TUTOR_FILE ), array( $this, 'plugin_action_links' ) );
42
43 // Plugin Row Meta.
44 add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
45
46 // Admin Footer Text.
47 add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
48 // Register Course Widget.
49 add_action( 'widgets_init', array( $this, 'register_course_widget' ) );
50
51 // Handle flash toast message for redirect_to util helper.
52 add_action( 'admin_head', array( new Utils(), 'handle_flash_message' ), 999 );
53 add_action( 'tutor_after_settings_menu', array( $this, 'whats_new_menu' ), 11 );
54 }
55
56 /**
57 * Register admin menus
58 *
59 * @since 1.0.0
60 * @return void
61 */
62 public function register_menu() {
63 $has_pro = tutor()->has_pro;
64
65 $unanswered_questions = tutor_utils()->unanswered_question_count();
66 $unanswered_bubble = '';
67 if ( $unanswered_questions ) {
68 $unanswered_bubble = '<span class="update-plugins count-' . $unanswered_questions . '"><span class="plugin-count">' . $unanswered_questions . '</span></span>';
69 }
70
71 $course_post_type = tutor()->course_post_type;
72
73 $pro_text = '';
74 if ( $has_pro ) {
75 $pro_text = ' ' . __( 'Pro', 'tutor' );
76 }
77
78 $enable_course_marketplace = (bool) tutor_utils()->get_option( 'enable_course_marketplace' );
79
80 $welcome = Tutor_Setup::is_welcome_page_visited();
81
82 $root_page = array( $this, 'tutor_course_list' );
83 if ( false === $welcome && Input::has( 'page' ) && 'tutor' === Input::get( 'page' ) && Input::has( 'welcome' ) ) {
84 $root_page = array( $this, 'welcome_page' );
85 }
86
87 $icon_base64_uri = '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>' );
88 $menu_position = 2;
89
90 add_menu_page(
91 __( 'Tutor LMS', 'tutor' ) . $pro_text,
92 __( 'Tutor LMS', 'tutor' ) . $pro_text,
93 'manage_tutor_instructor',
94 'tutor',
95 $root_page,
96 $icon_base64_uri,
97 $menu_position
98 );
99
100 // Added @since v2.0.0.
101 add_submenu_page( 'tutor', __( 'Courses', 'tutor' ), __( 'Courses', 'tutor' ), 'manage_tutor_instructor', 'tutor', array( $this, 'tutor_course_list' ) );
102
103 // Extendable action hook @since 2.2.0.
104 do_action( 'tutor_after_courses_menu' );
105
106 if ( ! $has_pro ) {
107 add_submenu_page( 'tutor', __( 'Course Bundles', 'tutor' ), __( 'Course Bundle <span class="tutor-badge-new">New</span>', 'tutor' ), 'manage_tutor', 'course-bundle', array( $this, 'course_bundle_page' ) );
108 }
109
110 add_submenu_page( 'tutor', __( 'Categories', 'tutor' ), __( 'Categories', 'tutor' ), 'manage_tutor', 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type, null );
111
112 add_submenu_page( 'tutor', __( 'Tags', 'tutor' ), __( 'Tags', 'tutor' ), 'manage_tutor', 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type, null );
113
114 add_submenu_page( 'tutor', __( 'Students', 'tutor' ), __( 'Students', 'tutor' ), 'manage_tutor', Students_List::STUDENTS_LIST_PAGE, array( $this, 'tutor_students' ) );
115
116 if ( $enable_course_marketplace ) {
117 add_submenu_page( 'tutor', __( 'Instructors', 'tutor' ), __( 'Instructors', 'tutor' ), 'manage_tutor', Instructors_List::INSTRUCTOR_LIST_PAGE, array( $this, 'tutor_instructors' ) );
118 }
119
120 add_submenu_page( 'tutor', __( 'Announcements', 'tutor' ), __( 'Announcements', 'tutor' ), 'manage_tutor_instructor', 'tutor_announcements', array( $this, 'tutor_announcements' ) );
121
122 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' ) );
123
124 add_submenu_page( 'tutor', __( 'Quiz Attempts', 'tutor' ), __( 'Quiz Attempts', 'tutor' ), 'manage_tutor_instructor', Quiz_Attempts_List::QUIZ_ATTEMPT_PAGE, array( $this, 'quiz_attempts' ) );
125
126 if ( $enable_course_marketplace ) {
127 add_submenu_page( 'tutor', __( 'Withdraw Requests', 'tutor' ), __( 'Withdraw Requests', 'tutor' ), 'manage_tutor', Withdraw_Requests_List::WITHDRAW_REQUEST_LIST_PAGE, array( $this, 'withdraw_requests' ) );
128 }
129
130 add_submenu_page( 'tutor', __( 'Add-ons', 'tutor' ), sprintf( '<span class="tutor-addons-text">%s</span>', __( 'Add-ons', 'tutor' ) ), 'manage_tutor', 'tutor-addons', array( $this, 'enable_disable_addons' ) );
131
132 do_action( 'tutor_admin_register' );
133
134 add_submenu_page( 'tutor', __( 'Tools', 'tutor' ), __( 'Tools', 'tutor' ), 'manage_tutor', 'tutor-tools', array( new \TUTOR\Tools_V2(), 'load_tools_page' ) );
135
136 add_submenu_page( 'tutor', __( 'Settings', 'tutor' ), __( 'Settings', 'tutor' ), 'manage_tutor', 'tutor_settings', array( new \TUTOR\Options_V2(), 'load_settings_page' ) );
137
138 do_action( 'tutor_after_settings_menu' );
139
140 if ( ! $has_pro ) {
141 add_submenu_page( 'tutor', __( 'Upgrade to Pro', 'tutor' ), sprintf( '<span class="tutor-get-pro-text">%s</span>', __( 'Upgrade to Pro', 'tutor' ) ), 'manage_options', 'tutor-get-pro', array( $this, 'tutor_get_pro' ) );
142 }
143 }
144
145 /**
146 * What's new page.
147 *
148 * @since 2.2.4
149 *
150 * @return void
151 */
152 public function whats_new_menu() {
153 $transient_key = 'tutor_plugin_info';
154 $plugin_info = get_transient( $transient_key );
155
156 if ( false === $plugin_info ) {
157 $plugin_info = tutils()->get_remote_plugin_info();
158 $hour_in_seconds = 1800;
159 set_transient( $transient_key, $plugin_info, $hour_in_seconds );
160 }
161
162 $remote_version = $plugin_info->version ?? TUTOR_VERSION;
163 $installed_version = TUTOR_VERSION;
164 $update_required = version_compare( $remote_version, $installed_version, '>' );
165
166 $menu_text = __( "What's New", 'tutor' );
167 if ( $update_required ) {
168 $menu_text .= ' <span class="update-plugins"><span class="plugin-count">1</span></span>';
169 }
170
171 add_submenu_page(
172 'tutor',
173 __( "What's New", 'tutor' ),
174 $menu_text,
175 'manage_options',
176 'tutor-whats-new',
177 function() use ( $remote_version, $installed_version, $update_required ) {
178 include tutor()->path . 'views/pages/whats-new.php';
179 }
180 );
181 }
182
183 /**
184 * Show Course Bundle Page For Free User.
185 *
186 * @since 2.2.0
187 *
188 * @return void
189 */
190 public function course_bundle_page() {
191 include tutor()->path . 'views/pages/course-bundle.php';
192 }
193
194 /**
195 * Show students page
196 *
197 * @since 1.0.0
198 * @return void
199 */
200 public function tutor_students() {
201 include tutor()->path . 'views/pages/students.php';
202 }
203
204 /**
205 * Show instructor page
206 *
207 * @since 1.0.0
208 * @return void
209 */
210 public function tutor_instructors() {
211 include tutor()->path . 'views/pages/instructors.php';
212 }
213
214 /**
215 * Show announcements page
216 *
217 * @since 1.0.0
218 * @return void
219 */
220 public function tutor_announcements() {
221 include tutor()->path . 'views/pages/announcements.php';
222 }
223
224 /**
225 * Show Q&A page
226 *
227 * @since 1.0.0
228 * @return void
229 */
230 public function question_answer() {
231 include tutor()->path . 'views/pages/question_answer.php';
232 }
233
234 /**
235 * Show quiz attempts page
236 *
237 * @since 1.0.0
238 * @return void
239 */
240 public function quiz_attempts() {
241 include tutor()->path . 'views/pages/quiz_attempts.php';
242 }
243
244 /**
245 * Show the withdraw requests table
246 *
247 * @since 1.2.0
248 * @return void
249 */
250 public function withdraw_requests() {
251 include tutor()->path . 'views/pages/withdraw_requests.php';
252 }
253
254 /**
255 * Enable or disable addons
256 *
257 * @since 1.0.0
258 * @return void
259 */
260 public function enable_disable_addons() {
261
262 if ( defined( 'TUTOR_PRO_VERSION' ) ) {
263 include tutor()->path . 'views/pages/enable_disable_addons.php';
264 } else {
265 include tutor()->path . 'views/pages/tutor-pro-addons.php';
266 }
267 }
268
269 /**
270 * Tutor tools page (OLD)
271 *
272 * @since 1.0.0
273 * @return void
274 */
275 public function tutor_tools_old() {
276 $tutor_admin_tools_page = Input::get( 'tutor_admin_tools_page' );
277 if ( $tutor_admin_tools_page ) {
278 include apply_filters( 'tutor_admin_tools_page', tutor()->path . "views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page );
279 } else {
280 $pages = apply_filters(
281 'tutor_tool_pages',
282 array(
283 'tutor_pages' => array( 'title' => __( 'Tutor Pages', 'tutor' ) ),
284 'status' => __( 'Status', 'tutor' ),
285 )
286 );
287
288 $current_page = 'tutor_pages';
289 $requested_page = Input::get( 'sub_page' );
290 if ( $requested_page ) {
291 $current_page = $requested_page;
292 }
293
294 $current_page = str_replace( '/', '', $current_page );
295 $current_page = str_replace( '.', '', $current_page );
296 $current_page = str_replace( '\\', '', $current_page );
297 $current_page = trim( $current_page );
298
299 include tutor()->path . 'views/pages/tools.php';
300 }
301 }
302
303 /**
304 * Show pro upgrade page
305 *
306 * @since 1.0.0
307 * @return void
308 */
309 public function tutor_get_pro() {
310 include tutor()->path . 'views/pages/get-pro.php';
311 }
312
313 /**
314 * Parent menu active
315 *
316 * @since 1.0.0
317 *
318 * @param string $parent_file parent file.
319 * @return string
320 */
321 public function parent_menu_active( $parent_file ) {
322 $taxonomy = Input::get( 'taxonomy' );
323 if ( 'course-category' === $taxonomy || 'course-tag' === $taxonomy ) {
324 return 'tutor';
325 }
326
327 return $parent_file;
328 }
329
330 /**
331 * Sub-menu active
332 *
333 * @since 1.0.0
334 *
335 * @param string $submenu_file submenu file.
336 * @param string $parent_file parent file.
337 *
338 * @return string
339 */
340 public function submenu_file_active( $submenu_file, $parent_file ) {
341 $taxonomy = Input::get( 'taxonomy' );
342 $course_post_type = tutor()->course_post_type;
343
344 if ( 'course-category' === $taxonomy ) {
345 return 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type;
346 }
347 if ( 'course-tag' === $taxonomy ) {
348 return 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type;
349 }
350
351 return $submenu_file;
352 }
353
354 /**
355 * Filter posts for instructor
356 *
357 * @since 1.0.0
358 * @return void
359 */
360 public function filter_posts_for_instructors() {
361 if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
362 @remove_menu_page( 'edit-comments.php' ); // Comments.
363 add_filter( 'posts_clauses_request', array( $this, 'posts_clauses_request' ) );
364 }
365 }
366
367 /**
368 * Request for posts clauses
369 *
370 * @since 1.0.0
371 *
372 * @param mixed $clauses clauses.
373 * @return mixed
374 */
375 public function posts_clauses_request( $clauses ) {
376
377 if ( ! is_admin() || ( ! Input::has( 'post_type' ) || Input::get( 'post_type' ) != tutor()->course_post_type ) || tutor_utils()->has_user_role( array( 'administrator', 'editor' ) ) ) {
378 return $clauses;
379 }
380
381 // Need multi instructor check.
382 global $wpdb;
383
384 $user_id = get_current_user_id();
385
386 $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 ) );
387 $own_courses = is_array( $get_assigned_courses_ids ) ? $get_assigned_courses_ids : array();
388
389 $in_query_pre = count( $own_courses ) ? implode( ',', $own_courses ) : null;
390 $in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
391
392 $course_post_type = tutor()->course_post_type;
393 $custom_author_query = " AND ({$wpdb->posts}.post_type!='{$course_post_type}' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
394
395 $clauses['where'] .= $custom_author_query;
396
397 return $clauses;
398 }
399
400 /**
401 * Prevent unauthorised course/lesson edit page by direct URL
402 *
403 * @since 1.0.0
404 * @return void
405 */
406 public function check_if_current_users_post() {
407 if ( current_user_can( 'administrator' ) || ! current_user_can( tutor()->instructor_role ) ) {
408 return;
409 }
410
411 if ( ! empty( Input::get( 'post' ) ) ) {
412 $get_post_id = Input::get( 'post', Input::TYPE_INT );
413 $get_post = get_post( $get_post_id );
414 $tutor_post_types = array( tutor()->course_post_type, tutor()->lesson_post_type );
415
416 $current_user = get_current_user_id();
417
418 if ( in_array( $get_post->post_type, $tutor_post_types ) && $get_post->post_author != $current_user ) {
419 global $wpdb;
420
421 $get_assigned_courses_ids = (int) $wpdb->get_var(
422 $wpdb->prepare(
423 "SELECT user_id
424 from {$wpdb->usermeta}
425 WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ",
426 $current_user,
427 $get_post_id
428 )
429 );
430
431 if ( ! $get_assigned_courses_ids ) {
432 wp_die( esc_html__( 'Permission Denied', 'tutor' ) );
433 }
434 }
435 }
436 }
437
438 /**
439 * Scan template files
440 *
441 * @since 1.0.0
442 *
443 * @param string $template_path template file path.
444 * @return array
445 */
446 public static function scan_template_files( $template_path = null ) {
447 if ( ! $template_path ) {
448 $template_path = tutor()->path . 'templates/';
449 }
450
451 $files = @scandir($template_path); // @codingStandardsIgnoreLine.
452 $result = array();
453
454 if ( ! empty( $files ) ) {
455 foreach ( $files as $key => $value ) {
456 if ( ! in_array( $value, array( '.', '..', '.DS_Store' ), true ) ) {
457 if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
458 $sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
459 foreach ( $sub_files as $sub_file ) {
460 $result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
461 }
462 } else {
463 $result[] = $value;
464 }
465 }
466 }
467 }
468 return $result;
469 }
470
471 /**
472 * Get Template overridden files
473 *
474 * @since 1.0.0
475 * @return array
476 */
477 public static function template_overridden_files() {
478 $template_files = self::scan_template_files();
479
480 $override_files = array();
481 foreach ( $template_files as $file ) {
482 $file_path = null;
483 if ( file_exists( trailingslashit( get_stylesheet_directory() ) . tutor()->template_path . $file ) ) {
484 $file_path = $file;
485 } elseif ( file_exists( trailingslashit( get_template_directory() ) . tutor()->template_path . $file ) ) {
486 $file_path = $file;
487 }
488
489 if ( $file_path ) {
490 $override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $file_path );
491 }
492 }
493
494 return $override_files;
495 }
496
497 /**
498 * Erase tutor data
499 *
500 * @since 1.0.0
501 * @return void
502 */
503 public function erase_tutor_data() {
504 global $wpdb;
505
506 $is_erase_data = tutor_utils()->get_option( 'delete_on_uninstall' );
507 // Deleting Data.
508
509 $plugin_file = tutor()->basename;
510 if ( $is_erase_data && current_user_can( 'deactivate_plugin', $plugin_file ) ) {
511 /**
512 * Deleting Post Type, Meta Data, taxonomy
513 */
514 $course_post_type = tutor()->course_post_type;
515 $lesson_post_type = tutor()->lesson_post_type;
516
517 $post_types = array(
518 $course_post_type,
519 $lesson_post_type,
520 'tutor_quiz',
521 'tutor_enrolled',
522 'topics',
523 'tutor_enrolled',
524 'tutor_announcements',
525 );
526
527 $post_type_strings = "'" . implode( "','", $post_types ) . "'";
528 $tutor_posts = $wpdb->get_col( "SELECT ID from {$wpdb->posts} WHERE post_type in({$post_type_strings}) ;" ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
529
530 if ( is_array( $tutor_posts ) && count( $tutor_posts ) ) {
531 foreach ( $tutor_posts as $post_id ) {
532 // Delete categories.
533 $terms = wp_get_object_terms( $post_id, 'course-category' );
534 foreach ( $terms as $term ) {
535 wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-category' );
536 }
537
538 // Delete tags if available.
539 $terms = wp_get_object_terms( $post_id, 'course-tag' );
540 foreach ( $terms as $term ) {
541 wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-tag' );
542 }
543
544 // Delete All Meta.
545 $wpdb->delete( $wpdb->postmeta, array( 'post_id' => $post_id ) );
546 $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
547 }
548 }
549
550 /**
551 * Deleting Comments (reviews, questions, quiz_answers, etc)
552 */
553 $tutor_comments = $wpdb->get_col( "SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;" );
554 $comments_ids_strings = "'" . implode( "','", $tutor_comments ) . "'";
555 if ( is_array( $tutor_comments ) && count( $tutor_comments ) ) {
556 $wpdb->query( "DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$comments_ids_strings}) " ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
557 }
558 $wpdb->delete( $wpdb->comments, array( 'comment_agent' => 'comment_agent' ) );
559
560 /**
561 * Delete Options
562 */
563
564 delete_option( 'tutor_option' );
565 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_student' ) );
566 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_approved' ) );
567 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_status' ) );
568 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_instructor' ) );
569 $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' " );
570
571 // Deleting Table.
572 $prefix = $wpdb->prefix;
573 //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
574 $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 " );
575
576 deactivate_plugins( $plugin_file );
577 }
578
579 wp_redirect( 'plugins.php' );
580 die();
581 }
582
583 /**
584 * Plugin activation link
585 *
586 * @since 1.0.0
587 *
588 * @param array $actions action list.
589 * @return array
590 */
591 public function plugin_action_links( $actions ) {
592 $has_pro = tutor()->has_pro;
593
594 if ( ! $has_pro ) {
595 $actions['tutor_pro_link'] =
596 '<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">
597 <span style="color: #ff7742; font-weight: bold;">' .
598 __( 'Upgrade to Pro', 'wp-megamenu' ) .
599 '</span>
600 </a>';
601 }
602
603 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __( 'Settings', 'tutor' ) . '</a>';
604
605 return $actions;
606 }
607
608 /**
609 * Add plugin meta data in WP plugins list page
610 *
611 * @since 1.0.0
612 *
613 * @param array $plugin_meta plugin meta data.
614 * @param string $plugin_file plugin file.
615 *
616 * @return array
617 */
618 public function plugin_row_meta( $plugin_meta, $plugin_file ) {
619
620 if ( tutor()->basename === $plugin_file ) {
621 $plugin_meta[] = sprintf(
622 '<a href="%s">%s</a>',
623 esc_url( 'https://docs.themeum.com/tutor-lms/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link' ),
624 __( '<strong style="color: #03bd24">Documentation</strong>', 'tutor' )
625 );
626 $plugin_meta[] = sprintf(
627 '<a href="%s">%s</a>',
628 esc_url( 'https://www.themeum.com/contact-us/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link' ),
629 __( '<strong style="color: #03bd24">Get Support</strong>', 'tutor' )
630 );
631 }
632
633 return $plugin_meta;
634 }
635
636 /**
637 * Add footer text only on tutor pages
638 *
639 * @since 1.0.0
640 *
641 * @param string $footer_text footer text.
642 * @return string
643 */
644 public function admin_footer_text( $footer_text ) {
645 $current_screen = get_current_screen();
646
647 /**
648 * We are making sure that this message will be only on Tutor Admin page
649 */
650 if ( apply_filters( 'tutor_display_admin_footer_text', ( tutor_utils()->array_get( 'parent_base', $current_screen ) === 'tutor' ) ) ) {
651 $footer_text = sprintf(
652 /* translators: %s: plugin name */
653 __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor' ),
654 sprintf( '<strong>%s</strong>', esc_html__( 'Tutor LMS', 'tutor' ) ),
655 '<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>'
656 );
657 }
658
659 return $footer_text;
660 }
661
662 /**
663 * Register course widget
664 *
665 * @since 1.0.0
666 * @return void
667 */
668 public function register_course_widget() {
669 register_widget( 'Tutor\Course_Widget' );
670 }
671
672 /**
673 * Tutor Course List
674 *
675 * @since 2.0.0
676 * @return void
677 */
678 public function tutor_course_list() {
679 include tutor()->path . 'views/pages/course-list.php';
680 }
681
682 /**
683 * Show welcome page
684 *
685 * @since 1.0.0
686 * @return void
687 */
688 public function welcome_page() {
689 Tutor_Setup::mark_as_visited();
690 include tutor()->path . 'views/pages/welcome.php';
691 exit;
692 }
693 }
694