PluginProbe
Tutor LMS – eLearning and online course solution / 3.9.2
Tutor LMS – eLearning and online course solution v3.9.2
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 3.9.2, at classes/Admin.php

857 lines 24.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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\Ecommerce\OrderController;
14 use Tutor\Helpers\HttpHelper;
15 use TUTOR\Input;
16 use Tutor\Models\CourseModel;
17 use Tutor\Traits\JsonResponse;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 /**
24 * Admin Class
25 *
26 * @since 1.0.0
27 */
28 class Admin {
29 use JsonResponse;
30
31 /**
32 * Constructor
33 *
34 * @since 1.0.0
35 * @return void
36 */
37 public function __construct() {
38
39 add_action( 'admin_notices', array( $this, 'show_unstable_version_admin_notice' ) );
40
41 add_action( 'admin_menu', array( $this, 'register_menu' ) );
42 // Force activate menu for necessary.
43 add_filter( 'parent_file', array( $this, 'parent_menu_active' ) );
44 add_filter( 'submenu_file', array( $this, 'submenu_file_active' ), 10, 2 );
45
46 add_action( 'admin_init', array( $this, 'filter_posts_for_instructors' ) );
47 add_action( 'load-post.php', array( $this, 'check_if_current_users_post' ) );
48
49 add_filter( 'plugin_action_links_' . plugin_basename( TUTOR_FILE ), array( $this, 'plugin_action_links' ) );
50
51 // Plugin Row Meta.
52 add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
53
54 // Admin Footer Text.
55 add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
56 // Register Course Widget.
57 add_action( 'widgets_init', array( $this, 'register_course_widget' ) );
58
59 // Handle flash toast message for redirect_to util helper.
60 add_action( 'admin_head', array( new Utils(), 'handle_flash_message' ), 999 );
61
62 add_action( 'admin_bar_menu', array( $this, 'add_toolbar_items' ), 100 );
63
64 add_action( 'wp_ajax_tutor_do_not_show_feature_page', array( $this, 'handle_do_not_show_feature_page' ) );
65 }
66
67 /**
68 * Show unstable version notice.
69 *
70 * @since 3.0.0
71 *
72 * @return void
73 */
74 public function show_unstable_version_admin_notice() {
75 $version = tutor_utils()->extract_version_details( TUTOR_VERSION );
76 if ( ! $version->is_stable ) {
77 /* translators: %s: version name */
78 $message = sprintf( __( 'You\'re currently using Tutor LMS %s. To ensure stability, please do not use it on a live site.', 'tutor' ), '<strong>' . $version->version . '</strong>' );
79 ?>
80 <div class="notice notice-warning">
81 <p><strong><?php esc_html_e( 'Warning!', 'tutor' ); ?></strong></p>
82 <p><?php echo wp_kses_post( $message ); ?></p>
83 </div>
84 <?php
85 }
86 }
87
88 /**
89 * Register admin menus
90 *
91 * @since 1.0.0
92 * @since 3.8.0 re-organize admin menu.
93 *
94 * @return void
95 */
96 public function register_menu() {
97 $has_pro = tutor()->has_pro;
98
99 $unanswered_questions = tutor_utils()->unanswered_question_count();
100 $unanswered_bubble = '';
101 if ( $unanswered_questions ) {
102 $unanswered_bubble = '<span class="update-plugins count-' . $unanswered_questions . '"><span class="plugin-count">' . $unanswered_questions . '</span></span>';
103 }
104
105 $course_post_type = tutor()->course_post_type;
106
107 $pro_text = '';
108 if ( $has_pro ) {
109 $pro_text = ' ' . apply_filters( 'tutor_pro_flag', __( 'Pro', 'tutor' ) );
110 }
111
112 $enable_course_marketplace = (bool) tutor_utils()->get_option( 'enable_course_marketplace' );
113
114 $welcome = Tutor_Setup::is_welcome_page_visited();
115
116 $root_page = array( $this, 'tutor_course_list' );
117 if ( false === $welcome && Input::has( 'page' ) && 'tutor' === Input::get( 'page' ) && Input::has( 'welcome' ) ) {
118 $root_page = array( $this, 'welcome_page' );
119 }
120
121 $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>' );
122 $menu_position = 2;
123
124 add_menu_page(
125 __( 'Tutor LMS', 'tutor' ) . $pro_text,
126 __( 'Tutor LMS', 'tutor' ) . $pro_text,
127 'manage_tutor_instructor',
128 'tutor',
129 $root_page,
130 $icon_base64_uri,
131 $menu_position
132 );
133
134 new WhatsNew();
135
136 $admin_menu = apply_filters(
137 'tutor_admin_menu',
138 array(
139 'group_one' => array(
140 'courses' => array(
141 'parent_slug' => 'tutor',
142 'page_title' => __( 'Courses', 'tutor' ),
143 'menu_title' => __( 'Courses', 'tutor' ),
144 'capability' => 'manage_tutor_instructor',
145 'menu_slug' => 'tutor',
146 'callback' => array( $this, 'tutor_course_list' ),
147 ),
148 'content_bank' => null,
149 'course_builder' => array(
150 'parent_slug' => 'tutor',
151 'page_title' => __( 'Course Builder', 'tutor' ),
152 'menu_title' => '<span class="tutor-create-course">Create Course</span>',
153 'capability' => 'manage_tutor_instructor',
154 'menu_slug' => 'create-course',
155 'callback' => array( new Course( false ), 'load_course_builder' ),
156 ),
157 'categories' => array(
158 'parent_slug' => 'tutor',
159 'page_title' => __( 'Categories', 'tutor' ),
160 'menu_title' => __( 'Categories', 'tutor' ),
161 'capability' => 'manage_tutor',
162 'menu_slug' => 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type,
163 ),
164 'tags' => array(
165 'parent_slug' => 'tutor',
166 'page_title' => __( 'Tags', 'tutor' ),
167 'menu_title' => __( 'Tags', 'tutor' ),
168 'capability' => 'manage_tutor',
169 'menu_slug' => 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type,
170 ),
171 ),
172 'group_two' => array(
173 'orders' => null,
174 'subscriptions' => null,
175 'coupons' => null,
176 'students' => array(
177 'parent_slug' => 'tutor',
178 'page_title' => __( 'Students', 'tutor' ),
179 'menu_title' => __( 'Students', 'tutor' ),
180 'capability' => 'manage_tutor',
181 'menu_slug' => Students_List::STUDENTS_LIST_PAGE,
182 'callback' => array( $this, 'tutor_students' ),
183
184 ),
185 'announcements' => array(
186 'parent_slug' => 'tutor',
187 'page_title' => __( 'Announcements', 'tutor' ),
188 'menu_title' => __( 'Announcements', 'tutor' ),
189 'capability' => 'manage_tutor_instructor',
190 'menu_slug' => 'tutor_announcements',
191 'callback' => array( $this, 'tutor_announcements' ),
192
193 ),
194 'assignments' => null,
195 'quiz_attempts' => array(
196 'parent_slug' => 'tutor',
197 'page_title' => __( 'Quiz Attempts', 'tutor' ),
198 'menu_title' => __( 'Quiz Attempts', 'tutor' ),
199 'capability' => 'manage_tutor_instructor',
200 'menu_slug' => Quiz_Attempts_List::QUIZ_ATTEMPT_PAGE,
201 'callback' => array( $this, 'quiz_attempts' ),
202 ),
203 'q_and_a' => array(
204 'parent_slug' => 'tutor',
205 'page_title' => __( 'Q&A', 'tutor' ),
206 'menu_title' => __( 'Q&A ', 'tutor' ) . $unanswered_bubble,
207 'capability' => 'manage_tutor_instructor',
208 'menu_slug' => Question_Answers_List::QUESTION_ANSWER_PAGE,
209 'callback' => array( $this, 'question_answer' ),
210 ),
211 'enrollments' => null,
212 'reports' => null,
213 'gradebook' => null,
214 'instructors' => $enable_course_marketplace ? array(
215 'parent_slug' => 'tutor',
216 'page_title' => __( 'Instructors', 'tutor' ),
217 'menu_title' => __( 'Instructors', 'tutor' ),
218 'capability' => 'manage_tutor',
219 'menu_slug' => Instructors_List::INSTRUCTOR_LIST_PAGE,
220 'callback' => array( $this, 'tutor_instructors' ),
221 ) : null,
222 'withdraw_requests' => $enable_course_marketplace ? array(
223 'parent_slug' => 'tutor',
224 'page_title' => __( 'Withdraw Requests', 'tutor' ),
225 'menu_title' => __( 'Withdraw Requests', 'tutor' ),
226 'capability' => 'manage_tutor',
227 'menu_slug' => Withdraw_Requests_List::WITHDRAW_REQUEST_LIST_PAGE,
228 'callback' => array( $this, 'withdraw_requests' ),
229 ) : null,
230 ),
231 'group_three' => array(
232 'google_classroom' => null,
233 'zoom' => null,
234 'google_meet' => null,
235 'h5p' => null,
236 'themes' => array(
237 'parent_slug' => 'tutor',
238 'page_title' => __( 'Themes', 'tutor' ),
239 'menu_title' => __( 'Themes', 'tutor' ),
240 'capability' => 'manage_tutor',
241 'menu_slug' => 'tutor-themes',
242 'callback' => array( $this, 'tutor_themes' ),
243 ),
244 'addons' => array(
245 'parent_slug' => 'tutor',
246 'page_title' => __( 'Addons', 'tutor' ),
247 'menu_title' => __( 'Addons', 'tutor' ),
248 'capability' => 'manage_tutor',
249 'menu_slug' => 'tutor-addons',
250 'callback' => array( $this, 'enable_disable_addons' ),
251 ),
252 'tools' => array(
253 'parent_slug' => 'tutor',
254 'page_title' => __( 'Tools', 'tutor' ),
255 'menu_title' => __( 'Tools', 'tutor' ),
256 'capability' => 'manage_tutor',
257 'menu_slug' => 'tutor-tools',
258 'callback' => array( new Tools_V2(), 'load_tools_page' ),
259 ),
260 'settings' => array(
261 'parent_slug' => 'tutor',
262 'page_title' => __( 'Settings', 'tutor' ),
263 'menu_title' => __( 'Settings', 'tutor' ),
264 'capability' => 'manage_tutor',
265 'menu_slug' => 'tutor_settings',
266 'callback' => array( new Options_V2(), 'load_settings_page' ),
267 ),
268 'license' => null,
269 'whats_new' => null,
270 'upgrade_to_pro' => $has_pro ? null : array(
271 'parent_slug' => 'tutor',
272 'page_title' => __( 'Upgrade to Pro', 'tutor' ),
273 'menu_title' => sprintf( '<span class="tutor-get-pro-text">%s</span>', __( 'Upgrade to Pro', 'tutor' ) ),
274 'capability' => 'manage_options',
275 'menu_slug' => 'tutor-get-pro',
276 'callback' => array( $this, 'tutor_get_pro' ),
277 ),
278 ),
279 )
280 );
281
282 foreach ( $admin_menu as $group => $menu ) {
283 foreach ( $menu as $name => $args ) {
284 if ( empty( $args ) ) {
285 continue;
286 }
287
288 // Backward compatibility hook.
289 if ( 'addons' === $name ) {
290 do_action( 'tutor_admin_register' );
291 }
292
293 // Backward compatibility hook.
294 do_action( "tutor_before_{$name}_admin_menu" );
295
296 do_action( "tutor_before_{$name}_menu" );
297 add_submenu_page( $args['parent_slug'], $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['callback'] ?? '', $args['position'] ?? null );
298
299 // Backward compatibility hook.
300 do_action( "tutor_after_{$name}_menu" );
301
302 do_action( "tutor_after_{$name}_admin_menu" );
303 }
304
305 if ( 'group_three' !== $group ) {
306 if ( 'group_two' === $group && ! current_user_can( 'manage_options' ) ) {
307 continue;
308 }
309
310 add_submenu_page( 'tutor', '', '<span class="tutor-admin-menu-separator"></span>', 'manage_tutor_instructor', '#' );
311 }
312 }
313 }
314
315 /**
316 * Tutor template view
317 *
318 * @since 3.6.0
319 */
320 public function tutor_themes() {
321 include tutor()->path . 'views/template-import/templates.php';
322 }
323
324 /**
325 * Welcome page opt-out
326 *
327 * @since 3.0.0
328 */
329 public function handle_do_not_show_feature_page() {
330 tutor_utils()->check_nonce();
331
332 if ( ! User::is_admin() ) {
333 $this->json_response(
334 tutor_utils()->error_message(),
335 null,
336 HttpHelper::STATUS_BAD_REQUEST
337 );
338 }
339
340 update_option( 'tutor-new-feature', '3.0.0' );
341 $this->json_response( __( 'Success', 'tutor' ) );
342 }
343
344 /**
345 * Show Feature Promotion Page for Free User.
346 *
347 * @since 2.2.0
348 *
349 * @return void
350 */
351 public function feature_promotion_page() {
352 include tutor()->path . 'views/pages/welcome.php';
353 // include tutor()->path . 'views/pages/feature-promotion.php';
354 }
355
356 /**
357 * Show students page
358 *
359 * @since 1.0.0
360 * @return void
361 */
362 public function tutor_students() {
363 include tutor()->path . 'views/pages/students.php';
364 }
365
366 /**
367 * Show instructor page
368 *
369 * @since 1.0.0
370 * @return void
371 */
372 public function tutor_instructors() {
373 include tutor()->path . 'views/pages/instructors.php';
374 }
375
376 /**
377 * Show announcements page
378 *
379 * @since 1.0.0
380 * @return void
381 */
382 public function tutor_announcements() {
383 include tutor()->path . 'views/pages/announcements.php';
384 }
385
386 /**
387 * Show Q&A page
388 *
389 * @since 1.0.0
390 * @return void
391 */
392 public function question_answer() {
393 include tutor()->path . 'views/pages/question_answer.php';
394 }
395
396 /**
397 * Show quiz attempts page
398 *
399 * @since 1.0.0
400 * @return void
401 */
402 public function quiz_attempts() {
403 include tutor()->path . 'views/pages/quiz_attempts.php';
404 }
405
406 /**
407 * Show the withdraw requests table
408 *
409 * @since 1.2.0
410 * @return void
411 */
412 public function withdraw_requests() {
413 include tutor()->path . 'views/pages/withdraw_requests.php';
414 }
415
416 /**
417 * Enable or disable addons
418 *
419 * @since 1.0.0
420 * @return void
421 */
422 public function enable_disable_addons() {
423 include tutor()->path . 'views/pages/enable_disable_addons.php';
424 }
425
426 /**
427 * Tutor tools page (OLD)
428 *
429 * @since 1.0.0
430 * @return void
431 */
432 public function tutor_tools_old() {
433 $tutor_admin_tools_page = Input::get( 'tutor_admin_tools_page' );
434 if ( $tutor_admin_tools_page ) {
435 include apply_filters( 'tutor_admin_tools_page', tutor()->path . "views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page );
436 } else {
437 $pages = apply_filters(
438 'tutor_tool_pages',
439 array(
440 'tutor_pages' => array( 'title' => __( 'Tutor Pages', 'tutor' ) ),
441 'status' => __( 'Status', 'tutor' ),
442 )
443 );
444
445 $current_page = 'tutor_pages';
446 $requested_page = Input::get( 'sub_page' );
447 if ( $requested_page ) {
448 $current_page = $requested_page;
449 }
450
451 $current_page = str_replace( '/', '', $current_page );
452 $current_page = str_replace( '.', '', $current_page );
453 $current_page = str_replace( '\\', '', $current_page );
454 $current_page = trim( $current_page );
455
456 include tutor()->path . 'views/pages/tools.php';
457 }
458 }
459
460 /**
461 * Show pro upgrade page
462 *
463 * @since 1.0.0
464 * @return void
465 */
466 public function tutor_get_pro() {
467 include tutor()->path . 'views/pages/get-pro.php';
468 }
469
470 /**
471 * Parent menu active
472 *
473 * @since 1.0.0
474 *
475 * @param string $parent_file parent file.
476 * @return string
477 */
478 public function parent_menu_active( $parent_file ) {
479 $taxonomy = Input::get( 'taxonomy' );
480 if ( CourseModel::COURSE_CATEGORY === $taxonomy || CourseModel::COURSE_TAG === $taxonomy ) {
481 return 'tutor';
482 }
483
484 return $parent_file;
485 }
486
487 /**
488 * Sub-menu active
489 *
490 * @since 1.0.0
491 *
492 * @param string $submenu_file submenu file.
493 * @param string $parent_file parent file.
494 *
495 * @return string
496 */
497 public function submenu_file_active( $submenu_file, $parent_file ) {
498 $taxonomy = Input::get( 'taxonomy' );
499 $course_post_type = tutor()->course_post_type;
500
501 if ( CourseModel::COURSE_CATEGORY === $taxonomy ) {
502 return 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type;
503 }
504 if ( CourseModel::COURSE_TAG === $taxonomy ) {
505 return 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type;
506 }
507
508 return $submenu_file;
509 }
510
511 /**
512 * Filter posts for instructor
513 *
514 * @since 1.0.0
515 * @return void
516 */
517 public function filter_posts_for_instructors() {
518 if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
519 @remove_menu_page( 'edit-comments.php' ); // Comments.
520 add_filter( 'posts_clauses_request', array( $this, 'posts_clauses_request' ) );
521 }
522 }
523
524 /**
525 * Request for posts clauses
526 *
527 * @since 1.0.0
528 *
529 * @param mixed $clauses clauses.
530 * @return mixed
531 */
532 public function posts_clauses_request( $clauses ) {
533
534 if ( ! is_admin() || ( ! Input::has( 'post_type' ) || Input::get( 'post_type' ) != tutor()->course_post_type ) || tutor_utils()->has_user_role( array( 'administrator', 'editor' ) ) ) {
535 return $clauses;
536 }
537
538 // Need multi instructor check.
539 global $wpdb;
540
541 $user_id = get_current_user_id();
542
543 $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 ) );
544 $own_courses = is_array( $get_assigned_courses_ids ) ? $get_assigned_courses_ids : array();
545
546 $in_query_pre = count( $own_courses ) ? implode( ',', $own_courses ) : null;
547 $in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
548
549 $course_post_type = tutor()->course_post_type;
550 $custom_author_query = " AND ({$wpdb->posts}.post_type!='{$course_post_type}' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
551
552 $clauses['where'] .= $custom_author_query;
553
554 return $clauses;
555 }
556
557 /**
558 * Prevent unauthorised course/lesson edit page by direct URL
559 *
560 * @since 1.0.0
561 * @return void
562 */
563 public function check_if_current_users_post() {
564 if ( current_user_can( 'administrator' ) || ! current_user_can( tutor()->instructor_role ) ) {
565 return;
566 }
567
568 if ( ! empty( Input::get( 'post' ) ) ) {
569 $get_post_id = Input::get( 'post', Input::TYPE_INT );
570 $get_post = get_post( $get_post_id );
571 $tutor_post_types = array( tutor()->course_post_type, tutor()->lesson_post_type );
572
573 $current_user = get_current_user_id();
574
575 if ( in_array( $get_post->post_type, $tutor_post_types ) && $get_post->post_author != $current_user ) {
576 global $wpdb;
577
578 $get_assigned_courses_ids = (int) $wpdb->get_var(
579 $wpdb->prepare(
580 "SELECT user_id
581 from {$wpdb->usermeta}
582 WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ",
583 $current_user,
584 $get_post_id
585 )
586 );
587
588 if ( ! $get_assigned_courses_ids ) {
589 wp_die( esc_html__( 'Permission Denied', 'tutor' ) );
590 }
591 }
592 }
593 }
594
595 /**
596 * Scan template files
597 *
598 * @since 1.0.0
599 *
600 * @param string $template_path template file path.
601 * @return array
602 */
603 public static function scan_template_files( $template_path = null ) {
604 if ( ! $template_path ) {
605 $template_path = tutor()->path . 'templates/';
606 }
607
608 $files = @scandir($template_path); // @codingStandardsIgnoreLine.
609 $result = array();
610
611 if ( ! empty( $files ) ) {
612 foreach ( $files as $key => $value ) {
613 if ( ! in_array( $value, array( '.', '..', '.DS_Store' ), true ) ) {
614 if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
615 $sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
616 foreach ( $sub_files as $sub_file ) {
617 $result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
618 }
619 } else {
620 $result[] = $value;
621 }
622 }
623 }
624 }
625 return $result;
626 }
627
628 /**
629 * Get Template overridden files
630 *
631 * @since 1.0.0
632 * @return array
633 */
634 public static function template_overridden_files() {
635 $template_files = self::scan_template_files();
636
637 $override_files = array();
638 foreach ( $template_files as $file ) {
639 $file_path = null;
640 if ( file_exists( trailingslashit( get_stylesheet_directory() ) . tutor()->template_path . $file ) ) {
641 $file_path = $file;
642 } elseif ( file_exists( trailingslashit( get_template_directory() ) . tutor()->template_path . $file ) ) {
643 $file_path = $file;
644 }
645
646 if ( $file_path ) {
647 $override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $file_path );
648 }
649 }
650
651 return $override_files;
652 }
653
654 /**
655 * Plugin activation link
656 *
657 * @since 1.0.0
658 *
659 * @param array $actions action list.
660 * @return array
661 */
662 public function plugin_action_links( $actions ) {
663 $has_pro = tutor()->has_pro;
664
665 if ( ! $has_pro ) {
666 $actions['tutor_pro_link'] =
667 '<a href="https://tutorlms.com/pricing?utm_source=tutor_plugin_action_link&utm_medium=wordpress_dashboard&utm_campaign=go_premium" target="_blank">
668 <span style="color: #ff7742; font-weight: bold;">' .
669 __( 'Upgrade to Pro', 'tutor' ) .
670 '</span>
671 </a>';
672 }
673
674 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __( 'Settings', 'tutor' ) . '</a>';
675
676 return $actions;
677 }
678
679 /**
680 * Add plugin meta data in WP plugins list page
681 *
682 * @since 1.0.0
683 *
684 * @param array $plugin_meta plugin meta data.
685 * @param string $plugin_file plugin file.
686 *
687 * @return array
688 */
689 public function plugin_row_meta( $plugin_meta, $plugin_file ) {
690
691 if ( tutor()->basename === $plugin_file ) {
692 $plugin_meta[] = sprintf(
693 '<a href="%s"><strong style="color: #03bd24">%s</strong></a>',
694 esc_url( 'https://docs.themeum.com/tutor-lms/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link' ),
695 esc_html__( 'Documentation', 'tutor' )
696 );
697 $plugin_meta[] = sprintf(
698 '<a href="%s"><strong style="color: #03bd24">%s</strong></a>',
699 esc_url( 'https://tutorlms.com/support/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link' ),
700 esc_html__( 'Get Support', 'tutor' )
701 );
702 }
703
704 return $plugin_meta;
705 }
706
707 /**
708 * Add footer text only on tutor pages
709 *
710 * @since 1.0.0
711 *
712 * @param string $footer_text footer text.
713 * @return string
714 */
715 public function admin_footer_text( $footer_text ) {
716 $current_screen = get_current_screen();
717
718 /**
719 * We are making sure that this message will be only on Tutor Admin page
720 */
721 if ( apply_filters( 'tutor_display_admin_footer_text', ( tutor_utils()->array_get( 'parent_base', $current_screen ) === 'tutor' ) ) ) {
722 $footer_text = sprintf(
723 /* translators: %s: plugin name */
724 __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor' ),
725 sprintf( '<strong>%s</strong>', esc_html__( 'Tutor LMS', 'tutor' ) ),
726 '<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>'
727 );
728 }
729
730 return $footer_text;
731 }
732
733 /**
734 * Register course widget
735 *
736 * @since 1.0.0
737 * @return void
738 */
739 public function register_course_widget() {
740 register_widget( Course_Widget::class );
741 }
742
743 /**
744 * Tutor Course List
745 *
746 * @since 2.0.0
747 * @return void
748 */
749 public function tutor_course_list() {
750 include tutor()->path . 'views/pages/course-list.php';
751 }
752
753 /**
754 * Orders view page
755 *
756 * @since 3.0.0
757 *
758 * @return void
759 */
760 public function orders_view() {
761 $current_page = Input::get( 'page' );
762 $action = Input::get( 'action' );
763
764 if ( OrderController::PAGE_SLUG === $current_page && 'edit' === $action ) {
765 ?>
766 <div class="tutor-admin-wrap tutor-order-details-wrapper">
767 <div id="tutor-order-details-root">
768 </div>
769 </div>
770 <?php
771 return;
772 }
773
774 include tutor()->path . 'views/pages/ecommerce/order-list.php';
775 }
776
777 /**
778 * Coupons view page
779 *
780 * @since 3.0.0
781 *
782 * @return void
783 */
784 public function coupons_view() {
785 $action = Input::get( 'action' );
786 if ( in_array( $action, array( 'add_new', 'edit' ) ) ) {
787 ?>
788 <div class="tutor-admin-wrap">
789 <div id="tutor-coupon-root">
790 </div>
791 </div>
792 <?php
793 return;
794 }
795 include tutor()->path . 'views/pages/ecommerce/coupon-list.php';
796 }
797
798 /**
799 * Show welcome page
800 *
801 * @since 1.0.0
802 * @return void
803 */
804 public function welcome_page() {
805 Tutor_Setup::mark_as_visited();
806 include tutor()->path . 'views/pages/welcome.php';
807 exit;
808 }
809
810 /**
811 * Add toolbar items
812 *
813 * @since 1.4.6
814 *
815 * @param \WP_Admin_Bar $admin_bar admin bar object.
816 *
817 * @return mixed
818 */
819 public function add_toolbar_items( \WP_Admin_Bar $admin_bar ) {
820 global $post;
821
822 $course_id = Input::get( 'post', 0, Input::TYPE_INT );
823 $course_post_type = tutor()->course_post_type;
824
825 if ( $admin_bar->get_node( 'new-courses' ) ) {
826 $args = $admin_bar->get_node( 'new-courses' );
827 $args->href = '#';
828 $args->meta['class'] = 'tutor-create-new-course';
829 $admin_bar->add_node( $args );
830 }
831
832 if ( ! tutor_utils()->can_user_edit_course( get_current_user_id(), $course_id ) ) {
833 return $admin_bar;
834 }
835
836 if (
837 ( is_admin() && $post && $course_id && $post->post_type === $course_post_type ) ||
838 ( ! is_admin() && is_single() && $post && $course_post_type === $post->post_type )
839 ) {
840
841 $admin_bar->add_menu(
842 array(
843 'id' => 'edit',
844 'title' => __( 'Edit with Course Builder', 'tutor' ),
845 'href' => tutor_utils()->course_edit_link( $post->ID ),
846 'meta' => array(
847 'title' => __( 'Edit with Course Builder', 'tutor' ),
848 'target' => '_blank',
849 ),
850 )
851 );
852 }
853
854 return $admin_bar;
855 }
856 }
857