PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.4.4
Tutor LMS – eLearning and online course solution v1.4.4
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 6 years ago Admin.php 6 years ago Ajax.php 6 years ago Assets.php 6 years ago Course.php 6 years ago Course_Settings_Tabs.php 6 years ago Course_Widget.php 6 years ago Dashboard.php 6 years ago Email.php 6 years ago FormHandler.php 6 years ago Gutenberg.php 6 years ago Instructor.php 6 years ago Instructors_List.php 6 years ago Lesson.php 6 years ago Options.php 6 years ago Post_types.php 6 years ago Q_and_A.php 6 years ago Question_Answers_List.php 6 years ago Quiz.php 6 years ago Quiz_Attempts_List.php 6 years ago Rewrite_Rules.php 6 years ago Shortcode.php 6 years ago Student.php 6 years ago Students_List.php 6 years ago Taxonomies.php 6 years ago Template.php 6 years ago Theme_Compatibility.php 6 years ago Tools.php 6 years ago Tutor.php 6 years ago TutorEDD.php 6 years ago Tutor_Base.php 6 years ago Tutor_List_Table.php 6 years ago Upgrader.php 6 years ago User.php 6 years ago Utils.php 6 years ago Video_Stream.php 6 years ago Withdraw.php 6 years ago Withdraw_Requests_List.php 6 years ago WooCommerce.php 6 years ago
Admin.php
479 lines
1 <?php
2 namespace TUTOR;
3
4 /**
5 * Class Admin
6 * @package TUTOR
7 *
8 * @since v.1.0.0
9 */
10
11 if ( ! defined( 'ABSPATH' ) )
12 exit;
13
14 class Admin{
15 public function __construct() {
16 add_action('admin_menu', array($this, 'register_menu'));
17 //Force activate menu for necessary
18 add_filter('parent_file', array($this, 'parent_menu_active'));
19 add_filter('submenu_file', array($this, 'submenu_file_active'), 10, 2);
20
21 add_action('admin_init', array($this, 'filter_posts_for_instructors'));
22 add_action('load-post.php', array($this, 'check_if_current_users_post') );
23
24 add_action('admin_action_uninstall_tutor_and_erase', array($this, 'erase_tutor_data'));
25 add_filter('plugin_action_links_' . plugin_basename(TUTOR_FILE), array( $this, 'plugin_action_links' ) );
26
27 //Plugin Row Meta
28 add_filter('plugin_row_meta', array($this, 'plugin_row_meta'), 10, 2);
29
30 //Admin Footer Text
31 add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
32 //Register Course Widget
33 add_action( 'widgets_init', array($this, 'register_course_widget') );
34 }
35
36 public function register_menu(){
37 $hasPro = tutor()->has_pro;
38
39 $unanswered_questions = tutor_utils()->unanswered_question_count();
40 $unanswered_bubble = '';
41 if ($unanswered_questions){
42 $unanswered_bubble = '<span class="update-plugins count-'.$unanswered_questions.'"><span class="plugin-count">'.$unanswered_questions.'</span></span>';
43 }
44
45 $course_post_type = tutor()->course_post_type;
46
47 $pro_text = '';
48 if ($hasPro){
49 $pro_text = ' '.__('Pro', 'tutor');
50 }
51
52 add_menu_page(__('Tutor LMS', 'tutor').$pro_text, __('Tutor LMS', 'tutor').$pro_text, 'manage_tutor_instructor', 'tutor', null,
53 'dashicons-welcome-learn-more', 2);
54 add_submenu_page('tutor', __('Categories', 'tutor'), __('Categories', 'tutor'), 'manage_tutor', 'edit-tags.php?taxonomy=course-category&post_type='.$course_post_type, null );
55
56 add_submenu_page('tutor', __('Tags', 'tutor'), __('Tags', 'tutor'), 'manage_tutor', 'edit-tags.php?taxonomy=course-tag&post_type='.$course_post_type, null );
57
58 add_submenu_page('tutor', __('Students', 'tutor'), __('Students', 'tutor'), 'manage_tutor', 'tutor-students', array($this, 'tutor_students') );
59
60 add_submenu_page('tutor', __('Instructors', 'tutor'), __('Instructors', 'tutor'), 'manage_tutor', 'tutor-instructors', array($this, 'tutor_instructors') );
61
62 add_submenu_page('tutor', __('Q & A', 'tutor'), __('Q & A '.$unanswered_bubble, 'tutor'), 'manage_tutor_instructor', 'question_answer', array($this, 'question_answer') );
63
64 add_submenu_page('tutor', __('Quiz Attempts', 'tutor'), __('Quiz Attempts', 'tutor'), 'manage_tutor_instructor', 'tutor_quiz_attempts',array($this, 'quiz_attempts') );
65 add_submenu_page('tutor', __('Withdraw Requests', 'tutor'), __('Withdraw Requests', 'tutor'), 'manage_tutor_instructor', 'tutor_withdraw_requests', array($this, 'withdraw_requests') );
66
67 //add_submenu_page('tutor', __('Add-ons', 'tutor'), __('Add-ons', 'tutor'), 'manage_tutor', 'tutor-addons', array(new Addons(),'addons_page') );
68 add_submenu_page( 'tutor', __( 'Add-ons', 'tutor' ), __( 'Add-ons', 'tutor' ), 'manage_tutor', 'tutor-addons', array( $this, 'enable_disable_addons' ) );
69
70 do_action('tutor_admin_register');
71
72 add_submenu_page('tutor', __('Settings', 'tutor'), __('Settings', 'tutor'), 'manage_tutor', 'tutor_settings', array($this, 'tutor_page') );
73
74 add_submenu_page('tutor', __('Tools', 'tutor'), __('Tools', 'tutor'), 'manage_tutor', 'tutor-tools', array($this, 'tutor_tools') );
75
76 if ( ! $hasPro){
77 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') );
78 }
79 }
80
81 public function tutor_page(){
82 $tutor_option = new Options();
83 echo apply_filters('tutor/options/generated-html', $tutor_option->generate());
84 }
85
86 public function tutor_students(){
87 include tutor()->path.'views/pages/students.php';
88 }
89
90 public function tutor_instructors(){
91 include tutor()->path.'views/pages/instructors.php';
92 }
93
94 public function question_answer(){
95 include tutor()->path.'views/pages/question_answer.php';
96 }
97
98 public function quiz_attempts(){
99 include tutor()->path.'views/pages/quiz_attempts.php';
100 }
101
102 /**
103 * Show the withdraw requests table
104 *
105 * @since v.1.2.0
106 */
107 public function withdraw_requests(){
108 include tutor()->path.'views/pages/withdraw_requests.php';
109 }
110
111 public function enable_disable_addons(){
112
113 if (defined('TUTOR_PRO_VERSION')) {
114 include tutor()->path.'views/pages/enable_disable_addons.php';
115 }else{
116 include tutor()->path.'views/pages/tutor-pro-addons.php';
117 }
118 }
119
120 public function tutor_tools(){
121 $tutor_admin_tools_page = tutils()->array_get('tutor_admin_tools_page', $_GET);
122 if ($tutor_admin_tools_page){
123 include apply_filters('tutor_admin_tools_page', tutor()->path."views/pages/{$tutor_admin_tools_page}.php", $tutor_admin_tools_page);
124 }else{
125 $pages = apply_filters('tutor_tool_pages', array(
126 'tutor_pages' => array('title' => __('Tutor Pages', 'tutor') ),
127 'status' => __('Status', 'tutor'),
128 ));
129
130 $current_page = 'tutor_pages';
131 $requested_page = sanitize_text_field(tutils()->array_get('sub_page', $_GET));
132 if ($requested_page){
133 $current_page = $requested_page;
134 }
135
136 include tutor()->path.'views/pages/tools.php';
137 }
138
139 }
140
141 public function tutor_get_pro(){
142 include tutor()->path.'views/pages/get-pro.php';
143 }
144
145 public function parent_menu_active( $parent_file ){
146 $taxonomy = tutor_utils()->avalue_dot('taxonomy', $_GET);
147 if ($taxonomy === 'course-category' || $taxonomy === 'course-tag'){
148 return 'tutor';
149 }
150
151 return $parent_file;
152 }
153
154 public function submenu_file_active($submenu_file, $parent_file){
155 $taxonomy = tutor_utils()->avalue_dot('taxonomy', $_GET);
156 $course_post_type = tutor()->course_post_type;
157
158 if ($taxonomy === 'course-category'){
159 return 'edit-tags.php?taxonomy=course-category&post_type='.$course_post_type;
160 }
161 if ($taxonomy === 'course-tag'){
162 return 'edit-tags.php?taxonomy=course-tag&post_type='.$course_post_type;
163 }
164
165
166 return $submenu_file;
167 }
168
169 /**
170 * Filter posts for instructor
171 */
172 public function filter_posts_for_instructors(){
173 if ( ! current_user_can('administrator') && current_user_can(tutor()->instructor_role)){
174 remove_menu_page( 'edit-comments.php' ); //Comments
175 add_filter( 'posts_clauses_request', array($this, 'posts_clauses_request') );
176 }
177 }
178
179 public function posts_clauses_request($clauses){
180 global $wpdb;
181
182 $user_id = get_current_user_id();
183
184 $get_assigned_courses_ids = $wpdb->get_col("SELECT meta_value from {$wpdb->usermeta} WHERE meta_key = '_tutor_instructor_course_id' AND user_id = {$user_id} ");
185
186 $custom_author_query = "AND {$wpdb->posts}.post_author = {$user_id}";
187 if (is_array($get_assigned_courses_ids) && count($get_assigned_courses_ids)){
188 $in_query_pre = implode(',', $get_assigned_courses_ids);
189 $custom_author_query = " AND ( {$wpdb->posts}.post_author = {$user_id} OR {$wpdb->posts}.ID IN({$in_query_pre}) ) ";
190 }
191
192 $clauses['where'] .= $custom_author_query;
193
194 return $clauses;
195 }
196
197 /**
198 * Prevent unauthorised course/lesson edit page by direct URL
199 *
200 * @since v.1.0.0
201 */
202 public function check_if_current_users_post(){
203 if (current_user_can('administrator') || ! current_user_can(tutor()->instructor_role)) {
204 return;
205 }
206
207 if (! empty($_GET['post']) ) {
208 $get_post_id = (int) sanitize_text_field($_GET['post']);
209 $get_post = get_post($get_post_id);
210 $tutor_post_types = array(tutor()->course_post_type, tutor()->lesson_post_type);
211
212 $current_user = get_current_user_id();
213
214 if (in_array($get_post->post_type, $tutor_post_types) && $get_post->post_author != $current_user){
215 global $wpdb;
216
217 $get_assigned_courses_ids = (int) $wpdb->get_var("SELECT user_id from {$wpdb->usermeta} WHERE user_id = {$current_user} AND meta_key = '_tutor_instructor_course_id' AND meta_value = {$get_post_id} ");
218
219 if ( ! $get_assigned_courses_ids){
220 wp_die(__('Permission Denied', 'tutor'));
221 }
222
223 }
224 }
225 }
226
227 /**
228 * Status
229 */
230
231 public static function scan_template_files( $template_path = null ) {
232 if ( ! $template_path){
233 $template_path = tutor()->path.'templates/';
234 }
235
236 $files = @scandir( $template_path ); // @codingStandardsIgnoreLine.
237 $result = array();
238
239 if ( ! empty( $files ) ) {
240 foreach ( $files as $key => $value ) {
241 if ( ! in_array( $value, array( '.', '..', '.DS_Store' ), true ) ) {
242 if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
243 $sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
244 foreach ( $sub_files as $sub_file ) {
245 $result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
246 }
247 } else {
248 $result[] = $value;
249 }
250 }
251 }
252 }
253 return $result;
254 }
255
256 /**
257 * @return array
258 *
259 *
260 */
261 public static function template_overridden_files(){
262 $template_files = self::scan_template_files();
263
264 $override_files = array();
265 foreach ($template_files as $file){
266 $file_path = null;
267 if (file_exists(trailingslashit(get_stylesheet_directory()).tutor()->template_path.$file)){
268 $file_path = $file;
269 }elseif (file_exists(trailingslashit(get_template_directory()).tutor()->template_path.$file)){
270 $file_path = $file;
271 }
272
273 if ($file_path){
274 $override_files[] = str_replace( WP_CONTENT_DIR.'/themes/', '', $file_path );
275 }
276 }
277
278 return $override_files;
279 }
280
281 public static function get_environment_info(){
282
283 // Figure out cURL version, if installed.
284 $curl_version = '';
285 if ( function_exists( 'curl_version' ) ) {
286 $curl_version = curl_version();
287 $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version'];
288 }
289
290
291 // WP memory limit.
292 $wp_memory_limit = tutor_utils()->let_to_num(WP_MEMORY_LIMIT);
293 if ( function_exists( 'memory_get_usage' ) ) {
294 $wp_memory_limit = max( $wp_memory_limit, tutor_utils()->let_to_num( @ini_get( 'memory_limit' ) ) );
295 }
296
297 $database_version = tutor_utils()->get_db_version();
298
299 return array(
300 'home_url' => get_option( 'home' ),
301 'site_url' => get_option( 'siteurl' ),
302 'version' => tutor()->version,
303 'wp_version' => get_bloginfo( 'version' ),
304 'wp_multisite' => is_multisite(),
305 'wp_memory_limit' => $wp_memory_limit,
306 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
307 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
308 'language' => get_locale(),
309 'external_object_cache' => wp_using_ext_object_cache(),
310 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : '',
311 'php_version' => phpversion(),
312 'php_post_max_size' => tutor_utils()->let_to_num( ini_get( 'post_max_size' ) ),
313 'php_max_execution_time' => ini_get( 'max_execution_time' ),
314 'php_max_input_vars' => ini_get( 'max_input_vars' ),
315 'curl_version' => $curl_version,
316 'suhosin_installed' => extension_loaded( 'suhosin' ),
317 'max_upload_size' => wp_max_upload_size(),
318 'mysql_version' => $database_version['number'],
319 'mysql_version_string' => $database_version['string'],
320 'default_timezone' => date_default_timezone_get(),
321 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ),
322 'soapclient_enabled' => class_exists( 'SoapClient' ),
323 'domdocument_enabled' => class_exists( 'DOMDocument' ),
324 'gzip_enabled' => is_callable( 'gzopen' ),
325 'mbstring_enabled' => extension_loaded( 'mbstring' ),
326 );
327
328 }
329
330
331 public function erase_tutor_data(){
332 global $wpdb;
333
334 $is_erase_data = tutor_utils()->get_option('delete_on_uninstall');
335 /**D*/ //=> Deleting Data
336
337 $plugin_file = tutor()->basename;
338 if ($is_erase_data && current_user_can( 'deactivate_plugin', $plugin_file )) {
339 /**
340 * Deleting Post Type, Meta Data, taxonomy
341 */
342 $course_post_type = tutor()->course_post_type;
343 $lesson_post_type = tutor()->lesson_post_type;
344
345 $post_types = array(
346 $course_post_type,
347 $lesson_post_type,
348 'tutor_quiz',
349 'tutor_enrolled',
350 'topics',
351 'tutor_enrolled',
352 'tutor_announcements',
353 );
354
355 $post_type_strings = "'".implode("','", $post_types)."'";
356 $tutor_posts = $wpdb->get_col("SELECT ID from {$wpdb->posts} WHERE post_type in({$post_type_strings}) ;");
357
358 if (is_array($tutor_posts) && count($tutor_posts)){
359 foreach ($tutor_posts as $post_id){
360 //Delete categories
361 $terms = wp_get_object_terms( $post_id, 'course-category' );
362 foreach( $terms as $term ){
363 /**D*/ wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-category' );
364 }
365
366 //Delete tags if available
367 $terms = wp_get_object_terms( $post_id, 'course-tag' );
368 foreach( $terms as $term ){
369 /**D*/ wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-tag' );
370 }
371
372 //Delete All Meta
373 /**D*/ $wpdb->delete($wpdb->postmeta, array('post_id' => $post_id) );
374 /**D*/ $wpdb->delete($wpdb->posts, array('ID' => $post_id) );
375 }
376 }
377
378 /**
379 * Deleting Comments (reviews, questions, quiz_answers, etc)
380 */
381 $tutor_comments = $wpdb->get_col("SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;");
382 $comments_ids_strings = "'".implode("','", $tutor_comments)."'";
383 if (is_array($tutor_comments) && count($tutor_comments)){
384 /**D*/ $wpdb->query("DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$comments_ids_strings}) ");
385 }
386 /**D*/ $wpdb->delete($wpdb->comments, array('comment_agent' => 'comment_agent'));
387
388 /**
389 * Delete Options
390 */
391
392 /**D*/ delete_option('tutor_option');
393 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_is_tutor_student'));
394 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_tutor_instructor_approved'));
395 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_tutor_instructor_status'));
396 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_is_tutor_instructor'));
397 /**D*/ $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' ");
398
399 //Deleting Table
400 $prefix = $wpdb->prefix;
401 /**D*/ $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 ");
402
403 deactivate_plugins($plugin_file);
404 }
405
406 wp_redirect('plugins.php');
407 die();
408 }
409
410 public function plugin_action_links($actions){
411 $hasPro = tutor()->has_pro;
412
413 if(!$hasPro){
414 $actions['tutor_pro_link'] = '<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"><span
415 style="color: #ff7742; font-weight: bold;">' . __('Upgrade to Pro', 'wp-megamenu') . '</span></a>';
416 }
417
418 $is_erase_data = tutor_utils()->get_option('delete_on_uninstall');
419
420 if ($is_erase_data) {
421 $plugin_file = tutor()->basename;
422 if ( current_user_can( 'deactivate_plugin', $plugin_file ) ) {
423 if ( isset( $actions['deactivate'] ) ) {
424 $actions['deactivate'] = '<a href="admin.php?page=tutor-tools&tutor_admin_tools_page=uninstall">' . __('Uninstall', 'tutor') . '</a>';
425 }
426 }
427 }
428
429 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __('Settings', 'tutor') . '</a>';
430 return $actions;
431 }
432
433 public function plugin_row_meta($plugin_meta, $plugin_file){
434
435 if ($plugin_file === tutor()->basename) {
436 $plugin_meta[] = sprintf( '<a href="%s">%s</a>',
437 esc_url( 'https://www.themeum.com/docs/tutor-introduction/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link' ),
438 __( '<strong style="color: #03bd24">Documentation</strong>', 'tutor' )
439 );
440 $plugin_meta[] = sprintf( '<a href="%s">%s</a>',
441 esc_url( 'https://www.themeum.com/support-forums/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link' ),
442 __( '<strong style="color: #03bd24">Get Support</strong>', 'tutor' )
443 );
444 }
445
446 return $plugin_meta;
447 }
448
449 /**
450 * @param $footer_text
451 *
452 * @return string
453 *
454 * Add footer text only on tutor pages
455 */
456 public function admin_footer_text( $footer_text ) {
457 $current_screen = get_current_screen();
458
459 /**
460 * We are making sure that this message will be only on Tutor Admin page
461 */
462 if ( apply_filters( 'tutor_display_admin_footer_text', (tutor_utils()->array_get('parent_base', $current_screen) === 'tutor' ) ) ) {
463 $footer_text = sprintf(
464 __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor' ),
465 sprintf( '<strong>%s</strong>', esc_html__( 'Tutor LMS', 'tutor' ) ),
466 '<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>'
467 );
468 }
469
470 return $footer_text;
471 }
472
473
474 public function register_course_widget(){
475 register_widget( 'Tutor\Course_Widget' );
476 }
477
478
479 }