PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.5.0
Tutor LMS – eLearning and online course solution v3.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 1 year ago Admin.php 1 year ago Ajax.php 1 year ago Announcements.php 1 year ago Assets.php 1 year ago Backend_Page_Trait.php 1 year ago BaseController.php 1 year ago Course.php 1 year ago Course_Embed.php 3 years ago Course_Filter.php 1 year ago Course_List.php 1 year ago Course_Settings_Tabs.php 1 year ago Course_Widget.php 1 year ago Custom_Validation.php 3 years ago Dashboard.php 1 year ago Earnings.php 1 year ago FormHandler.php 2 years ago Frontend.php 1 year ago Gutenberg.php 1 year ago Input.php 1 year ago Instructor.php 1 year ago Instructors_List.php 1 year ago Lesson.php 1 year ago Options_V2.php 1 year ago Permalink.php 2 years ago Post_types.php 1 year ago Private_Course_Access.php 1 year ago Q_And_A.php 1 year ago Question_Answers_List.php 3 years ago Quiz.php 1 year ago QuizBuilder.php 1 year ago Quiz_Attempts_List.php 1 year ago RestAPI.php 2 years ago Reviews.php 3 years ago Rewrite_Rules.php 2 years ago Shortcode.php 1 year ago Singleton.php 1 year ago Student.php 1 year ago Students_List.php 1 year ago Taxonomies.php 1 year ago Template.php 1 year ago Theme_Compatibility.php 3 years ago Tools.php 1 year ago Tools_V2.php 1 year ago Tutor.php 1 year ago TutorEDD.php 1 year ago Tutor_Base.php 2 years ago Tutor_Setup.php 1 year ago Upgrader.php 1 year ago User.php 1 year ago Utils.php 1 year ago Video_Stream.php 3 years ago WhatsNew.php 2 years ago Withdraw.php 1 year ago Withdraw_Requests_List.php 1 year ago WooCommerce.php 1 year ago
Admin.php
713 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\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 // add_action( 'tutor_after_settings_menu', '\TUTOR\WhatsNew::whats_new_menu', 11 );
62
63 add_action( 'admin_bar_menu', array( $this, 'add_toolbar_items' ), 100 );
64
65 add_action( 'wp_ajax_tutor_do_not_show_feature_page', array( $this, 'handle_do_not_show_feature_page' ) );
66 }
67
68 /**
69 * Show unstable version notice.
70 *
71 * @since 3.0.0
72 *
73 * @return void
74 */
75 public function show_unstable_version_admin_notice() {
76 $version = tutor_utils()->extract_version_details( TUTOR_VERSION );
77 if ( ! $version->is_stable ) {
78 /* translators: %s: version name */
79 $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>' );
80 ?>
81 <div class="notice notice-warning">
82 <p><strong><?php esc_html_e( 'Warning!', 'tutor' ); ?></strong></p>
83 <p><?php echo wp_kses_post( $message ); ?></p>
84 </div>
85 <?php
86 }
87 }
88
89 /**
90 * Register admin menus
91 *
92 * @since 1.0.0
93 * @return void
94 */
95 public function register_menu() {
96 $has_pro = tutor()->has_pro;
97
98 $unanswered_questions = tutor_utils()->unanswered_question_count();
99 $unanswered_bubble = '';
100 if ( $unanswered_questions ) {
101 $unanswered_bubble = '<span class="update-plugins count-' . $unanswered_questions . '"><span class="plugin-count">' . $unanswered_questions . '</span></span>';
102 }
103
104 $course_post_type = tutor()->course_post_type;
105
106 $pro_text = '';
107 if ( $has_pro ) {
108 $pro_text = ' ' . apply_filters( 'tutor_pro_flag', __( 'Pro', 'tutor' ) );
109 }
110
111 $enable_course_marketplace = (bool) tutor_utils()->get_option( 'enable_course_marketplace' );
112
113 $welcome = Tutor_Setup::is_welcome_page_visited();
114
115 $root_page = array( $this, 'tutor_course_list' );
116 if ( false === $welcome && Input::has( 'page' ) && 'tutor' === Input::get( 'page' ) && Input::has( 'welcome' ) ) {
117 $root_page = array( $this, 'welcome_page' );
118 }
119
120 $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>' );
121 $menu_position = 2;
122
123 add_menu_page(
124 __( 'Tutor LMS', 'tutor' ) . $pro_text,
125 __( 'Tutor LMS', 'tutor' ) . $pro_text,
126 'manage_tutor_instructor',
127 'tutor',
128 $root_page,
129 $icon_base64_uri,
130 $menu_position
131 );
132
133 // Added @since v2.0.0.
134 add_submenu_page( 'tutor', __( 'Courses', 'tutor' ), __( 'Courses', 'tutor' ), 'manage_tutor_instructor', 'tutor', array( $this, 'tutor_course_list' ) );
135
136 if ( '3.0.0' !== get_option( 'tutor-new-feature' ) ) {
137 add_submenu_page( 'tutor', __( 'What\'s New', 'tutor' ), sprintf( '<span class="tutor-new-feature tutor-text-orange">%s</span>', __( 'What\'s New', 'tutor' ) ), 'manage_tutor', 'tutor-new-feature', array( $this, 'feature_promotion_page' ) );
138 }
139
140 // Ecommerce menu @since 3.0.0.
141 do_action( 'tutor_after_courses_admin_menu' );
142
143 add_submenu_page( 'tutor', __( 'Course Builder', 'tutor' ), '<span class="tutor-create-course">Create Course</span>', 'manage_tutor_instructor', 'create-course', array( new Course( false ), 'load_course_builder' ) );
144
145 // Extendable action hook @since 2.2.0.
146 do_action( 'tutor_after_courses_menu' );
147
148 add_submenu_page( 'tutor', __( 'Categories', 'tutor' ), __( 'Categories', 'tutor' ), 'manage_tutor', 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type, null );
149
150 add_submenu_page( 'tutor', __( 'Tags', 'tutor' ), __( 'Tags', 'tutor' ), 'manage_tutor', 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type, null );
151
152 add_submenu_page( 'tutor', __( 'Students', 'tutor' ), __( 'Students', 'tutor' ), 'manage_tutor', Students_List::STUDENTS_LIST_PAGE, array( $this, 'tutor_students' ) );
153
154 if ( $enable_course_marketplace ) {
155 add_submenu_page( 'tutor', __( 'Instructors', 'tutor' ), __( 'Instructors', 'tutor' ), 'manage_tutor', Instructors_List::INSTRUCTOR_LIST_PAGE, array( $this, 'tutor_instructors' ) );
156 add_submenu_page( 'tutor', __( 'Withdraw Requests', 'tutor' ), __( 'Withdraw Requests', 'tutor' ), 'manage_tutor', Withdraw_Requests_List::WITHDRAW_REQUEST_LIST_PAGE, array( $this, 'withdraw_requests' ) );
157 }
158
159 add_submenu_page( 'tutor', __( 'Announcements', 'tutor' ), __( 'Announcements', 'tutor' ), 'manage_tutor_instructor', 'tutor_announcements', array( $this, 'tutor_announcements' ) );
160
161 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' ) );
162
163 add_submenu_page( 'tutor', __( 'Quiz Attempts', 'tutor' ), __( 'Quiz Attempts', 'tutor' ), 'manage_tutor_instructor', Quiz_Attempts_List::QUIZ_ATTEMPT_PAGE, array( $this, 'quiz_attempts' ) );
164
165 add_submenu_page( 'tutor', __( 'Addons', 'tutor' ), __( 'Addons', 'tutor' ), 'manage_tutor', 'tutor-addons', array( $this, 'enable_disable_addons' ) );
166
167 do_action( 'tutor_admin_register' );
168
169 add_submenu_page( 'tutor', __( 'Tools', 'tutor' ), __( 'Tools', 'tutor' ), 'manage_tutor', 'tutor-tools', array( new \TUTOR\Tools_V2(), 'load_tools_page' ) );
170
171 add_submenu_page( 'tutor', __( 'Settings', 'tutor' ), __( 'Settings', 'tutor' ), 'manage_tutor', 'tutor_settings', array( new \TUTOR\Options_V2(), 'load_settings_page' ) );
172
173 do_action( 'tutor_after_settings_menu' );
174
175 if ( ! $has_pro ) {
176 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' ) );
177 }
178 }
179
180 /**
181 * Welcome page opt-out
182 *
183 * @since 3.0.0
184 */
185 public function handle_do_not_show_feature_page() {
186 tutor_utils()->check_nonce();
187
188 if ( ! User::is_admin() ) {
189 $this->json_response(
190 tutor_utils()->error_message(),
191 null,
192 HttpHelper::STATUS_BAD_REQUEST
193 );
194 }
195
196 update_option( 'tutor-new-feature', '3.0.0' );
197 $this->json_response( __( 'Success', 'tutor' ) );
198 }
199
200 /**
201 * Show Feature Promotion Page for Free User.
202 *
203 * @since 2.2.0
204 *
205 * @return void
206 */
207 public function feature_promotion_page() {
208 include tutor()->path . 'views/pages/welcome.php';
209 // include tutor()->path . 'views/pages/feature-promotion.php';
210 }
211
212 /**
213 * Show students page
214 *
215 * @since 1.0.0
216 * @return void
217 */
218 public function tutor_students() {
219 include tutor()->path . 'views/pages/students.php';
220 }
221
222 /**
223 * Show instructor page
224 *
225 * @since 1.0.0
226 * @return void
227 */
228 public function tutor_instructors() {
229 include tutor()->path . 'views/pages/instructors.php';
230 }
231
232 /**
233 * Show announcements page
234 *
235 * @since 1.0.0
236 * @return void
237 */
238 public function tutor_announcements() {
239 include tutor()->path . 'views/pages/announcements.php';
240 }
241
242 /**
243 * Show Q&A page
244 *
245 * @since 1.0.0
246 * @return void
247 */
248 public function question_answer() {
249 include tutor()->path . 'views/pages/question_answer.php';
250 }
251
252 /**
253 * Show quiz attempts page
254 *
255 * @since 1.0.0
256 * @return void
257 */
258 public function quiz_attempts() {
259 include tutor()->path . 'views/pages/quiz_attempts.php';
260 }
261
262 /**
263 * Show the withdraw requests table
264 *
265 * @since 1.2.0
266 * @return void
267 */
268 public function withdraw_requests() {
269 include tutor()->path . 'views/pages/withdraw_requests.php';
270 }
271
272 /**
273 * Enable or disable addons
274 *
275 * @since 1.0.0
276 * @return void
277 */
278 public function enable_disable_addons() {
279 include tutor()->path . 'views/pages/enable_disable_addons.php';
280 }
281
282 /**
283 * Tutor tools page (OLD)
284 *
285 * @since 1.0.0
286 * @return void
287 */
288 public function tutor_tools_old() {
289 $tutor_admin_tools_page = Input::get( 'tutor_admin_tools_page' );
290 if ( $tutor_admin_tools_page ) {
291 include apply_filters( 'tutor_admin_tools_page', tutor()->path . "views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page );
292 } else {
293 $pages = apply_filters(
294 'tutor_tool_pages',
295 array(
296 'tutor_pages' => array( 'title' => __( 'Tutor Pages', 'tutor' ) ),
297 'status' => __( 'Status', 'tutor' ),
298 )
299 );
300
301 $current_page = 'tutor_pages';
302 $requested_page = Input::get( 'sub_page' );
303 if ( $requested_page ) {
304 $current_page = $requested_page;
305 }
306
307 $current_page = str_replace( '/', '', $current_page );
308 $current_page = str_replace( '.', '', $current_page );
309 $current_page = str_replace( '\\', '', $current_page );
310 $current_page = trim( $current_page );
311
312 include tutor()->path . 'views/pages/tools.php';
313 }
314 }
315
316 /**
317 * Show pro upgrade page
318 *
319 * @since 1.0.0
320 * @return void
321 */
322 public function tutor_get_pro() {
323 include tutor()->path . 'views/pages/get-pro.php';
324 }
325
326 /**
327 * Parent menu active
328 *
329 * @since 1.0.0
330 *
331 * @param string $parent_file parent file.
332 * @return string
333 */
334 public function parent_menu_active( $parent_file ) {
335 $taxonomy = Input::get( 'taxonomy' );
336 if ( CourseModel::COURSE_CATEGORY === $taxonomy || CourseModel::COURSE_TAG === $taxonomy ) {
337 return 'tutor';
338 }
339
340 return $parent_file;
341 }
342
343 /**
344 * Sub-menu active
345 *
346 * @since 1.0.0
347 *
348 * @param string $submenu_file submenu file.
349 * @param string $parent_file parent file.
350 *
351 * @return string
352 */
353 public function submenu_file_active( $submenu_file, $parent_file ) {
354 $taxonomy = Input::get( 'taxonomy' );
355 $course_post_type = tutor()->course_post_type;
356
357 if ( CourseModel::COURSE_CATEGORY === $taxonomy ) {
358 return 'edit-tags.php?taxonomy=course-category&post_type=' . $course_post_type;
359 }
360 if ( CourseModel::COURSE_TAG === $taxonomy ) {
361 return 'edit-tags.php?taxonomy=course-tag&post_type=' . $course_post_type;
362 }
363
364 return $submenu_file;
365 }
366
367 /**
368 * Filter posts for instructor
369 *
370 * @since 1.0.0
371 * @return void
372 */
373 public function filter_posts_for_instructors() {
374 if ( ! current_user_can( 'administrator' ) && current_user_can( tutor()->instructor_role ) ) {
375 @remove_menu_page( 'edit-comments.php' ); // Comments.
376 add_filter( 'posts_clauses_request', array( $this, 'posts_clauses_request' ) );
377 }
378 }
379
380 /**
381 * Request for posts clauses
382 *
383 * @since 1.0.0
384 *
385 * @param mixed $clauses clauses.
386 * @return mixed
387 */
388 public function posts_clauses_request( $clauses ) {
389
390 if ( ! is_admin() || ( ! Input::has( 'post_type' ) || Input::get( 'post_type' ) != tutor()->course_post_type ) || tutor_utils()->has_user_role( array( 'administrator', 'editor' ) ) ) {
391 return $clauses;
392 }
393
394 // Need multi instructor check.
395 global $wpdb;
396
397 $user_id = get_current_user_id();
398
399 $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 ) );
400 $own_courses = is_array( $get_assigned_courses_ids ) ? $get_assigned_courses_ids : array();
401
402 $in_query_pre = count( $own_courses ) ? implode( ',', $own_courses ) : null;
403 $in_query_where = $in_query_pre ? " OR {$wpdb->posts}.ID IN({$in_query_pre})" : '';
404
405 $course_post_type = tutor()->course_post_type;
406 $custom_author_query = " AND ({$wpdb->posts}.post_type!='{$course_post_type}' OR {$wpdb->posts}.post_author = {$user_id}) {$in_query_where}";
407
408 $clauses['where'] .= $custom_author_query;
409
410 return $clauses;
411 }
412
413 /**
414 * Prevent unauthorised course/lesson edit page by direct URL
415 *
416 * @since 1.0.0
417 * @return void
418 */
419 public function check_if_current_users_post() {
420 if ( current_user_can( 'administrator' ) || ! current_user_can( tutor()->instructor_role ) ) {
421 return;
422 }
423
424 if ( ! empty( Input::get( 'post' ) ) ) {
425 $get_post_id = Input::get( 'post', Input::TYPE_INT );
426 $get_post = get_post( $get_post_id );
427 $tutor_post_types = array( tutor()->course_post_type, tutor()->lesson_post_type );
428
429 $current_user = get_current_user_id();
430
431 if ( in_array( $get_post->post_type, $tutor_post_types ) && $get_post->post_author != $current_user ) {
432 global $wpdb;
433
434 $get_assigned_courses_ids = (int) $wpdb->get_var(
435 $wpdb->prepare(
436 "SELECT user_id
437 from {$wpdb->usermeta}
438 WHERE user_id = %d AND meta_key = '_tutor_instructor_course_id' AND meta_value = %d ",
439 $current_user,
440 $get_post_id
441 )
442 );
443
444 if ( ! $get_assigned_courses_ids ) {
445 wp_die( esc_html__( 'Permission Denied', 'tutor' ) );
446 }
447 }
448 }
449 }
450
451 /**
452 * Scan template files
453 *
454 * @since 1.0.0
455 *
456 * @param string $template_path template file path.
457 * @return array
458 */
459 public static function scan_template_files( $template_path = null ) {
460 if ( ! $template_path ) {
461 $template_path = tutor()->path . 'templates/';
462 }
463
464 $files = @scandir($template_path); // @codingStandardsIgnoreLine.
465 $result = array();
466
467 if ( ! empty( $files ) ) {
468 foreach ( $files as $key => $value ) {
469 if ( ! in_array( $value, array( '.', '..', '.DS_Store' ), true ) ) {
470 if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
471 $sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
472 foreach ( $sub_files as $sub_file ) {
473 $result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
474 }
475 } else {
476 $result[] = $value;
477 }
478 }
479 }
480 }
481 return $result;
482 }
483
484 /**
485 * Get Template overridden files
486 *
487 * @since 1.0.0
488 * @return array
489 */
490 public static function template_overridden_files() {
491 $template_files = self::scan_template_files();
492
493 $override_files = array();
494 foreach ( $template_files as $file ) {
495 $file_path = null;
496 if ( file_exists( trailingslashit( get_stylesheet_directory() ) . tutor()->template_path . $file ) ) {
497 $file_path = $file;
498 } elseif ( file_exists( trailingslashit( get_template_directory() ) . tutor()->template_path . $file ) ) {
499 $file_path = $file;
500 }
501
502 if ( $file_path ) {
503 $override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $file_path );
504 }
505 }
506
507 return $override_files;
508 }
509
510 /**
511 * Plugin activation link
512 *
513 * @since 1.0.0
514 *
515 * @param array $actions action list.
516 * @return array
517 */
518 public function plugin_action_links( $actions ) {
519 $has_pro = tutor()->has_pro;
520
521 if ( ! $has_pro ) {
522 $actions['tutor_pro_link'] =
523 '<a href="https://tutorlms.com/pricing?utm_source=tutor_plugin_action_link&utm_medium=wordpress_dashboard&utm_campaign=go_premium" target="_blank">
524 <span style="color: #ff7742; font-weight: bold;">' .
525 __( 'Upgrade to Pro', 'tutor' ) .
526 '</span>
527 </a>';
528 }
529
530 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __( 'Settings', 'tutor' ) . '</a>';
531
532 return $actions;
533 }
534
535 /**
536 * Add plugin meta data in WP plugins list page
537 *
538 * @since 1.0.0
539 *
540 * @param array $plugin_meta plugin meta data.
541 * @param string $plugin_file plugin file.
542 *
543 * @return array
544 */
545 public function plugin_row_meta( $plugin_meta, $plugin_file ) {
546
547 if ( tutor()->basename === $plugin_file ) {
548 $plugin_meta[] = sprintf(
549 '<a href="%s"><strong style="color: #03bd24">%s</strong></a>',
550 esc_url( 'https://docs.themeum.com/tutor-lms/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link' ),
551 esc_html__( 'Documentation', 'tutor' )
552 );
553 $plugin_meta[] = sprintf(
554 '<a href="%s"><strong style="color: #03bd24">%s</strong></a>',
555 esc_url( 'https://www.themeum.com/contact-us/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link' ),
556 esc_html__( 'Get Support', 'tutor' )
557 );
558 }
559
560 return $plugin_meta;
561 }
562
563 /**
564 * Add footer text only on tutor pages
565 *
566 * @since 1.0.0
567 *
568 * @param string $footer_text footer text.
569 * @return string
570 */
571 public function admin_footer_text( $footer_text ) {
572 $current_screen = get_current_screen();
573
574 /**
575 * We are making sure that this message will be only on Tutor Admin page
576 */
577 if ( apply_filters( 'tutor_display_admin_footer_text', ( tutor_utils()->array_get( 'parent_base', $current_screen ) === 'tutor' ) ) ) {
578 $footer_text = sprintf(
579 /* translators: %s: plugin name */
580 __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor' ),
581 sprintf( '<strong>%s</strong>', esc_html__( 'Tutor LMS', 'tutor' ) ),
582 '<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>'
583 );
584 }
585
586 return $footer_text;
587 }
588
589 /**
590 * Register course widget
591 *
592 * @since 1.0.0
593 * @return void
594 */
595 public function register_course_widget() {
596 register_widget( Course_Widget::class );
597 }
598
599 /**
600 * Tutor Course List
601 *
602 * @since 2.0.0
603 * @return void
604 */
605 public function tutor_course_list() {
606 include tutor()->path . 'views/pages/course-list.php';
607 }
608
609 /**
610 * Orders view page
611 *
612 * @since 3.0.0
613 *
614 * @return void
615 */
616 public function orders_view() {
617 $current_page = Input::get( 'page' );
618 $action = Input::get( 'action' );
619
620 if ( OrderController::PAGE_SLUG === $current_page && 'edit' === $action ) {
621 ?>
622 <div class="tutor-admin-wrap tutor-order-details-wrapper">
623 <div id="tutor-order-details-root">
624 </div>
625 </div>
626 <?php
627 return;
628 }
629
630 include tutor()->path . 'views/pages/ecommerce/order-list.php';
631 }
632
633 /**
634 * Coupons view page
635 *
636 * @since 3.0.0
637 *
638 * @return void
639 */
640 public function coupons_view() {
641 $action = Input::get( 'action' );
642 if ( in_array( $action, array( 'add_new', 'edit' ) ) ) {
643 ?>
644 <div class="tutor-admin-wrap">
645 <div id="tutor-coupon-root">
646 </div>
647 </div>
648 <?php
649 return;
650 }
651 include tutor()->path . 'views/pages/ecommerce/coupon-list.php';
652 }
653
654 /**
655 * Show welcome page
656 *
657 * @since 1.0.0
658 * @return void
659 */
660 public function welcome_page() {
661 Tutor_Setup::mark_as_visited();
662 include tutor()->path . 'views/pages/welcome.php';
663 exit;
664 }
665
666 /**
667 * Add toolbar items
668 *
669 * @since 1.4.6
670 *
671 * @param \WP_Admin_Bar $admin_bar admin bar object.
672 *
673 * @return mixed
674 */
675 public function add_toolbar_items( \WP_Admin_Bar $admin_bar ) {
676 global $post;
677
678 $course_id = Input::get( 'post', 0, Input::TYPE_INT );
679 $course_post_type = tutor()->course_post_type;
680
681 if ( $admin_bar->get_node( 'new-courses' ) ) {
682 $args = $admin_bar->get_node( 'new-courses' );
683 $args->href = '#';
684 $args->meta['class'] = 'tutor-create-new-course';
685 $admin_bar->add_node( $args );
686 }
687
688 if ( ! tutor_utils()->can_user_edit_course( get_current_user_id(), $course_id ) ) {
689 return $admin_bar;
690 }
691
692 if (
693 ( is_admin() && $post && $course_id && $post->post_type === $course_post_type ) ||
694 ( ! is_admin() && is_single() && $post && $course_post_type === $post->post_type )
695 ) {
696
697 $admin_bar->add_menu(
698 array(
699 'id' => 'edit',
700 'title' => __( 'Edit with Course Builder', 'tutor' ),
701 'href' => tutor_utils()->course_edit_link( $post->ID ),
702 'meta' => array(
703 'title' => __( 'Edit with Course Builder', 'tutor' ),
704 'target' => '_blank',
705 ),
706 )
707 );
708 }
709
710 return $admin_bar;
711 }
712 }
713