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