diff --git a/wp-content/plugins/wporg-learn/inc/sensei.php b/wp-content/plugins/wporg-learn/inc/sensei.php index 76771a90a..69ef3dcc9 100644 --- a/wp-content/plugins/wporg-learn/inc/sensei.php +++ b/wp-content/plugins/wporg-learn/inc/sensei.php @@ -17,6 +17,16 @@ add_action( 'sensei_before_main_content', __NAMESPACE__ . '\theme_wrapper_start' ); add_action( 'sensei_after_main_content', __NAMESPACE__ . '\theme_wrapper_end' ); add_action( 'init', __NAMESPACE__ . '\wporg_correct_sensei_slugs', 9 ); +add_action( 'template_redirect', __NAMESPACE__ . '\restrict_my_courses_page_access' ); +add_filter( 'sensei_login_url', __NAMESPACE__ . '\sensei_login_url', 20, 2 ); +add_filter( 'sensei_registration_url', __NAMESPACE__ . '\sensei_registration_url', 20, 2 ); +// Disable the Sensei user register page, use the WordPress registration page, see 'sensei_registration_url' filter. +add_filter( 'sensei_use_wp_register_link', '__return_true' ); +// Repalce the Sensei login/register form contents. +add_action( 'sensei_login_form_before', __NAMESPACE__ . '\sensei_login_form_before' ); +add_action( 'sensei_register_form_start', __NAMESPACE__ . '\sensei_register_form_start' ); +// Disable Sensei user login & creation. +add_filter( 'init', __NAMESPACE__ . '\block_login_register_actions', 1 ); /** * Slugs in Sensei are translatable, which won't work for our site and the language switcher. @@ -258,3 +268,114 @@ function get_my_courses_page_url() { return get_permalink( $page_id ); } + +/** + * Redirect requests for the "My Courses" page to the login page and back, if logged out. + */ +function restrict_my_courses_page_access() { + if ( ! is_user_logged_in() && is_page( Sensei()->settings->get_my_courses_page_id() ) ) { + $redirect_to = wp_unslash( $_GET['redirect_to'] ?? '' ) ?: sensei_get_current_page_url(); + + wp_redirect( wp_login_url( $redirect_to ) ); + exit; + } +} + +/** + * Don't use the Sensei My Courses page as the login page. + */ +function sensei_login_url( $url, $redirect = '' ) { + return wp_login_url( $redirect ); +} + +/** + * Don't use the Sensei My Courses page as the registration page, but equally don't use the register page. + * + * Sensei uses the registration page for all logged out users, and the login page for all logged in users. + * This is a poor user experience, as it means that the 'Take Course' links will direct to the registration page, rather than the login page. + * For that reason, we're filtering the registration location to the login page. + */ +function sensei_registration_url( $url, $redirect = '' ) { + return wp_login_url( $redirect ); +} + +/** + * Replace the Sensei My Courses login form with a call to action to WordPress.org. + */ +function sensei_login_form_before() { + // Start an output buffer, we'll remove the form content in the post-login-form filter. + ob_start(); + + add_action( 'sensei_login_form_after', function() { + $html = ob_get_clean(); + + /* + * Use the provided redirect_to, or the current page failing that. + * This differs from Sensei which doesn't respect the redirect_to parameter. + * Validation will occur by the login redirection code. + */ + $redirect_to = wp_unslash( $_GET['redirect_to'] ?? '' ) ?: sensei_get_current_page_url(); + + // Replace the form with a call to action to WordPress.org. + $html = preg_replace( + '!!is', + sprintf( + '
%s
', + esc_url( wp_login_url( $redirect_to ) ), + __( 'Log In', 'wporg-learn' ), + ), + $html + ); + + echo wp_kses_post( $html ); + } ); +} + +/** + * Replace the Sensei registration form with a call to action to WordPress.org. + */ +function sensei_register_form_start() { + // Start an output buffer, we'll replace the form content in the post-login-form filter. + ob_start(); + + add_action( 'sensei_register_form_end', function() { + // We don't need any of the output buffer contents, since we're just in the
tag. + ob_end_clean(); + + // Output a registration button. + echo sprintf( + '', + esc_url( wp_registration_url() ), + esc_html__( 'Register', 'wporg-learn' ), + ); + + /* + * Add some custom styles for the My Courses page to remove the registation form border. + * + * This styles it to match the login section beside it. + */ + echo ''; + } ); +} + +/** + * Forcibly disable Sensei user login & creation. + * + * Even if registrations are disabled, sensei still processes the form, for security we don't want this. + */ +function block_login_register_actions() { + if ( function_exists( 'Sensei' ) ) { + remove_action( 'init', array( Sensei()->frontend ?? false, 'sensei_process_registration' ), 2 ); + remove_filter( 'init', array( Sensei()->frontend ?? false, 'sensei_handle_login_request' ), 10 ); // Yes, Sensei calls it a filter. + } + + // We're also going to forcefully disable the POST'd fields, incase the above action names change. + + // By unsetting this, it forces Sensei not to be able to create a user. + unset( $_REQUEST['sensei_reg_password'], $_POST['sensei_reg_password'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + + // By unsetting these, sensei can't process a login. + if ( 'sensei-login' == ( $_REQUEST['form'] ?? '' ) ) { + unset( $_REQUEST['_wpnonce'], $_REQUEST['log'], $_REQUEST['pwd'], $_POST['log'], $_POST['pwd'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + } +}