Issues (896)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/class-sensei-frontend.php (17 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4
/**
5
 * Sensei Frontend Class
6
 *
7
 * All functionality pertaining to the frontend of Sensei.
8
 *
9
 * @package Core
10
 * @author Automattic
11
 *
12
 * @since 1.0.0
13
 */
14
class Sensei_Frontend {
15
16
	public $messages;
17
	public $data;
18
19
	/**
20
	 * Constructor.
21
	 * @since  1.0.0
22
	 */
23
	public function __construct () {
24
25
		// Template output actions
26
		add_action( 'sensei_before_main_content', array( $this, 'sensei_output_content_wrapper' ), 10 );
27
		add_action( 'sensei_after_main_content', array( $this, 'sensei_output_content_wrapper_end' ), 10 );
28
		add_action( 'sensei_lesson_archive_lesson_title', array( $this, 'sensei_lesson_archive_lesson_title' ), 10 );
29
30
		// 1.2.1
31
		add_action( 'wp_head', array( $this, 'sensei_complete_lesson' ), 10 );
32
		add_action( 'wp_head', array( $this, 'sensei_complete_course' ), 10 );
33
		add_action( 'sensei_frontend_messages', array( $this, 'sensei_frontend_messages' ) );
34
		add_action( 'sensei_lesson_video', array( $this, 'sensei_lesson_video' ), 10, 1 );
35
		add_action( 'sensei_complete_lesson_button', array( $this, 'sensei_complete_lesson_button' ) );
36
		add_action( 'sensei_reset_lesson_button', array( $this, 'sensei_reset_lesson_button' ) );
37
38
		add_action( 'sensei_course_archive_meta', array( $this, 'sensei_course_archive_meta' ) );
39
40
		add_action( 'sensei_lesson_tag_main_content', array( $this, 'sensei_lesson_archive_main_content' ), 10 );
41
		add_action( 'sensei_no_permissions_main_content', array( $this, 'sensei_no_permissions_main_content' ), 10 );
42
43
		add_action( 'sensei_lesson_meta', array( $this, 'sensei_lesson_meta' ), 10 );
44
		add_action( 'sensei_single_course_content_inside_before', array( $this, 'sensei_course_start' ), 10 );
45
46
		// add_filter( 'get_comments_number', array( $this, 'sensei_lesson_comment_count' ), 1 );
47
		add_filter( 'the_title', array( $this, 'sensei_lesson_preview_title' ), 10, 2 );
48
49
		//1.6.2
50
		add_filter( 'wp_login_failed', array( $this, 'sensei_login_fail_redirect' ), 10 );
51
		add_filter( 'init', array( $this, 'sensei_handle_login_request' ), 10 );
52
		//1.6.3
53
		add_action( 'init', array( $this, 'sensei_process_registration' ), 2 );
54
		//1.7.0
55
		add_action( 'sensei_pagination', array( $this, 'sensei_breadcrumb' ), 80, 1 );
56
57
		// Fix pagination for course archive pages when filtering by course type
58
		add_filter( 'pre_get_posts', array( $this, 'sensei_course_archive_pagination' ) );
59
60
		// Scripts and Styles
61
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ) );
62
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
63
64
		// Custom Menu Item filters
65
		add_filter( 'wp_setup_nav_menu_item', array( $this, 'sensei_setup_nav_menu_item' ) );
66
		add_filter( 'wp_nav_menu_objects', array( $this, 'sensei_wp_nav_menu_objects' ) );
67
		// Search Results filters
68
		add_filter( 'post_class', array( $this, 'sensei_search_results_classes' ), 10 );
69
		// Only show course & lesson excerpts in search results
70
		add_filter( 'the_content', array( $this, 'sensei_search_results_excerpt' ) );
71
72
        //Use WooCommerce filter to show admin bar to Teachers.
73
        add_action( 'init', array( $this, 'sensei_show_admin_bar') );
74
75
        // Remove course from active courses if an order is cancelled or refunded
76
		add_action( 'woocommerce_order_status_processing_to_cancelled', array( $this, 'remove_active_course' ), 10, 1 );
77
		add_action( 'woocommerce_order_status_completed_to_cancelled', array( $this, 'remove_active_course' ), 10, 1 );
78
		add_action( 'woocommerce_order_status_on-hold_to_cancelled', array( $this, 'remove_active_course' ), 10, 1 );
79
		add_action( 'woocommerce_order_status_processing_to_refunded', array( $this, 'remove_active_course' ), 10, 1 );
80
		add_action( 'woocommerce_order_status_completed_to_refunded', array( $this, 'remove_active_course' ), 10, 1 );
81
		add_action( 'woocommerce_order_status_on-hold_to_refunded', array( $this, 'remove_active_course' ), 10, 1 );
82
83
		// Make sure correct courses are marked as active for users
84
		add_action( 'sensei_before_my_courses', array( $this, 'activate_purchased_courses' ), 10, 1 );
85
		add_action( 'sensei_single_course_content_inside_before', array( $this, 'activate_purchased_single_course' ), 10 );
86
87
		// Lesson tags
88
		add_action( 'sensei_lesson_meta_extra', array( $this, 'lesson_tags_display' ), 10, 1 );
89
		add_action( 'pre_get_posts', array( $this, 'lesson_tag_archive_filter' ), 10, 1 );
90
		add_filter( 'sensei_lessons_archive_text', array( $this, 'lesson_tag_archive_header' ) );
91
		add_action( 'sensei_loop_lesson_inside_before', array( $this, 'lesson_tag_archive_description' ), 11 );
92
93
		// Hide Sensei activity comments from lesson and course pages
94
		add_filter( 'wp_list_comments_args', array( $this, 'hide_sensei_activity' ) );
95
	} // End __construct()
96
97
	/**
98
	 * Graceful fallback for course and lesson variables on Frontend object
99
	 *
100
	 * @param string $key Key to get.
101
	 * @since  1.7.3
102
	 * @return array|mixed
103
	 */
104
	public function __get( $key ) {
105
106
		if ( 'lesson' == $key || 'course' == $key ) {
107
			if ( WP_DEBUG ) {
108
				trigger_error( sprintf( 'Sensei()->frontend->%1$s has been <strong>deprecated</strong> since version %2$s! Please use Sensei()->%1$s to access the instance.', $key, '1.7.3' ) );
109
			}
110
			return Sensei()->$key;
111
		}
112
113
		return null;
114
	}
115
116
	/**
117
	 * Enqueue frontend JavaScripts.
118
	 * @since  1.0.0
119
	 * @return void
120
	 */
121
	public function enqueue_scripts () {
122
123
		$disable_js = false;
124
		if ( isset( Sensei()->settings->settings[ 'js_disable' ] ) ) {
125
			$disable_js = Sensei()->settings->settings[ 'js_disable' ];
126
		} // End If Statement
127
		if ( ! $disable_js ) {
128
129
			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
130
131
			// My Courses tabs script
132
			wp_register_script( Sensei()->token . '-user-dashboard', esc_url( Sensei()->plugin_url . 'assets/js/user-dashboard' . $suffix . '.js' ), array( 'jquery-ui-tabs' ), Sensei()->version, true );
133
			wp_enqueue_script( Sensei()->token . '-user-dashboard' );
134
135
136
            // Course Archive javascript
137
            if( is_post_type_archive( 'course' ) ){
138
139
                wp_register_script( 'sensei-course-archive-js', esc_url( Sensei()->plugin_url . 'assets/js/frontend/course-archive' . $suffix . '.js' ), array( 'jquery' ), '1', true );
140
                wp_enqueue_script( 'sensei-course-archive-js' );
141
142
            }
143
144
145
			// Allow additional scripts to be loaded
146
			do_action( 'sensei_additional_scripts' );
147
148
		} // End If Statement
149
150
	} // End enqueue_scripts()
151
152
	/**
153
	 * Enqueue frontend CSS files.
154
	 * @since  1.0.0
155
	 * @return void
156
	 */
157
	public function enqueue_styles () {
158
159
		$disable_styles = false;
160
		if ( isset( Sensei()->settings->settings[ 'styles_disable' ] ) ) {
161
			$disable_styles = Sensei()->settings->settings[ 'styles_disable' ];
162
		} // End If Statement
163
164
		// Add filter for theme overrides
165
		$disable_styles = apply_filters( 'sensei_disable_styles', $disable_styles );
166
167
		if ( ! $disable_styles ) {
168
169
			wp_register_style( Sensei()->token . '-frontend', Sensei()->plugin_url . 'assets/css/frontend/sensei.css', '', Sensei()->version, 'screen' );
170
			wp_enqueue_style( Sensei()->token . '-frontend' );
171
172
			// Allow additional stylesheets to be loaded
173
			do_action( 'sensei_additional_styles' );
174
175
		} // End If Statement
176
177
	} // End enqueue_styles()
178
179
180
	/**
181
	 * sensei_get_template_part function.
182
	 *
183
     * @deprecated sine 1.9.0
184
	 * @access public
185
	 * @param mixed $slug
186
	 * @param string $name (default: '')
187
	 * @return void
188
	 */
189
	function sensei_get_template_part( $slug, $name = '' ) {
190
191
        _deprecated_function( 'class-woothemes-sensei-frontend.php', '1.9.0', 'Sensei_Templates::get_part' );
192
        Sensei_Templates::get_part( $slug, $name );
193
194
	} // End sensei_get_template_part()
195
196
	/**
197
	 * sensei_get_template function.
198
	 *
199
     * @deprecated since 1.9.0
200
	 * @access public
201
	 * @param mixed $template_name
202
	 * @param array $args (default: array())
203
	 * @param string $template_path (default: '')
204
	 * @param string $default_path (default: '')
205
	 * @return void
206
	 */
207
	function sensei_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
208
209
        _deprecated_function( 'sensei_get_template', '1.9.0', 'Sensei_Templates::get_template' );
210
        Sensei_Templates::get_template($template_name, $args, $template_path, $default_path  );
211
212
	} // End sensei_get_template()
213
214
215
	/**
216
	 * sensei_locate_template function.
217
	 *
218
	 * @access public
219
	 * @param mixed $template_name
220
	 * @param string $template_path (default: '')
221
	 * @param string $default_path (default: '')
222
	 * @return void
223
	 */
224
	function sensei_locate_template( $template_name, $template_path = '', $default_path = '' ) {
225
226
        _deprecated_function( 'sensei_locate_template', '1.9.0', 'Sensei_Templates::locate_template' );
227
        Sensei_Templates::locate_template( $template_name, $template_path, $default_path );
228
229
	} // End sensei_locate_template()
230
231
232
	/**
233
	 * sensei_output_content_wrapper function.
234
     *
235
	 * @access public
236
	 * @return void
237
	 */
238 View Code Duplication
	function sensei_output_content_wrapper() {
239
240
	    // backwards compatibility check for old location under the wrappers directory of the active theme
241
        $backwards_compatible_wrapper_location =   array(
242
            Sensei()->template_url . 'wrappers/wrapper-start.php',
243
            'wrappers/wrapper-start.php'
244
        );
245
246
        $template = locate_template( $backwards_compatible_wrapper_location );
247
        if( !empty( $template ) ){
248
249
            Sensei_Templates::get_template( 'wrappers/wrapper-start.php' );
250
            return;
251
252
        }
253
254
		Sensei_Templates::get_template( 'globals/wrapper-start.php' );
255
256
	} // End sensei_output_content_wrapper()
257
258
259
	/**
260
	 * sensei_output_content_wrapper_end function.
261
     *
262
	 * @access public
263
	 * @return void
264
	 */
265 View Code Duplication
	function sensei_output_content_wrapper_end() {
266
267
	    // backwards compatibility check for old location under the wrappers directory of the active theme
268
        $backwards_compatible_wrapper_location =   array(
269
            Sensei()->template_url . 'wrappers/wrapper-end.php',
270
            'wrappers/wrapper-end.php'
271
        );
272
273
        $backwards_compatible_template = locate_template( $backwards_compatible_wrapper_location );
274
        if( !empty( $backwards_compatible_template ) ){
275
276
            Sensei_Templates::get_template( 'wrappers/wrapper-end.php' );
277
            return;
278
279
        }
280
281
282
		Sensei_Templates::get_template( 'globals/wrapper-end.php' );
283
284
	} // End sensei_output_content_wrapper_end()
285
286
287
	/**
288
	 * sensei_output_content_pagination function.
289
	 *
290
	 * @access public
291
	 * @return void
292
	 */
293
	public static function load_content_pagination() {
294
295
        if( is_singular('course') ) {
296
297
            // backwards compatibility check for old location under the wrappers directory of the active theme
298
            $template = locate_template( array( Sensei()->template_url . 'wrappers/pagination-posts.php' ) );
299
            if( !empty( $template ) ){
300
301
                Sensei_Templates::get_template( 'wrappers/pagination-posts.php' );
302
                return;
303
304
            }
305
306
			Sensei_Templates::get_template( 'globals/pagination-posts.php' );
307
308 View Code Duplication
		} elseif( is_singular('lesson') ) {
309
310
		    // backwards compatibility check for old location under the wrappers directory of the active theme
311
		    $template = locate_template( array( Sensei()->template_url . 'wrappers/pagination-lesson.php' ) );
312
            if( !empty( $template ) ){
313
314
                Sensei_Templates::get_template( 'wrappers/pagination-lesson.php' );
315
                return;
316
317
            }
318
319
			Sensei_Templates::get_template( 'globals/pagination-lesson.php' );
320
321
		} elseif( is_singular('quiz') ) {
322
323
		    // backwards compatibility check for old location under the wrappers directory of the active theme
324
		    $template = locate_template( array( Sensei()->template_url . 'wrappers/pagination-quiz.php' ) );
325
            if( !empty( $template ) ){
326
327
                Sensei_Templates::get_template( 'wrappers/pagination-quiz.php' );
328
                return;
329
330
            }
331
332
			Sensei_Templates::get_template( 'globals/pagination-quiz.php' );
333
334 View Code Duplication
		} else {
335
336
            // backwards compatibility check for old location under the wrappers directory of the active theme
337
            $template = locate_template( array( Sensei()->template_url . 'wrappers/pagination.php' ) );
338
            if( !empty( $template ) ){
339
340
                Sensei_Templates::get_template( 'wrappers/pagination.php' );
341
                return;
342
343
            }
344
345
			Sensei_Templates::get_template( 'globals/pagination.php' );
346
347
		} // End If Statement
348
349
	} // End sensei_output_content_pagination()
350
351
	/**
352
	 * outputs comments for the specified pages
353
	 * @deprecated
354
	 * @return void
355
	 */
356
	function sensei_output_comments() {
357
358
		Sensei_Lesson::output_comments();
359
360
	} // End sensei_output_comments()
361
362
	/**
363
	 * sensei_setup_nav_menu_item function.
364
	 *
365
	 * Generate the urls for Sensei custom menu items.
366
	 *
367
	 * @access public
368
	 * @param object $item
369
	 * @return object $item
370
	 */
371
	public function sensei_setup_nav_menu_item( $item ) {
372
		global $pagenow, $wp_rewrite;
373
374
		if( 'nav-menus.php' != $pagenow && !defined('DOING_AJAX') && isset( $item->url ) && 'custom' == $item->type ) {
375
376
			// Set up Sensei menu links
377
			$course_page_id = intval( Sensei()->settings->settings[ 'course_page' ] );
0 ignored issues
show
$course_page_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
378
			$my_account_page_id = intval( Sensei()->settings->settings[ 'my_course_page' ] );
379
380
			$course_page_url = Sensei_Course::get_courses_page_url();
381
			$lesson_archive_url = get_post_type_archive_link( 'lesson' );
382
			$my_courses_url = get_permalink( $my_account_page_id );
383
			$my_messages_url = get_post_type_archive_link( 'sensei_message' );
384
385
			switch ( $item->url ) {
386
				case '#senseicourses':
387
					$item->url = $course_page_url;
388
					break;
389
390
				case '#senseilessons':
391
					$item->url = $lesson_archive_url;
392
					break;
393
394
				case '#senseimycourses':
395
					$item->url = $my_courses_url;
396
					break;
397
398
				case '#senseimymessages':
399
					$item->url = $my_messages_url;
400
                    // if no archive link exist for sensei_message
401
                    // set it back to the place holder
402
                    if( ! $item->url ){
403
404
                        $item->url = '#senseimymessages';
405
406
                    }
407
					break;
408
409
				case '#senseilearnerprofile':
410
					$item->url = esc_url( Sensei()->learner_profiles->get_permalink() );
411
					break;
412
413
				case '#senseiloginlogout':
414
						$logout_url = wp_logout_url( home_url() );
415
						// Login link links to the My Courses page, to avoid the WP dashboard.
416
						$login_url = $my_courses_url;
417
418
						$item->url = ( is_user_logged_in() ? $logout_url : $login_url );
419
420
						// determine the menu title login or logout
421
						if ( is_user_logged_in() ) {
422
							$menu_title =  __( 'Logout'  ,'woothemes-sensei');
423
						} else {
424
							$menu_title =  __( 'Login'  ,'woothemes-sensei');
425
						}
426
427
						/**
428
						 * Action Filter: login/logout menu title
429
						 *
430
						 * With this filter you can alter the login / login menu item title string
431
						 *
432
						 * @param $menu_title
433
						 */
434
						$item->title = apply_filters( 'sensei_login_logout_menu_title', $menu_title );
435
436
					break;
437
438
				default:
439
					break;
440
			}
441
442
			$_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] );
443
			$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_root_relative_current );
444
			$item_url = untrailingslashit( $item->url );
445
			$_indexless_current = untrailingslashit( preg_replace( '/' . preg_quote( $wp_rewrite->index, '/' ) . '$/', '', $current_url ) );
446
			// Highlight current menu item
447
			if ( $item_url && in_array( $item_url, array( $current_url, $_indexless_current, $_root_relative_current ) ) ) {
448
				$item->classes[] = 'current-menu-item current_page_item';
449
			}
450
451
		} // endif nav
452
453
		return $item;
454
455
	} // End sensei_setup_nav_menu_item()
456
457
	/**
458
	 * sensei_wp_nav_menu_objects function.
459
	 *
460
	 * Remove Sensei custom menu items depending on settings and logged in status.
461
	 *
462
	 * @access public
463
	 * @param object $sorted_menu_items
464
	 * @return object $sorted_menu_items
465
	 */
466
	public function sensei_wp_nav_menu_objects( $sorted_menu_items ) {
467
468
		foreach( $sorted_menu_items as $k=>$item ) {
469
470
			// Remove the My Messages link for logged out users or if Private Messages are disabled
471 View Code Duplication
			if( ! get_post_type_archive_link( 'sensei_message' )
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
472
                && '#senseimymessages' == $item->url ) {
473
474
				if ( !is_user_logged_in() || ( isset( Sensei()->settings->settings['messages_disable'] ) && Sensei()->settings->settings['messages_disable'] ) ) {
475
476
					unset( $sorted_menu_items[$k] );
477
478
				}
479
			}
480
			// Remove the My Profile link for logged out users.
481 View Code Duplication
			if( Sensei()->learner_profiles->get_permalink() == $item->url ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
482
483
				if ( !is_user_logged_in() || ! ( isset( Sensei()->settings->settings[ 'learner_profile_enable' ] ) && Sensei()->settings->settings[ 'learner_profile_enable' ] ) ) {
484
485
					unset( $sorted_menu_items[$k] );
486
487
				}
488
			}
489
		}
490
		return $sorted_menu_items;
491
	} // End sensei_wp_nav_menu_objects
492
493
	// add category nicenames in body and post class
494
	function sensei_search_results_classes($classes) {
495
	    global $post;
496
	    // Handle Search Classes for Courses, Lessons, and WC Products
497
	    if ( isset( $post->post_type ) && ( ( 'course' == $post->post_type ) || ( 'lesson' == $post->post_type ) || ( 'product' == $post->post_type ) ) ) {
498
	    	$classes[] = 'post';
499
		} // End If Statement
500
	    return $classes;
501
	} // End sensei_search_results_classes()
502
503
    /**
504
     * sensei_single_title output for single page title
505
     * @since  1.1.0
506
     * @return void
507
     * @deprecated
508
     */
509
    function the_single_title() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
510
511
        _deprecated_function(' WooThemes_Sensei_Frontend::the_single_title', '1.9.0');
512
513
    } // End sensei_single_title()
514
515
	/**
516
	 * sensei_course_image output for course image Please use Sensei()->course->course_image instead.
517
     *
518
     * @deprecated since 1.9.0
519
     * @param $course_id
520
     * @param string $width
521
     * @param string $height
522
     * @param bool|false $return
523
     * @return string|void
524
	 */
525
	function sensei_course_image( $course_id, $width = '100', $height = '100', $return = false ) {
526
527
    	if ( ! $return ) {
528
529
			echo Sensei()->course->course_image( $course_id, $width, $height );
530
            return '';
531
532
		} // End If Statement
533
534
		return Sensei()->course->course_image( $course_id, $width, $height );
535
536
	} // End sensei_course_image()
537
538
	/**
539
	 * sensei_lesson_image output for lesson image
540
	 * @since  1.2.0
541
     * @deprecated since 1.9.0
542
     * @param $lesson_id
543
     * @param string $width
544
     * @param string $height
545
     * @param bool|false $return
546
     * @param bool|false $widget
547
     * @return string
548
	 */
549
	function sensei_lesson_image( $lesson_id, $width = '100', $height = '100', $return = false, $widget = false ) {
550
551
        if( ! $return ){
552
553
            echo Sensei()->lesson->lesson_image( $lesson_id, $width, $height, $widget );
554
            return '';
555
        }
556
557
        return Sensei()->lesson->lesson_image( $lesson_id, $width, $height, $widget );
558
559
	} // End sensei_lesson_image()
560
561
    /**
562
     * @since 1.0.0
563
     * @param WP_Query $query
564
     */
565
    function sensei_course_archive_pagination( $query ) {
566
567
		if( ! is_admin() && $query->is_main_query() && isset( $_GET['action'] ) && in_array( $_GET['action'], array( 'newcourses', 'featuredcourses', 'freecourses', 'paidcourses' ) ) ) {
568
569
			$amount = 0;
570
			if ( isset( Sensei()->settings->settings[ 'course_archive_amount' ] ) && ( 0 < absint( Sensei()->settings->settings[ 'course_archive_amount' ] ) ) ) {
571
				$amount = absint( Sensei()->settings->settings[ 'course_archive_amount' ] );
572
			}
573
574
			if( $amount ) {
575
				$query->set( 'posts_per_page', $amount );
576
			}
577
578
			$query->set( 'orderby', 'menu_order date' );
579
580
		}
581
	}
582
583
	/**
584
	 * sensei_course_archive_header function.
585
	 *
586
	 * @access public
587
	 * @since  1.2.0
588
     * @deprecated since 1.9.0 use WooThemes_Sensei_Course::archive_header
589
	 * @return void
590
	 */
591
	function sensei_course_archive_header(  ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
592
593
        trigger_error('This function sensei_course_archive_header has been depricated. Please use: WooThemes_Sensei_Course::course_archive_header ');
594
        WooThemes_Sensei_Course::archive_header( '', '<header class="archive-header"><h1>', '</h1></header>' );
595
596
	} // sensei_course_archive_header()
597
598
	/**
599
	 * sensei_lesson_archive_header function.
600
	 *
601
     * @deprecated since 1.9.0
602
	 * @access public
603
	 * @since  1.2.1
604
	 * @return void
605
	 */
606
	public function sensei_lesson_archive_header( ) {
607
        _deprecated_function( 'WooThemes_Sensei_Frontend::sensei_lesson_archive_header', '1.9.0', 'WooThemes_Sensei_Lesson::the_archive_header' );
608
        Sensei()->lesson->the_archive_header();
609
	} // sensei_course_archive_header()
610
611
    /**
612
     * @deprecated since 1.9.0
613
     */
614
	public function sensei_message_archive_header( ){
615
        _deprecated_function('Sensei_Frontend::sensei_message_archive_header','Please use: Sense');
616
        Sensei_Messages::the_archive_header();
617
	} // sensei_message_archive_header()
618
619
	/**
620
	 * sensei_course_archive_course_title output for course archive page individual course title
621
	 * @since  1.2.0
622
     * @param WP_Post $post_item
623
	 * @return void
624
	 */
625
	function sensei_course_archive_course_title( $post_item ) {
626
		if ( isset( $post_item->ID ) && ( 0 < $post_item->ID ) ) {
627
			$post_id = absint( $post_item->ID );
628
    		$post_title = $post_item->post_title;
629
		} else {
630
			$post_id = get_the_ID();
631
    		$post_title = get_the_title();
632
		} // End If Statement
633
		?><header><h2><a href="<?php echo get_permalink( $post_id ); ?>" title="<?php echo esc_attr( $post_title ); ?>"><?php echo $post_title; ?></a></h2></header><?php
634
	} // End sensei_course_archive_course_title()
635
636
	/**
637
	 * sensei_lesson_archive_lesson_title output for course archive page individual course title
638
	 * @since  1.2.1
639
	 * @return void
640
	 */
641
	public function sensei_lesson_archive_lesson_title() {
642
		$post_id = get_the_ID();
643
    	$post_title = get_the_title();
644
		?><header><h2><a href="<?php echo get_permalink( $post_id ); ?>" title="<?php echo esc_attr( $post_title ); ?>"><?php echo $post_title; ?></a></h2></header><?php
645
	} // End sensei_lesson_archive_lesson_title()
646
647
	/**
648
	 * sensei_breadcrumb outputs Sensei breadcrumb trail on lesson & quiz pages
649
	 * @since  1.7.0
650
	 * @param  integer $id course, lesson or quiz id
651
	 * @return void
652
	 */
653
	public function sensei_breadcrumb( $id = 0 ) {
654
655
		// Only output on lesson, quiz and taxonomy (module) pages
656
		if( ! ( is_tax( 'module' ) || is_singular( 'lesson' ) || is_singular( 'quiz' ) ) ) return;
657
658
		if( empty( $id )  ){
659
660
            $id = get_the_ID();
661
662
        }
663
664
		$sensei_breadcrumb_prefix = __( 'Back to: ', 'woothemes-sensei' );
665
		$separator = apply_filters( 'sensei_breadcrumb_separator', '&gt;' );
666
667
		$html = '<section class="sensei-breadcrumb">' . $sensei_breadcrumb_prefix;
668
		// Lesson
669 View Code Duplication
		if ( is_singular( 'lesson' ) && 0 < intval( $id ) ) {
670
			$course_id = intval( get_post_meta( $id, '_lesson_course', true ) );
671
			if( ! $course_id ) {
672
				return;
673
			}
674
			$html .= '<a href="' . esc_url( get_permalink( $course_id ) ) . '" title="' . __( 'Back to the course', 'woothemes-sensei' ) . '">' . get_the_title( $course_id ) . '</a>';
675
    	} // End If Statement
676
    	// Quiz
677 View Code Duplication
		if ( is_singular( 'quiz' ) && 0 < intval( $id ) ) {
678
			$lesson_id = intval( get_post_meta( $id, '_quiz_lesson', true ) );
679
			if( ! $lesson_id ) {
680
				return;
681
			}
682
			 $html .= '<a href="' . esc_url( get_permalink( $lesson_id ) ) . '" title="' .  __( 'Back to the lesson', 'woothemes-sensei' ) . '">' . get_the_title( $lesson_id ) . '</a>';
683
    	} // End If Statement
684
685
    	// Allow other plugins to filter html
686
    	$html = apply_filters ( 'sensei_breadcrumb_output', $html, $separator );
687
    	$html .= '</section>';
688
689
    	echo $html;
690
	} // End sensei_breadcrumb()
691
692
693
    /**
694
     * @deprecated since 1.9.0 use WooThemes_Sensei_Lesson::course_signup_link instead
695
     */
696
	public function sensei_lesson_course_signup_link( ) {
697
698
        _deprecated_function('sensei_lesson_course_signup_link', '1.9.0', 'WooThemes_Sensei_Lesson::course_signup_link' );
699
        WooThemes_Sensei_Lesson::course_signup_link();
700
	}
701
702
	public function lesson_tags_display( $lesson_id = 0 ) {
703
		if( $lesson_id ) {
704
			$tags = wp_get_post_terms( $lesson_id, 'lesson-tag' );
705
			if( $tags && count( $tags ) > 0 ) {
706
				$tag_list = '';
707
				foreach( $tags as $tag ) {
708
					$tag_link = get_term_link( $tag, 'lesson-tag' );
709
					if( ! is_wp_error( $tag_link ) ) {
710
						if( $tag_list ) { $tag_list .= ', '; }
711
						$tag_list .= '<a href="' . $tag_link . '">' . $tag->name . '</a>';
712
					}
713
				}
714
				if( $tag_list ) {
715
					?><section class="lesson-tags">
716
		    			<?php printf( __( 'Lesson tags: %1$s', 'woothemes-sensei' ), $tag_list ); ?>
717
		    		</section><?php
718
		    	}
719
	    	}
720
		}
721
	}
722
723
    /**
724
     * @param WP_Query $query
725
     */
726
	public function lesson_tag_archive_filter( $query ) {
727
    	if( is_tax( 'lesson-tag' ) && $query->is_main_query() ) {
728
    		// Limit to lessons only
729
    		$query->set( 'post_type', 'lesson' );
730
731
    		// Set order of lessons
732
    		$query->set( 'orderby', 'menu_order' );
733
    		$query->set( 'order', 'ASC' );
734
735
    	}
736
    }
737
738
    public function lesson_tag_archive_header( $title ) {
739
		if( is_tax( 'lesson-tag' ) ) {
740
			$title = sprintf( __( 'Lesson tag: %1$s', 'woothemes-sensei' ), apply_filters( 'sensei_lesson_tag_archive_title', get_queried_object()->name ) );
741
		}
742
		return $title;
743
	}
744
745
	public function lesson_tag_archive_description() {
746
		if( is_tax( 'lesson-tag' ) ) {
747
			$tag = get_queried_object();
748
			echo '<p class="archive-description lesson-description">' . apply_filters( 'sensei_lesson_tag_archive_description', nl2br( $tag->description ), $tag->term_id ) . '</p>';
749
		}
750
	}
751
752
	public function sensei_complete_lesson() {
753
		global $post,  $current_user;
754
		// Handle Quiz Completion
755
		if ( isset( $_POST['quiz_action'] ) && wp_verify_nonce( $_POST[ 'woothemes_sensei_complete_lesson_noonce' ], 'woothemes_sensei_complete_lesson_noonce' ) ) {
756
757
			$sanitized_submit = esc_html( $_POST['quiz_action'] );
758
759
			switch ($sanitized_submit) {
760
                case 'lesson-complete':
761
762
					Sensei_Utils::sensei_start_lesson( $post->ID, $current_user->ID, $complete = true );
763
764
					break;
765
766
                case 'lesson-reset':
767
768
					Sensei_Utils::sensei_remove_user_from_lesson( $post->ID, $current_user->ID );
769
770
					$this->messages = '<div class="sensei-message note">' .  __( 'Lesson Reset Successfully.', 'woothemes-sensei' ) . '</div>';
771
					break;
772
773
				default:
774
					// Nothing
775
					break;
776
777
			} // End Switch Statement
778
779
		} // End If Statement
780
781
	} // End sensei_complete_lesson()
782
783
	public function sensei_complete_course() {
784
		global $post,  $current_user, $wp_query;
785
		if ( isset( $_POST['course_complete'] ) && wp_verify_nonce( $_POST[ 'woothemes_sensei_complete_course_noonce' ], 'woothemes_sensei_complete_course_noonce' ) ) {
786
787
			$sanitized_submit = esc_html( $_POST['course_complete'] );
788
			$sanitized_course_id = absint( esc_html( $_POST['course_complete_id'] ) );
789
			// Handle submit data
790
			switch ($sanitized_submit) {
791
				case __( 'Mark as Complete', 'woothemes-sensei' ):
792
793
					// Add user to course
794
					$course_metadata = array(
795
						'start' => current_time('mysql'),
796
						'percent' => 0, // No completed lessons yet
797
						'complete' => 0,
798
					);
799
					$activity_logged = Sensei_Utils::update_course_status( $current_user->ID, $sanitized_course_id, 'in-progress', $course_metadata );
800
801
					if ( $activity_logged ) {
802
						// Get all course lessons
803
						$course_lesson_ids = Sensei()->course->course_lessons( $sanitized_course_id, 'any', 'ids' );
804
						// Mark all quiz user meta lessons as complete
805
						foreach ( $course_lesson_ids as $lesson_item_id ){
806
							// Mark lesson as complete
807
							$activity_logged = Sensei_Utils::sensei_start_lesson( $lesson_item_id, $current_user->ID, $complete = true );
0 ignored issues
show
$activity_logged is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
808
						} // End For Loop
809
810
						// Update with final stats
811
						$course_metadata = array(
812
							'percent' => 100,
813
							'complete' => count($course_lesson_ids),
814
						);
815
						$activity_logged = Sensei_Utils::update_course_status( $current_user->ID, $sanitized_course_id, 'complete', $course_metadata );
0 ignored issues
show
$activity_logged is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
816
817
						do_action( 'sensei_user_course_end', $current_user->ID, $sanitized_course_id );
818
819
						// Success message
820
						$this->messages = '<header class="archive-header"><div class="sensei-message tick">' . sprintf( __( '%1$s marked as complete.', 'woothemes-sensei' ), get_the_title( $sanitized_course_id ) ) . '</div></header>';
821
					} // End If Statement
822
823
					break;
824
825
				case __( 'Delete Course', 'woothemes-sensei' ):
826
827
					Sensei_Utils::sensei_remove_user_from_course( $sanitized_course_id, $current_user->ID );
828
829
					// Success message
830
					$this->messages = '<header class="archive-header"><div class="sensei-message tick">' . sprintf( __( '%1$s deleted.', 'woothemes-sensei' ), get_the_title( $sanitized_course_id ) ) . '</div></header>';
831
					break;
832
833
				default:
834
					// Nothing
835
					break;
836
			} // End Switch Statement
837
838
		} // End If Statement
839
	} // End sensei_complete_course()
840
841
	/**
842
	 * @deprecated use WooThemes_Sensei_Quiz::get_user_answers
843
	 * @param int $lesson_id
844
	 * @return array
845
	 */
846
	public function sensei_get_user_quiz_answers( $lesson_id = 0 ) {
847
		global $current_user;
848
849
		$user_answers = array();
850
851
		if ( 0 < intval( $lesson_id ) ) {
852
			$lesson_quiz_questions = Sensei()->lesson->lesson_quiz_questions( $lesson_id );
853
			foreach( $lesson_quiz_questions as $question ) {
854
				$answer = maybe_unserialize( base64_decode( Sensei_Utils::sensei_get_activity_value( array( 'post_id' => $question->ID, 'user_id' => $current_user->ID, 'type' => 'sensei_user_answer', 'field' => 'comment_content' ) ) ) );
855
				$user_answers[ $question->ID ] = $answer;
856
			}
857
		}
858
859
		return $user_answers;
860
	} // End sensei_get_user_quiz_answers()
861
862
	public function sensei_has_user_completed_lesson( $post_id = 0, $user_id = 0 ) {
863
		_deprecated_function( __FUNCTION__, '1.7', "WooThemes_Sensei_Utils::user_completed_lesson()" );
864
		return Sensei_Utils::user_completed_lesson( $post_id, $user_id );
865
	} // End sensei_has_user_completed_lesson()
866
867
/**
868
*
869
 */
870
	public function sensei_frontend_messages() {
871
		Sensei()->notices->maybe_print_notices();
872
	} // End sensei_frontend_messages()
873
874 View Code Duplication
	public function sensei_lesson_video( $post_id = 0 ) {
875
		if ( 0 < intval( $post_id ) ) {
876
			$lesson_video_embed = get_post_meta( $post_id, '_lesson_video_embed', true );
877
			if ( 'http' == substr( $lesson_video_embed, 0, 4) ) {
878
        		// V2 - make width and height a setting for video embed
879
        		$lesson_video_embed = wp_oembed_get( esc_url( $lesson_video_embed )/*, array( 'width' => 100 , 'height' => 100)*/ );
880
        	} // End If Statement
881
        	if ( '' != $lesson_video_embed ) {
882
        	?><div class="video"><?php echo html_entity_decode($lesson_video_embed); ?></div><?php
883
        	} // End If Statement
884
        } // End If Statement
885
	} // End sensei_lesson_video()
886
887
	public function sensei_complete_lesson_button() {
888
		global  $post;
889
890
		$quiz_id = 0;
891
892
		//make sure user is taking course
893
		$course_id = Sensei()->lesson->get_course_id( $post->ID );
894
		if( ! Sensei_Utils::user_started_course( $course_id, get_current_user_id() ) ){
0 ignored issues
show
It seems like $course_id defined by Sensei()->lesson->get_course_id($post->ID) on line 893 can also be of type boolean; however, Sensei_Utils::user_started_course() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
895
			return;
896
		}
897
898
		// Lesson quizzes
899
		$quiz_id = Sensei()->lesson->lesson_quizzes( $post->ID );
900
		$pass_required = true;
901
		if( $quiz_id ) {
902
			// Get quiz pass setting
903
	    	$pass_required = get_post_meta( $quiz_id, '_pass_required', true );
904
	    }
905
		if( ! $quiz_id || ( $quiz_id && ! $pass_required ) ) {
906
			?>
907
			<form class="lesson_button_form" method="POST" action="<?php echo esc_url( get_permalink() ); ?>">
908
	            <input type="hidden"
909
                       name="woothemes_sensei_complete_lesson_noonce"
910
                       id="woothemes_sensei_complete_lesson_noonce"
911
                       value="<?php echo esc_attr( wp_create_nonce( 'woothemes_sensei_complete_lesson_noonce' ) ); ?>"
912
                />
913
914
	            <input type="hidden" name="quiz_action" value="lesson-complete" />
915
916
                <input type="submit"
917
                       name="quiz_complete"
918
                       class="quiz-submit complete"
919
                       value="<?php _e( 'Complete Lesson', 'woothemes-sensei' ); ?>"/>
920
921
	        </form>
922
			<?php
923
		} // End If Statement
924
	} // End sensei_complete_lesson_button()
925
926
	public function sensei_reset_lesson_button() {
927
		global  $post;
928
929
		$quiz_id = 0;
930
931
		// Lesson quizzes
932
		$quiz_id = Sensei()->lesson->lesson_quizzes( $post->ID );
933
		$reset_allowed = true;
934
		if( $quiz_id ) {
935
			// Get quiz pass setting
936
			$reset_allowed = get_post_meta( $quiz_id, '_enable_quiz_reset', true );
937
		}
938 View Code Duplication
		if ( ! $quiz_id || !empty($reset_allowed) ) {
939
		?>
940
		<form method="POST" action="<?php echo esc_url( get_permalink() ); ?>">
941
942
            <input
943
            type="hidden"
944
            name="<?php echo esc_attr( 'woothemes_sensei_complete_lesson_noonce' ); ?>"
945
            id="<?php echo esc_attr( 'woothemes_sensei_complete_lesson_noonce' ); ?>"
946
            value="<?php echo esc_attr( wp_create_nonce( 'woothemes_sensei_complete_lesson_noonce' ) ); ?>" />
947
948
            <input type="hidden" name="quiz_action" value="lesson-reset" />
949
950
            <input type="submit" name="quiz_complete" class="quiz-submit reset" value="<?php _e( 'Reset Lesson', 'woothemes-sensei' ); ?>"/>
951
952
        </form>
953
		<?php
954
		} // End If Statement
955
	} // End sensei_reset_lesson_button()
956
957
    /**
958
     * @deprecated since 1.9.0
959
     */
960
    public function sensei_lesson_quiz_meta( ) {
961
962
        Sensei_Lesson::footer_quiz_call_to_action();
963
964
	} // End sensei_lesson_quiz_meta()
965
966
	public function sensei_course_archive_meta() {
967
		global  $post;
968
		// Meta data
969
		$post_id = get_the_ID();
970
		$post_title = get_the_title();
971
		$author_display_name = get_the_author();
972
		$author_id = get_the_author_meta('ID');
973
		$category_output = get_the_term_list( $post_id, 'course-category', '', ', ', '' );
974
		$free_lesson_count = intval( Sensei()->course->course_lesson_preview_count( $post_id ) );
975
		?><section class="entry">
976
        	<p class="sensei-course-meta">
977 View Code Duplication
           	<?php if ( isset( Sensei()->settings->settings[ 'course_author' ] ) && ( Sensei()->settings->settings[ 'course_author' ] ) ) { ?>
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
978
		   	<span class="course-author"><?php _e( 'by ', 'woothemes-sensei' ); ?><?php the_author_link(); ?></span>
979
		   	<?php } // End If Statement ?>
980
		   	<span class="course-lesson-count"><?php echo Sensei()->course->course_lesson_count( $post_id ) . '&nbsp;' . __( 'Lessons', 'woothemes-sensei' ); ?></span>
981
		   	<?php if ( '' != $category_output ) { ?>
982
		   	<span class="course-category"><?php echo sprintf( __( 'in %s', 'woothemes-sensei' ), $category_output ); ?></span>
983
		   	<?php } // End If Statement ?>
984
		   	<?php sensei_simple_course_price( $post_id ); ?>
985
        	</p>
986
        	<p class="course-excerpt"><?php the_excerpt(); ?></p>
987 View Code Duplication
        	<?php if ( 0 < $free_lesson_count ) {
988
                $free_lessons = sprintf( __( 'You can access %d of this course\'s lessons for free', 'woothemes-sensei' ), $free_lesson_count ); ?>
989
                <p class="sensei-free-lessons"><a href="<?php echo get_permalink( $post_id ); ?>"><?php _e( 'Preview this course', 'woothemes-sensei' ) ?></a> - <?php echo $free_lessons; ?></p>
990
            <?php } ?>
991
		</section><?php
992
	} // End sensei_course_archive_meta()
993
994
    /**
995
     * @deprecated since 1.9.0
996
     */
997
	public function sensei_single_main_content() {
998
	    _deprecated_function('Woothemes_Sensei_Frontend::sensei_single_main_content', '1.9.0');
999
	} // End sensei_single_main_content()
1000
1001
    /**
1002
    * @deprecated since 1.9.0
1003
    */
1004
	public function sensei_lesson_archive_main_content() {
1005
        _deprecated_function('Sensei_Frontend::sensei_lesson_archive_main_content', '1.9.0', 'Please include loop-lesson.php directly');
1006
	} // End sensei_lesson_archive_main_content()
1007
1008
    /**
1009
    * @deprecated since 1.9.0
1010
    */
1011
	public function sensei_message_archive_main_content() {
1012
		_deprecated_function( 'Sensei_Frontend::sensei_message_archive_main_content', 'This method is no longer needed' );
1013
	} // End sensei_lesson_archive_main_content()
1014
1015
    /**
1016
    * @deprecated since 1.9.0
1017
    */
1018
	public function sensei_no_permissions_main_content() {
1019
        _deprecated_function( 'Sensei_Frontend::sensei_no_permissions_main_content', 'This method is no longer needed' );
1020
	} // End sensei_no_permissions_main_content()
1021
1022
	public function sensei_course_category_main_content() {
1023
		global $post;
1024
		if ( have_posts() ) { ?>
1025
1026
			<section id="main-course" class="course-container">
1027
1028
                <?php do_action( 'sensei_course_archive_header' ); ?>
1029
1030
                <?php while ( have_posts() ) { the_post(); ?>
1031
1032
                    <article class="<?php echo join( ' ', get_post_class( array( 'course', 'post' ), get_the_ID() ) ); ?>">
1033
1034
	    			    <?php sensei_do_deprecated_action('sensei_course_image','1.9.0', 'sensei_single_course_content_inside_before', get_the_ID() ); ?>
1035
1036
	    			    <?php sensei_do_deprecated_action( 'sensei_course_archive_course_title','1.9.0','sensei_course_content_inside_before', $post ); ?>
1037
1038
	    			    <?php do_action( 'sensei_course_archive_meta' ); ?>
1039
1040
	    		    </article>
1041
1042
                <?php } // End While Loop ?>
1043
1044
	    	</section>
1045
1046
		<?php } else { ?>
1047
1048
			<p>
1049
1050
                <?php _e( 'No courses found that match your selection.', 'woothemes-sensei' ); ?>
1051
1052
            </p>
1053
1054
		<?php } // End If Statement
1055
1056
	} // End sensei_course_category_main_content()
1057
1058
	public function sensei_login_form() {
1059
		?>
1060
		<div id="my-courses">
1061
			<?php Sensei()->notices->maybe_print_notices(); ?>
1062
			<div class="col2-set" id="customer_login">
1063
1064
				<div class="col-1">
1065
					<?php
1066
					// output the actual form markup
1067
                    Sensei_Templates::get_template( 'user/login-form.php');
1068
					?>
1069
				</div>
1070
1071
			<?php
1072
			if ( get_option('users_can_register') ) {
1073
1074
				// get current url
1075
				$action_url = get_permalink();
1076
1077
				?>
1078
1079
				<div class="col-2">
1080
					<h2><?php _e( 'Register', 'woothemes-sensei' ); ?></h2>
1081
1082
					<form method="post" class="register"  action="<?php echo esc_url( $action_url ); ?>" >
1083
1084
						<?php do_action( 'sensei_register_form_start' ); ?>
1085
1086
						<p class="form-row form-row-wide">
1087
							<label for="sensei_reg_username"><?php _e( 'Username', 'woothemes-sensei' ); ?> <span class="required">*</span></label>
1088
							<input type="text" class="input-text" name="sensei_reg_username" id="sensei_reg_username" value="<?php if ( ! empty( $_POST['sensei_reg_username'] ) ) esc_attr_e( $_POST['sensei_reg_username'] ); ?>" />
1089
						</p>
1090
1091
						<p class="form-row form-row-wide">
1092
							<label for="sensei_reg_email"><?php _e( 'Email address', 'woothemes-sensei' ); ?> <span class="required">*</span></label>
1093
							<input type="email" class="input-text" name="sensei_reg_email" id="sensei_reg_email" value="<?php if ( ! empty( $_POST['sensei_reg_email'] ) ) esc_attr_e( $_POST['sensei_reg_email'] ); ?>" />
1094
						</p>
1095
1096
						<p class="form-row form-row-wide">
1097
							<label for="sensei_reg_password"><?php _e( 'Password', 'woothemes-sensei' ); ?> <span class="required">*</span></label>
1098
							<input type="password" class="input-text" name="sensei_reg_password" id="sensei_reg_password" value="<?php if ( ! empty( $_POST['sensei_reg_password'] ) ) esc_attr_e( $_POST['sensei_reg_password'] ); ?>" />
1099
						</p>
1100
1101
						<!-- Spam Trap -->
1102
						<div style="left:-999em; position:absolute;"><label for="trap"><?php _e( 'Anti-spam', 'woothemes-sensei' ); ?></label><input type="text" name="email_2" id="trap" tabindex="-1" /></div>
1103
1104
						<?php do_action( 'sensei_register_form_fields' ); ?>
1105
						<?php do_action( 'register_form' ); ?>
1106
1107
						<p class="form-row">
1108
							<input type="submit" class="button" name="register" value="<?php _e( 'Register', 'woothemes-sensei' ); ?>" />
1109
						</p>
1110
1111
						<?php do_action( 'sensei_register_form_end' ); ?>
1112
1113
					</form>
1114
				</div>
1115
				<?php
1116
			}
1117
			?>
1118
			</div>
1119
		</div>
1120
1121
		<?php
1122
	} // End sensei_login_form()
1123
1124
	public function sensei_lesson_meta( $post_id = 0 ) {
1125
		global $post;
1126
		if ( 0 < intval( $post_id ) ) {
1127
		$lesson_course_id = absint( get_post_meta( $post_id, '_lesson_course', true ) );
1128
		?><section class="entry">
1129
            <p class="sensei-course-meta">
1130 View Code Duplication
			    <?php if ( isset( Sensei()->settings->settings[ 'lesson_author' ] ) && ( Sensei()->settings->settings[ 'lesson_author' ] ) ) { ?>
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1131
			    <span class="course-author"><?php _e( 'by ', 'woothemes-sensei' ); ?><?php the_author_link(); ?></span>
1132
			    <?php } ?>
1133
                <?php if ( 0 < intval( $lesson_course_id ) ) { ?>
1134
                <span class="lesson-course"><?php echo '&nbsp;' . sprintf( __( 'Part of: %s', 'woothemes-sensei' ), '<a href="' . esc_url( get_permalink( $lesson_course_id ) ) . '" title="' . __( 'View course', 'woothemes-sensei' ) . '"><em>' . get_the_title( $lesson_course_id ) . '</em></a>' ); ?></span>
1135
                <?php } ?>
1136
            </p>
1137
            <p class="lesson-excerpt"><?php the_excerpt( ); ?></p>
1138
		</section><?php
1139
		} // End If Statement
1140
	} // sensei_lesson_meta()
1141
1142
	public function sensei_lesson_preview_title_text( $course_id ) {
1143
1144
		$preview_text = __( ' (Preview)', 'woothemes-sensei' );
1145
1146
		//if this is a paid course
1147
		if ( Sensei_WC::is_woocommerce_active() ) {
1148
    	    $wc_post_id = get_post_meta( $course_id, '_course_woocommerce_product', true );
1149
    	    if ( 0 < $wc_post_id ) {
1150
    	    	$preview_text = __( ' (Free Preview)', 'woothemes-sensei' );
1151
    	    } // End If Statement
1152
    	}
1153
    	return $preview_text;
1154
	}
1155
1156
	public function sensei_lesson_preview_title( $title = '', $id = 0 ) {
1157
		global $post, $current_user;
1158
1159
		// Limit to lessons and check if lesson ID matches filtered post ID
1160
		// @see https://github.com/woothemes/sensei/issues/574
1161
		if( isset( $post->ID ) && $id == $post->ID && 'lesson' == get_post_type( $post ) ) {
1162
1163
			// Limit to main query only
1164
			if( is_main_query() ) {
1165
1166
				// Get the course ID
1167
				$course_id = get_post_meta( $post->ID, '_lesson_course', true );
1168
1169
				// Check if the user is taking the course
1170
				if( is_singular( 'lesson' ) && Sensei_Utils::is_preview_lesson( $post->ID ) && ! Sensei_Utils::user_started_course( $course_id, $current_user->ID ) && $post->ID == $id ) {
1171
					$title .= ' ' . $this->sensei_lesson_preview_title_text( $course_id );
1172
				}
1173
			}
1174
		}
1175
		return $title;
1176
	} // sensei_lesson_preview_title
1177
1178
	public function sensei_course_start() {
1179
		global $post, $current_user;
1180
1181
		// Check if the user is taking the course
1182
		$is_user_taking_course = Sensei_Utils::user_started_course( $post->ID, $current_user->ID );
1183
		// Handle user starting the course
1184
		if ( isset( $_POST['course_start'] )
1185
		    && wp_verify_nonce( $_POST[ 'woothemes_sensei_start_course_noonce' ], 'woothemes_sensei_start_course_noonce' )
1186
		    && !$is_user_taking_course ) {
1187
1188
			// Start the course
1189
			$activity_logged = Sensei_Utils::user_start_course( $current_user->ID, $post->ID );
1190
			$this->data = new stdClass();
1191
			$this->data->is_user_taking_course = false;
1192
			if ( $activity_logged ) {
1193
				$this->data->is_user_taking_course = true;
1194
1195
				// Refresh page to avoid re-posting
1196
				?>
1197
1198
			    <script type="text/javascript"> window.location = '<?php echo get_permalink( $post->ID ); ?>'; </script>
1199
1200
			    <?php
1201
			} // End If Statement
1202
		} // End If Statement
1203
	} // End sensei_course_start()
1204
1205
    /**
1206
     * @deprecated since 1.9.0
1207
     */
1208
	public function sensei_course_meta() {
1209
        _deprecated_function( 'Sensei_Frontend::sensei_course_meta', '1.9.0' , 'Sensei_Course::the_course_meta()' );
1210
        Sensei()->course->the_course_meta( get_post() );
1211
	} // End sensei_course_meta()
1212
1213
    /**
1214
     * @deprecated since 1.9.0
1215
     */
1216
	public function sensei_course_meta_video() {
1217
        _deprecated_function( 'Sensei_Frontend::sensei_course_meta_video', '1.9.0' , 'Sensei_Course::the_course_video()' );
1218
        Sensei_Course::the_course_video();
1219
	} // End sensei_course_meta_video()
1220
1221
    /**
1222
     * This function shows the WooCommerce cart notice if the user has
1223
     * added the current course to cart. It does not show if the user is already taking
1224
     * the course.
1225
     *
1226
     * @since 1.0.2
1227
     * @return void;
0 ignored issues
show
The doc-type void; could not be parsed: Expected "|" or "end of type", but got ";" at position 4. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1228
     */
1229
    public function sensei_woocommerce_in_cart_message() {
1230
		global $post, $woocommerce;
1231
1232
		$wc_post_id = absint( get_post_meta( $post->ID, '_course_woocommerce_product', true ) );
1233
        $user_course_status_id = Sensei_Utils::user_started_course($post->ID , get_current_user_id() );
1234
		if ( 0 < intval( $wc_post_id ) && ! $user_course_status_id ) {
1235
1236
			if ( Sensei_WC::is_product_in_cart( $wc_post_id ) ) {
1237
				echo '<div class="sensei-message info">' . sprintf(  __('You have already added this Course to your cart. Please %1$s to access the course.', 'woothemes-sensei') . '</div>', '<a class="cart-complete" href="' . $woocommerce->cart->get_checkout_url() . '" title="' . __('complete the purchase', 'woothemes-sensei') . '">' . __('complete the purchase', 'woothemes-sensei') . '</a>' );
1238
			} // End If Statement
1239
1240
		} // End If Statement
1241
1242
	} // End sensei_woocommerce_in_cart_message()
1243
1244
	// Deprecated
1245
	public function sensei_lesson_comment_count( $count ) {
1246
		return $count;
1247
	} // End sensei_lesson_comment_count()
1248
1249
	/**
1250
	 * Only show excerpts for lessons and courses in search results
1251
	 * @param  string $content Original content
1252
	 * @return string          Modified content
1253
	 */
1254
	public function sensei_search_results_excerpt( $content ) {
1255
		global $post;
1256
1257
		if( is_search() && in_array( $post->post_type, array( 'course', 'lesson' ) ) ) {
1258
			$content = '<p class="course-excerpt">' . the_excerpt( ) . '</p>';
1259
		}
1260
1261
		return $content;
1262
	} // End sensei_search_results_excerpt()
1263
1264
	/**
1265
	 * Remove active course when an order is refunded or cancelled
1266
	 * @param  integer $order_id ID of order
1267
	 * @return void
1268
	 */
1269
	public function remove_active_course( $order_id ) {
1270
		$order = new WC_Order( $order_id );
1271
1272
		foreach ( $order->get_items() as $item ) {
1273
			if ( isset( $item['variation_id'] ) && ( 0 < $item['variation_id'] ) ) {
1274
				// If item has variation_id then its a variation of the product
1275
				$item_id = $item['variation_id'];
1276
			} else {
1277
				// Than its real product set it's id to item_id
1278
				$item_id = $item['product_id'];
1279
			} 
1280
1281
            if ( $item_id > 0 ) {
1282
1283
				$user_id = get_post_meta( $order_id, '_customer_user', true );
1284
1285
				if( $user_id ) {
1286
1287
					// Get all courses for product
1288
					$args = array(
1289
						'posts_per_page' => -1,
1290
						'post_type' => 'course',
1291
						'meta_query' => array(
1292
							array(
1293
								'key' => '_course_woocommerce_product',
1294
								'value' => $item_id
1295
							)
1296
						),
1297
						'orderby' => 'menu_order date',
1298
						'order' => 'ASC',
1299
						'fields' => 'ids',
1300
					);
1301
					$course_ids = get_posts( $args );
1302
1303
					if( $course_ids && count( $course_ids ) > 0 ) {
1304
						foreach( $course_ids as $course_id ) {
1305
1306
							// Remove all course user meta
1307
							Sensei_Utils::sensei_remove_user_from_course( $course_id, $user_id );
1308
1309
						} // End For Loop
1310
					} // End If Statement
1311
				} // End If Statement
1312
			} // End If Statement
1313
		} // End For Loop
1314
	} // End remove_active_course()
1315
1316
1317
	/**
1318
	 * Activate all purchased courses for user
1319
	 * @since  1.4.8
1320
	 * @param  integer $user_id User ID
1321
	 * @return void
1322
	 */
1323
	public function activate_purchased_courses( $user_id = 0 ) {
1324
1325
		if( $user_id ) {
1326
1327
			if( Sensei_WC::is_woocommerce_active() ) {
1328
1329
				// Get all user's orders
1330
				$order_args = array(
1331
					'post_type' => 'shop_order',
1332
					'post_status' =>  array( 'wc-processing', 'wc-completed' ),
1333
					'posts_per_page' => -1,
1334
					'meta_query' => array(
1335
						array(
1336
							'key' => '_customer_user',
1337
							'value' => $user_id
1338
						)
1339
					),
1340
				);
1341
1342
				$orders = get_posts( $order_args );
1343
1344
				$product_ids = array();
1345
				$order_ids = array();
1346
1347
				foreach( $orders as $post_id ) {
1348
1349
					// Only process each order once
1350
					$processed = get_post_meta( $post_id, 'sensei_products_processed', true );
1351
1352
					if( $processed && $processed == 'processed' ) {
1353
						continue;
1354
					}
1355
1356
					// Get course product IDs from order
1357
					$order = new WC_Order( $post_id );
1358
1359
					$items = $order->get_items();
1360
					foreach( $items as $item ) {
1361
                                            if (isset($item['variation_id']) && $item['variation_id'] > 0) {
1362
                                                $item_id = $item['variation_id'];
1363
                                                $product_type = 'variation';
1364
                                            } else {
1365
                                                $item_id = $item['product_id'];
1366
                                            }
1367
1368
                                            $product_ids[] = $item_id;
1369
                                            }
1370
1371
					$order_ids[] = $post_id;
1372
				}
1373
1374
				if( count( $product_ids ) > 0 ) {
1375
1376
					// Get all courses from user's orders
1377
					$course_args = array(
1378
						'post_type' => 'course',
1379
						'posts_per_page' => -1,
1380
						'meta_query' => array(
1381
							array(
1382
								'key' => '_course_woocommerce_product',
1383
								'value' => $product_ids,
1384
								'compare' => 'IN'
1385
							)
1386
						),
1387
						'orderby' => 'menu_order date',
1388
						'order' => 'ASC',
1389
						'fields' => 'ids',
1390
					);
1391
					$course_ids = get_posts( $course_args );
1392
1393
					foreach( $course_ids as $course_id ) {
1394
1395
						$user_course_status = Sensei_Utils::user_course_status( intval($course_id), $user_id );
1396
1397
						// Ignore course if already completed
1398
						if( Sensei_Utils::user_completed_course( $user_course_status ) ) {
1399
							continue;
1400
						}
1401
1402
						// Ignore course if already started
1403
						if( $user_course_status ) {
1404
							continue;
1405
						}
1406
1407
						// Mark course as started by user
1408
						Sensei_Utils::user_start_course( $user_id, $course_id );
1409
					}
1410
				}
1411
1412
				if( count( $order_ids ) > 0 ) {
1413
					foreach( $order_ids as $order_id ) {
1414
						// Mark order as processed
1415
						update_post_meta( $order_id, 'sensei_products_processed', 'processed' );
1416
					}
1417
				}
1418
			}
1419
		}
1420
	} // End activate_purchased_courses()
1421
1422
	/**
1423
	 * Activate single course if already purchases
1424
	 * @return void
1425
	 */
1426
	public function activate_purchased_single_course() {
1427
		global $post, $current_user;
1428
1429
		if( Sensei_WC::is_woocommerce_active() ) {
1430
1431
			if( ! is_user_logged_in() ) return;
1432
			if( ! isset( $post->ID ) ) return;
1433
1434
			$user_id = $current_user->ID;
1435
			$course_id = $post->ID;
1436
			$course_product_id = (int) get_post_meta( $course_id, '_course_woocommerce_product', true );
1437
			if( ! $course_product_id ) {
1438
				return;
1439
			}
1440
1441
			$user_course_status = Sensei_Utils::user_course_status( intval($course_id), $user_id );
1442
1443
			// Ignore course if already completed
1444
			if( Sensei_Utils::user_completed_course( $user_course_status ) ) {
1445
1446
				return;
1447
			}
1448
1449
			// Ignore course if already started
1450
			if( $user_course_status ) {
1451
				return;
1452
			}
1453
1454
			// Get all user's orders
1455
			$order_args = array(
1456
				'post_type' => 'shop_order',
1457
				'posts_per_page' => -1,
1458
				'post_status' => array( 'wc-processing', 'wc-completed' ),
1459
				'meta_query' => array(
1460
					array(
1461
						'key' => '_customer_user',
1462
						'value' => $user_id
1463
					)
1464
				),
1465
				'fields' => 'ids',
1466
			);
1467
			$orders = get_posts( $order_args );
1468
1469
			foreach( $orders as $order_post_id ) {
1470
1471
				// Get course product IDs from order
1472
				$order = new WC_Order( $order_post_id );
1473
1474
				$items = $order->get_items();
1475
				foreach( $items as $item ) {
1476
1477
                    $product = wc_get_product( $item['product_id'] );
1478
1479
                    // handle product bundles
1480
                    if( is_object( $product ) &&  $product->is_type('bundle') ){
1481
1482
                        $bundled_product = new WC_Product_Bundle( $product->id );
1483
                        $bundled_items = $bundled_product->get_bundled_items();
1484
1485
                        foreach( $bundled_items as $bundled_item ){
1486
1487
                            if( $bundled_item->product_id == $course_product_id ) {
1488
                                Sensei_Utils::user_start_course( $user_id, $course_id );
1489
                                return;
1490
                            }
1491
1492
                        }
1493
1494
                    } else {
1495
1496
                    // handle regular products
1497
                        if( $item['product_id'] == $course_product_id ) {
1498
                            Sensei_Utils::user_start_course( $user_id, $course_id );
1499
                            return;
1500
                        }
1501
1502
                    }
1503
				}
1504
			}
1505
1506
		}
1507
	} // End activate_purchased_single_course()
1508
1509
	/**
1510
	 * Hide Sensei activity comments from frontend (requires WordPress 4.0+)
1511
	 * @param  array  $args Default arguments
1512
	 * @return array        Modified arguments
1513
	 */
1514
	public function hide_sensei_activity( $args = array() ) {
1515
1516
		if( is_singular( 'lesson' ) || is_singular( 'course' ) ) {
1517
			$args['type'] = 'comment';
1518
		}
1519
1520
		return $args;
1521
	} // End hide_sensei_activity()
1522
1523
	/**
1524
	 * Redirect failed login attempts to the front end login page
1525
	 * in the case where the login fields are not left empty
1526
	 *
1527
	 * @return void redirect
1528
	 */
1529
	function sensei_login_fail_redirect( ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1530
1531
		//if not posted from the sensei login form let
1532
		// WordPress or any other party handle the failed request
1533
	    if( ! isset( $_REQUEST['form'] ) || 'sensei-login' != $_REQUEST['form']  ){
1534
1535
	    	return ;
1536
1537
	    }
1538
1539
    	// Get the reffering page, where did the post submission come from?
1540
    	$referrer = add_query_arg('login', false, $_SERVER['HTTP_REFERER']);
1541
1542
   		 // if there's a valid referrer, and it's not the default log-in screen
1543
	    if(!empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin')){
1544
	        // let's append some information (login=failed) to the URL for the theme to use
1545
	        wp_redirect( esc_url_raw( add_query_arg('login', 'failed',  $referrer) ) );
1546
	    	exit;
1547
    	}
1548
	}// End sensei_login_fail_redirect_to_front_end_login
1549
1550
	/**
1551
	 * Handle the login reques from all sensei intiated login forms.
1552
	 *
1553
	 * @return void redirect
1554
	 */
1555
	function sensei_handle_login_request( ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1556
1557
		// Check that it is a sensei login request and if it has a valid nonce
1558
	    if(  isset( $_REQUEST['form'] ) && 'sensei-login' == $_REQUEST['form'] ) {
1559
1560
	    	// Validate the login request nonce
1561
		    if( !wp_verify_nonce( $_REQUEST['_wpnonce'], 'sensei-login' ) ){
1562
		    	return;
1563
		    }
1564
1565
		    //get the page where the sensei log form is located
1566
		    $referrer = $_REQUEST['_wp_http_referer'];
1567
		    //$redirect = $_REQUEST['_sensei_redirect'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1568
1569
		    if ( ( isset( $_REQUEST['log'] ) && !empty( $_REQUEST['log'] ) )
1570
		    	 && ( isset( $_REQUEST['pwd'] ) && !empty( $_REQUEST['pwd'] ) ) ){
1571
1572
		    	// when the user has entered a password or username do the sensei login
1573
		    	$creds = array();
1574
1575
		    	// check if the requests login is an email address
1576
		    	if( is_email(  trim( $_REQUEST['log'] ) )  ){
1577
		    		// query wordpress for the users details
1578
		    		$user =	get_user_by( 'email', sanitize_email( $_REQUEST['log'] )  );
1579
1580
		    		// validate the user object
1581
		    		if( !$user ){
1582
1583
		    			// the email doesnt exist
1584
                        wp_redirect( esc_url_raw( add_query_arg('login', 'failed', $referrer) ) );
1585
		        		exit;
1586
1587
		    		}
1588
1589
		    		//assigne the username to the creds array for further processing
1590
		    		$creds['user_login'] =  $user->user_login ;
1591
1592
		    	}else{
1593
1594
		    		// process this as a default username login
1595
		    		$creds['user_login'] = sanitize_text_field( $_REQUEST['log'] ) ;
1596
1597
		    	}
1598
1599
				// get setup the rest of the creds array
1600
				$creds['user_password'] = sanitize_text_field( $_REQUEST['pwd'] );
1601
				$creds['remember'] = isset( $_REQUEST['rememberme'] ) ? true : false ;
1602
1603
				//attempt logging in with the given details
1604
			    $secure_cookie = is_ssl() ? true : false;
1605
			    $user = wp_signon( $creds, $secure_cookie );
1606
1607
				if ( is_wp_error($user) ){ // on login failure
1608
                    wp_redirect( esc_url_raw( add_query_arg('login', 'failed', $referrer) ) );
1609
                    exit;
1610
				}else{ // on login success
1611
1612
					/**
1613
					* change the redirect url programatically
1614
					*
1615
					* @since 1.6.1
1616
					*
1617
					* @param string $referrer the page where the current url wheresensei login form was posted from
1618
					*/
1619
1620
					$success_redirect_url = apply_filters('sesei_login_success_redirect_url', remove_query_arg( 'login', $referrer ) );
1621
1622
					wp_redirect( esc_url_raw( $success_redirect_url ) );
1623
		        	exit;
1624
1625
				}	// end is_wp_error($user)
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1626
1627
		    }else{ // if username or password is empty
1628
1629
                wp_redirect( esc_url_raw( add_query_arg('login', 'emptyfields', $referrer) ) );
1630
		        exit;
1631
1632
		    } // end if username $_REQUEST['log']  and password $_REQUEST['pwd'] is empty
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1633
1634
	    }elseif( ( isset( $_GET['login'] ) ) ) {
1635
	    	// else if this request is a redircect from a previously faile login request
1636
	    	$this->login_message_process();
1637
1638
			//exit the handle login request function
1639
			return;
1640
	    }
1641
1642
	    // if none of the above
1643
	    return;
1644
1645
	} // End  sensei_login_fail_redirect_to_front_end_login
1646
1647
	/**
1648
	 * handle sensei specific registration requests
1649
	 *
1650
	 * @return void redirect
1651
	 *
1652
	 */
1653
	public function sensei_process_registration(){
1654
		global 	 $current_user;
1655
		// check the for the sensei specific registration requests
1656
		if( !isset( $_POST['sensei_reg_username'] ) && ! isset( $_POST['sensei_reg_email'] ) && !isset( $_POST['sensei_reg_password'] )){
1657
			// exit if this is not a sensei registration request
1658
			return ;
1659
		}
1660
		// check for spam throw cheating huh
1661
		if( isset( $_POST['email_2'] ) &&  '' !== $_POST['email_2']   ){
1662
			$message = 'Error:  The spam field should be empty';
1663
			Sensei()->notices->add_notice( $message, 'alert');
1664
			return;
1665
		}
1666
1667
		// retreive form variables
1668
		$new_user_name		= sanitize_user( $_POST['sensei_reg_username'] );
1669
		$new_user_email		= $_POST['sensei_reg_email'];
1670
		$new_user_password	= $_POST['sensei_reg_password'];
1671
1672
		// Check the username
1673
		$username_error_notice = '';
1674
		if ( $new_user_name == '' ) {
1675
			$username_error_notice =  __( '<strong>ERROR</strong>: Please enter a username.' );
1676
		} elseif ( ! validate_username( $new_user_name ) ) {
1677
			$username_error_notice =  __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' );
1678
		} elseif ( username_exists( $new_user_name ) ) {
1679
			$username_error_notice =  __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' );
1680
		}
1681
1682
		// exit on username error
1683
		if( '' !== $username_error_notice ){
1684
			Sensei()->notices->add_notice( $username_error_notice , 'alert');
1685
			return;
1686
		}
1687
1688
		// Check the e-mail address
1689
		$email_error_notice = '';
1690
		if ( $new_user_email == '' ) {
1691
			$email_error_notice = __( '<strong>ERROR</strong>: Please type your e-mail address.' );
1692
		} elseif ( ! is_email( $new_user_email ) ) {
1693
			$email_error_notice = __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' );
1694
		} elseif ( email_exists( $new_user_email ) ) {
1695
			$email_error_notice = __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' );
1696
		}
1697
1698
		// exit on email address error
1699
		if( '' !== $email_error_notice ){
1700
			Sensei()->notices->add_notice( $email_error_notice , 'alert');
1701
			return;
1702
		}
1703
1704
		//check user password
1705
1706
		// exit on email address error
1707
		if( empty( $new_user_password ) ){
1708
			Sensei()->notices->add_notice(  __( '<strong>ERROR</strong>: The password field may not be empty, please enter a secure password.' )  , 'alert');
1709
			return;
1710
		}
1711
1712
		// register user
1713
		$user_id = wp_create_user( $new_user_name, $new_user_password, $new_user_email );
1714
		if ( ! $user_id || is_wp_error( $user_id ) ) {
1715
			Sensei()->notices->add_notice( sprintf( __( '<strong>ERROR</strong>: Couldn\'t register you&hellip; please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ), 'alert');
1716
		}
1717
1718
		// notify the user
1719
		wp_new_user_notification( $user_id, $new_user_password );
1720
1721
		// set global current user aka log the user in
1722
		$current_user = get_user_by( 'id', $user_id );
1723
		wp_set_auth_cookie( $user_id, true );
1724
1725
		// Redirect
1726
		global $wp;
1727
		if ( wp_get_referer() ) {
1728
			$redirect = esc_url( wp_get_referer() );
1729
		} else {
1730
			$redirect = esc_url( home_url( $wp->request ) );
1731
		}
1732
1733
		wp_redirect( apply_filters( 'sensei_registration_redirect', $redirect ) );
1734
		exit;
1735
1736
	} // end  sensei_process_registration)()
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1737
1738
	/**
1739
	 * login_message_process(). handle the login message displayed on faile login
1740
	 *
1741
	 * @return void redirect
1742
	 * @since 1.7.0
1743
	 */
1744
	public function login_message_process(){
1745
1746
            // setup the message variables
1747
			$message = '';
1748
1749
			//only output message if the url contains login=failed and login=emptyfields
1750
1751
			if( $_GET['login'] == 'failed' ){
1752
1753
				$message = __('Incorrect login details', 'woothemes-sensei' );
1754
1755
			}elseif( $_GET['login'] == 'emptyfields'  ){
1756
1757
				$message= __('Please enter your username and password', 'woothemes-sensei' );
1758
			}
1759
1760
			Sensei()->notices->add_notice( $message, 'alert');
1761
1762
	}// end login_message_process
1763
1764
1765
    /**
1766
     * sensei_show_admin_bar(). Use WooCommerce filter
1767
     * to show admin bar to Teachers as well.
1768
     *
1769
     * @return void redirect
1770
     *
1771
     */
1772
    public function sensei_show_admin_bar () {
1773
1774
        if (current_user_can('edit_courses')) {
1775
1776
            add_filter( 'woocommerce_disable_admin_bar', '__return_false', 10, 1);
1777
1778
        }
1779
1780
    }
1781
1782
} // End Class
1783
1784
/**
1785
 * Class WooThemes_Sensei_Frontend
1786
 * @ignore only for backward compatibility
1787
 * @since 1.9.0
1788
 */
1789
class WooThemes_Sensei_Frontend extends Sensei_Frontend{}
1790