PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.5.6
Tutor LMS – eLearning and online course solution v1.5.6
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 Frontend.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 RestAPI.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
478 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 public function erase_tutor_data(){
331 global $wpdb;
332
333 $is_erase_data = tutor_utils()->get_option('delete_on_uninstall');
334 /**D*/ //=> Deleting Data
335
336 $plugin_file = tutor()->basename;
337 if ($is_erase_data && current_user_can( 'deactivate_plugin', $plugin_file )) {
338 /**
339 * Deleting Post Type, Meta Data, taxonomy
340 */
341 $course_post_type = tutor()->course_post_type;
342 $lesson_post_type = tutor()->lesson_post_type;
343
344 $post_types = array(
345 $course_post_type,
346 $lesson_post_type,
347 'tutor_quiz',
348 'tutor_enrolled',
349 'topics',
350 'tutor_enrolled',
351 'tutor_announcements',
352 );
353
354 $post_type_strings = "'".implode("','", $post_types)."'";
355 $tutor_posts = $wpdb->get_col("SELECT ID from {$wpdb->posts} WHERE post_type in({$post_type_strings}) ;");
356
357 if (is_array($tutor_posts) && count($tutor_posts)){
358 foreach ($tutor_posts as $post_id){
359 //Delete categories
360 $terms = wp_get_object_terms( $post_id, 'course-category' );
361 foreach( $terms as $term ){
362 /**D*/ wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-category' );
363 }
364
365 //Delete tags if available
366 $terms = wp_get_object_terms( $post_id, 'course-tag' );
367 foreach( $terms as $term ){
368 /**D*/ wp_remove_object_terms( $post_id, array( $term->term_id ), 'course-tag' );
369 }
370
371 //Delete All Meta
372 /**D*/ $wpdb->delete($wpdb->postmeta, array('post_id' => $post_id) );
373 /**D*/ $wpdb->delete($wpdb->posts, array('ID' => $post_id) );
374 }
375 }
376
377 /**
378 * Deleting Comments (reviews, questions, quiz_answers, etc)
379 */
380 $tutor_comments = $wpdb->get_col("SELECT comment_ID from {$wpdb->comments} WHERE comment_agent = 'comment_agent' ;");
381 $comments_ids_strings = "'".implode("','", $tutor_comments)."'";
382 if (is_array($tutor_comments) && count($tutor_comments)){
383 /**D*/ $wpdb->query("DELETE from {$wpdb->commentmeta} WHERE comment_ID in({$comments_ids_strings}) ");
384 }
385 /**D*/ $wpdb->delete($wpdb->comments, array('comment_agent' => 'comment_agent'));
386
387 /**
388 * Delete Options
389 */
390
391 /**D*/ delete_option('tutor_option');
392 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_is_tutor_student'));
393 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_tutor_instructor_approved'));
394 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_tutor_instructor_status'));
395 /**D*/ $wpdb->delete($wpdb->usermeta, array('meta_key' => '_is_tutor_instructor'));
396 /**D*/ $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%_tutor_completed_lesson_id_%' ");
397
398 //Deleting Table
399 $prefix = $wpdb->prefix;
400 /**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 ");
401
402 deactivate_plugins($plugin_file);
403 }
404
405 wp_redirect('plugins.php');
406 die();
407 }
408
409 public function plugin_action_links($actions){
410 $hasPro = tutor()->has_pro;
411
412 if(!$hasPro){
413 $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
414 style="color: #ff7742; font-weight: bold;">' . __('Upgrade to Pro', 'wp-megamenu') . '</span></a>';
415 }
416
417 $is_erase_data = tutor_utils()->get_option('delete_on_uninstall');
418
419 if ($is_erase_data) {
420 $plugin_file = tutor()->basename;
421 if ( current_user_can( 'deactivate_plugin', $plugin_file ) ) {
422 if ( isset( $actions['deactivate'] ) ) {
423 $actions['deactivate'] = '<a href="admin.php?page=tutor-tools&tutor_admin_tools_page=uninstall">' . __('Uninstall', 'tutor') . '</a>';
424 }
425 }
426 }
427
428 $actions['settings'] = '<a href="admin.php?page=tutor_settings">' . __('Settings', 'tutor') . '</a>';
429 return $actions;
430 }
431
432 public function plugin_row_meta($plugin_meta, $plugin_file){
433
434 if ($plugin_file === tutor()->basename) {
435 $plugin_meta[] = sprintf( '<a href="%s">%s</a>',
436 esc_url( 'https://www.themeum.com/docs/tutor-introduction/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_docs_link' ),
437 __( '<strong style="color: #03bd24">Documentation</strong>', 'tutor' )
438 );
439 $plugin_meta[] = sprintf( '<a href="%s">%s</a>',
440 esc_url( 'https://www.themeum.com/support-forums/?utm_source=tutor&utm_medium=plugins_installation_list&utm_campaign=plugin_support_link' ),
441 __( '<strong style="color: #03bd24">Get Support</strong>', 'tutor' )
442 );
443 }
444
445 return $plugin_meta;
446 }
447
448 /**
449 * @param $footer_text
450 *
451 * @return string
452 *
453 * Add footer text only on tutor pages
454 */
455 public function admin_footer_text( $footer_text ) {
456 $current_screen = get_current_screen();
457
458 /**
459 * We are making sure that this message will be only on Tutor Admin page
460 */
461 if ( apply_filters( 'tutor_display_admin_footer_text', (tutor_utils()->array_get('parent_base', $current_screen) === 'tutor' ) ) ) {
462 $footer_text = sprintf(
463 __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'tutor' ),
464 sprintf( '<strong>%s</strong>', esc_html__( 'Tutor LMS', 'tutor' ) ),
465 '<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>'
466 );
467 }
468
469 return $footer_text;
470 }
471
472
473 public function register_course_widget(){
474 register_widget( 'Tutor\Course_Widget' );
475 }
476
477
478 }