PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.5.0
Tutor LMS – eLearning and online course solution v2.5.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 2 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 2 years ago Gutenberg.php 3 years ago Input.php 3 years ago Instructor.php 2 years ago Instructors_List.php 2 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 2 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 2 years ago Tutor_Setup.php 3 years ago Upgrader.php 2 years ago User.php 2 years ago Utils.php 2 years ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 2 years ago Withdraw_Requests_List.php 3 years ago WooCommerce.php 2 years ago
Admin.php
656 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', '\TUTOR\WhatsNew::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', __( 'Email', 'tutor' ), __( 'Email <span class="tutor-badge-new">Hot</span>', 'tutor' ), 'manage_tutor', 'new-key-feature', array( $this, 'feature_promotion_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 * Show Feature Promotion Page for Free User.
147 *
148 * @since 2.2.0
149 *
150 * @return void
151 */
152 public function feature_promotion_page() {
153 include tutor()->path . 'views/pages/feature-promotion.php';
154 }
155
156 /**
157 * Show students page
158 *
159 * @since 1.0.0
160 * @return void
161 */
162 public function tutor_students() {
163 include tutor()->path . 'views/pages/students.php';
164 }
165
166 /**
167 * Show instructor page
168 *
169 * @since 1.0.0
170 * @return void
171 */
172 public function tutor_instructors() {
173 include tutor()->path . 'views/pages/instructors.php';
174 }
175
176 /**
177 * Show announcements page
178 *
179 * @since 1.0.0
180 * @return void
181 */
182 public function tutor_announcements() {
183 include tutor()->path . 'views/pages/announcements.php';
184 }
185
186 /**
187 * Show Q&A page
188 *
189 * @since 1.0.0
190 * @return void
191 */
192 public function question_answer() {
193 include tutor()->path . 'views/pages/question_answer.php';
194 }
195
196 /**
197 * Show quiz attempts page
198 *
199 * @since 1.0.0
200 * @return void
201 */
202 public function quiz_attempts() {
203 include tutor()->path . 'views/pages/quiz_attempts.php';
204 }
205
206 /**
207 * Show the withdraw requests table
208 *
209 * @since 1.2.0
210 * @return void
211 */
212 public function withdraw_requests() {
213 include tutor()->path . 'views/pages/withdraw_requests.php';
214 }
215
216 /**
217 * Enable or disable addons
218 *
219 * @since 1.0.0
220 * @return void
221 */
222 public function enable_disable_addons() {
223
224 if ( defined( 'TUTOR_PRO_VERSION' ) ) {
225 include tutor()->path . 'views/pages/enable_disable_addons.php';
226 } else {
227 include tutor()->path . 'views/pages/tutor-pro-addons.php';
228 }
229 }
230
231 /**
232 * Tutor tools page (OLD)
233 *
234 * @since 1.0.0
235 * @return void
236 */
237 public function tutor_tools_old() {
238 $tutor_admin_tools_page = Input::get( 'tutor_admin_tools_page' );
239 if ( $tutor_admin_tools_page ) {
240 include apply_filters( 'tutor_admin_tools_page', tutor()->path . "views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page );
241 } else {
242 $pages = apply_filters(
243 'tutor_tool_pages',
244 array(
245 'tutor_pages' => array( 'title' => __( 'Tutor Pages', 'tutor' ) ),
246 'status' => __( 'Status', 'tutor' ),
247 )
248 );
249
250 $current_page = 'tutor_pages';
251 $requested_page = Input::get( 'sub_page' );
252 if ( $requested_page ) {
253 $current_page = $requested_page;
254 }
255
256 $current_page = str_replace( '/', '', $current_page );
257 $current_page = str_replace( '.', '', $current_page );
258 $current_page = str_replace( '\\', '', $current_page );
259 $current_page = trim( $current_page );
260
261 include tutor()->path . 'views/pages/tools.php';
262 }
263 }
264
265 /**
266 * Show pro upgrade page
267 *
268 * @since 1.0.0
269 * @return void
270 */
271 public function tutor_get_pro() {
272 include tutor()->path . 'views/pages/get-pro.php';
273 }
274
275 /**
276 * Parent menu active
277 *
278 * @since 1.0.0
279 *
280 * @param string $parent_file parent file.
281 * @return string
282 */
283 public function parent_menu_active( $parent_file ) {
284 $taxonomy = Input::get( 'taxonomy' );
285 if ( 'course-category' === $taxonomy || 'course-tag' === $taxonomy ) {
286 return 'tutor';
287 }
288
289 return $parent_file;
290 }
291
292 /**
293 * Sub-menu active
294 *
295 * @since 1.0.0
296 *
297 * @param string $submenu_file submenu file.
298 * @param string $parent_file parent file.
299 *
300 * @return string
301 */
302 public function submenu_file_active( $submenu_file, $parent_file ) {
303 $taxonomy = Input::get( 'taxonomy' );
304 $course_post_type = tutor()->course_post_type;
305
306 if ( 'course-category' === $taxonomy ) {
307 return 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type;
308 }
309 if ( 'course-tag' === $taxonomy ) {
310 return 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type;
311 }
312
313 return $submenu_file;
314 }
315
316 /**
317 * Filter posts for instructor
318 *
319 * @since 1.0.0
320 * @return void
321 */
322 public function filter_posts_for_instructors() {
323 if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
324 @remove_menu_page( 'edit-comments.php' ); // Comments.
325 add_filter( 'posts_clauses_request', array( $this, 'posts_clauses_request' ) );
326 }
327 }
328
329 /**
330 * Request for posts clauses
331 *
332 * @since 1.0.0
333 *
334 * @param mixed $clauses clauses.
335 * @return mixed
336 */
337 public function posts_clauses_request( $clauses ) {
338
339 if ( ! is_admin() || ( ! Input::has( 'post_type' ) || Input::get( 'post_type' ) != tutor()->course_post_type ) || tutor_utils()->has_user_role( array( 'administrator', 'editor' ) ) ) {
340 return $clauses;
341 }
342
343 // Need multi instructor check.
344 global $wpdb;
345
346 $user_id = get_current_user_id();
347
348 $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 ) );
349 $own_courses = is_array( $get_assigned_courses_ids ) ? $get_assigned_courses_ids : array();
350
351 $in_query_pre = count( $own_courses ) ? implode( ',', $own_courses ) : null;
352 $in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
353
354 $course_post_type = tutor()->course_post_type;
355 $custom_author_query = " AND ({$wpdb->posts}.post_type!='{$course_post_type}' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
356
357 $clauses['where'] .= $custom_author_query;
358
359 return $clauses;
360 }
361
362 /**
363 * Prevent unauthorised course/lesson edit page by direct URL
364 *
365 * @since 1.0.0
366 * @return void
367 */
368 public function check_if_current_users_post() {
369 if ( current_user_can( 'administrator' ) || ! current_user_can( tutor()->instructor_role ) ) {
370 return;
371 }
372
373 if ( ! empty( Input::get( 'post' ) ) ) {
374 $get_post_id = Input::get( 'post', Input::TYPE_INT );
375 $get_post = get_post( $get_post_id );
376 $tutor_post_types = array( tutor()->course_post_type, tutor()->lesson_post_type );
377
378 $current_user = get_current_user_id();
379
380 if ( in_array( $get_post->post_type, $tutor_post_types ) && $get_post->post_author != $current_user ) {
381 global $wpdb;
382
383 $get_assigned_courses_ids = (int) $wpdb->get_var(
384 $wpdb->prepare(
385 "SELECT user_id
386 from {$wpdb->usermeta}
387 WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ",
388 $current_user,
389 $get_post_id
390 )
391 );
392
393 if ( ! $get_assigned_courses_ids ) {
394 wp_die( esc_html__( 'Permission Denied', 'tutor' ) );
395 }
396 }
397 }
398 }
399
400 /**
401 * Scan template files
402 *
403 * @since 1.0.0
404 *
405 * @param string $template_path template file path.
406 * @return array
407 */
408 public static function scan_template_files( $template_path = null ) {
409 if ( ! $template_path ) {
410 $template_path = tutor()->path . 'templates/';
411 }
412
413 $files = @scandir($template_path); // @codingStandardsIgnoreLine.
414 $result = array();
415
416 if ( ! empty( $files ) ) {
417 foreach ( $files as $key => $value ) {
418 if ( ! in_array( $value, array( '.', '..', '.DS_Store' ), true ) ) {
419 if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
420 $sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
421 foreach ( $sub_files as $sub_file ) {
422 $result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
423 }
424 } else {
425 $result[] = $value;
426 }
427 }
428 }
429 }
430 return $result;
431 }
432
433 /**
434 * Get Template overridden files
435 *
436 * @since 1.0.0
437 * @return array
438 */
439 public static function template_overridden_files() {
440 $template_files = self::scan_template_files();
441
442 $override_files = array();
443 foreach ( $template_files as $file ) {
444 $file_path = null;
445 if ( file_exists( trailingslashit( get_stylesheet_directory() ) . tutor()->template_path . $file ) ) {
446 $file_path = $file;
447 } elseif ( file_exists( trailingslashit( get_template_directory() ) . tutor()->template_path . $file ) ) {
448 $file_path = $file;
449 }
450
451 if ( $file_path ) {
452 $override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $file_path );
453 }
454 }
455
456 return $override_files;
457 }
458
459 /**
460 * Erase tutor data
461 *
462 * @since 1.0.0
463 * @return void
464 */
465 public function erase_tutor_data() {
466 global $wpdb;
467
468 $is_erase_data = tutor_utils()->get_option( 'delete_on_uninstall' );
469 // Deleting Data.
470
471 $plugin_file = tutor()->basename;
472 if ( $is_erase_data && current_user_can( 'deactivate_plugin', $plugin_file ) ) {
473 /**
474 * Deleting Post Type, Meta Data, taxonomy
475 */
476 $course_post_type = tutor()->course_post_type;
477 $lesson_post_type = tutor()->lesson_post_type;
478
479 $post_types = array(
480 $course_post_type,
481 $lesson_post_type,
482 'tutor_quiz',
483 'tutor_enrolled',
484 'topics',
485 'tutor_enrolled',
486 'tutor_announcements',
487 );
488
489 $post_type_strings = "'" . implode( "','", $post_types ) . "'";
490 $tutor_posts = $wpdb->get_col( "SELECT ID from {$wpdb->posts} WHERE post_type in({$post_type_strings}) ;" ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
491
492 if ( is_array( $tutor_posts ) && count( $tutor_posts ) ) {
493 foreach ( $tutor_posts as $post_id ) {
494 // Delete categories.
495 $terms = wp_get_object_terms( $post_id, 'course-category' );
496 foreach ( $terms as $term ) {
497 wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-category' );
498 }
499
500 // Delete tags if available.
501 $terms = wp_get_object_terms( $post_id, 'course-tag' );
502 foreach ( $terms as $term ) {
503 wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-tag' );
504 }
505
506 // Delete All Meta.
507 $wpdb->delete( $wpdb->postmeta, array( 'post_id' => $post_id ) );
508 $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
509 }
510 }
511
512 /**
513 * Deleting Comments (reviews, questions, quiz_answers, etc)
514 */
515 $tutor_comments = $wpdb->get_col( "SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;" );
516 $comments_ids_strings = "'" . implode( "','", $tutor_comments ) . "'";
517 if ( is_array( $tutor_comments ) && count( $tutor_comments ) ) {
518 $wpdb->query( "DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$comments_ids_strings}) " ); //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
519 }
520 $wpdb->delete( $wpdb->comments, array( 'comment_agent' => 'comment_agent' ) );
521
522 /**
523 * Delete Options
524 */
525
526 delete_option( 'tutor_option' );
527 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_student' ) );
528 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_approved' ) );
529 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_tutor_instructor_status' ) );
530 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => '_is_tutor_instructor' ) );
531 $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' " );
532
533 // Deleting Table.
534 $prefix = $wpdb->prefix;
535 //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
536 $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 " );
537
538 deactivate_plugins( $plugin_file );
539 }
540
541 wp_redirect( 'plugins.php' );
542 die();
543 }
544
545 /**
546 * Plugin activation link
547 *
548 * @since 1.0.0
549 *
550 * @param array $actions action list.
551 * @return array
552 */
553 public function plugin_action_links( $actions ) {
554 $has_pro = tutor()->has_pro;
555
556 if ( ! $has_pro ) {
557 $actions['tutor_pro_link'] =
558 '<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">
559 <span style="color: #ff7742; font-weight: bold;">' .
560 __( 'Upgrade to Pro', 'wp-megamenu' ) .
561 '</span>
562 </a>';
563 }
564
565 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __( 'Settings', 'tutor' ) . '</a>';
566
567 return $actions;
568 }
569
570 /**
571 * Add plugin meta data in WP plugins list page
572 *
573 * @since 1.0.0
574 *
575 * @param array $plugin_meta plugin meta data.
576 * @param string $plugin_file plugin file.
577 *
578 * @return array
579 */
580 public function plugin_row_meta( $plugin_meta, $plugin_file ) {
581
582 if ( tutor()->basename === $plugin_file ) {
583 $plugin_meta[] = sprintf(
584 '<a href="%s">%s</a>',
585 esc_url( 'https://docs.themeum.com/tutor-lms/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link' ),
586 __( '<strong style="color: #03bd24">Documentation</strong>', 'tutor' )
587 );
588 $plugin_meta[] = sprintf(
589 '<a href="%s">%s</a>',
590 esc_url( 'https://www.themeum.com/contact-us/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link' ),
591 __( '<strong style="color: #03bd24">Get Support</strong>', 'tutor' )
592 );
593 }
594
595 return $plugin_meta;
596 }
597
598 /**
599 * Add footer text only on tutor pages
600 *
601 * @since 1.0.0
602 *
603 * @param string $footer_text footer text.
604 * @return string
605 */
606 public function admin_footer_text( $footer_text ) {
607 $current_screen = get_current_screen();
608
609 /**
610 * We are making sure that this message will be only on Tutor Admin page
611 */
612 if ( apply_filters( 'tutor_display_admin_footer_text', ( tutor_utils()->array_get( 'parent_base', $current_screen ) === 'tutor' ) ) ) {
613 $footer_text = sprintf(
614 /* translators: %s: plugin name */
615 __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor' ),
616 sprintf( '<strong>%s</strong>', esc_html__( 'Tutor LMS', 'tutor' ) ),
617 '<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>'
618 );
619 }
620
621 return $footer_text;
622 }
623
624 /**
625 * Register course widget
626 *
627 * @since 1.0.0
628 * @return void
629 */
630 public function register_course_widget() {
631 register_widget( 'Tutor\Course_Widget' );
632 }
633
634 /**
635 * Tutor Course List
636 *
637 * @since 2.0.0
638 * @return void
639 */
640 public function tutor_course_list() {
641 include tutor()->path . 'views/pages/course-list.php';
642 }
643
644 /**
645 * Show welcome page
646 *
647 * @since 1.0.0
648 * @return void
649 */
650 public function welcome_page() {
651 Tutor_Setup::mark_as_visited();
652 include tutor()->path . 'views/pages/welcome.php';
653 exit;
654 }
655 }
656