PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.5.1
Forumax – AI Powered Advanced Community Forum Plugin v2.5.1
2.5.1 2.5.0 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 All 31 releases
← All changes | includes/login-form.php +82 -9 2.5.0 → 2.5.1 View file →
@@ -7,8 +7,10 @@
7 7 *
8 8 * @package Forumax
9 9 */
10 10
11 +defined( 'ABSPATH' ) || exit;
12 +
11 13 /**
12 14 * Render the tabbed login and registration form.
13 15 *
14 16 * @param array $atts Shortcode attributes.
@@ -38,8 +40,15 @@
38 40
39 41 $can_register = get_option( 'users_can_register' );
40 42 $wrapper_id = $uid;
41 43
44 + // Errors passed back by forumax_login_failed_redirect() / forumax_handle_registration().
45 + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only display flags.
46 + $login_failed = isset( $_GET['login'] ) && 'failed' === sanitize_key( wp_unslash( $_GET['login'] ) );
47 + $reg_errors = isset( $_GET['reg_error'] ) ? array_filter( array_map( 'sanitize_key', explode( ',', sanitize_text_field( wp_unslash( $_GET['reg_error'] ) ) ) ) ) : array();
48 + // phpcs:enable
49 + $active_tab = ( $can_register && ! empty( $reg_errors ) ) ? 'register' : 'login';
50 +
42 51 ob_start();
43 52 ?>
44 53 <div class="frmx-auth-tabs" id="<?php echo esc_attr( $wrapper_id ); ?>">
45 54
@@ -44,12 +53,12 @@
44 53 <div class="frmx-auth-tabs" id="<?php echo esc_attr( $wrapper_id ); ?>">
45 54
46 55 <?php if ( $can_register ) : ?>
47 56 <div class="frmx-auth-tabs-header">
48 - <button type="button" class="frmx-auth-tab frmx-auth-tab-active" data-frmx-tab="login">
57 + <button type="button" class="frmx-auth-tab<?php echo 'login' === $active_tab ? ' frmx-auth-tab-active' : ''; ?>" data-frmx-tab="login">
49 58 <?php esc_html_e( 'Sign In', 'forumax' ); ?>
50 59 </button>
51 - <button type="button" class="frmx-auth-tab" data-frmx-tab="register">
60 + <button type="button" class="frmx-auth-tab<?php echo 'register' === $active_tab ? ' frmx-auth-tab-active' : ''; ?>" data-frmx-tab="register">
52 61 <?php esc_html_e( 'Create Account', 'forumax' ); ?>
53 62 </button>
54 63 </div>
55 64 <?php endif; ?>
@@ -54,9 +63,14 @@
54 63 </div>
55 64 <?php endif; ?>
56 65
57 66 <!-- Login Tab -->
58 - <div class="frmx-auth-panel frmx-auth-panel-active" data-frmx-panel="login">
67 + <div class="frmx-auth-panel<?php echo 'login' === $active_tab ? ' frmx-auth-panel-active' : ''; ?>" data-frmx-panel="login">
68 + <?php if ( $login_failed ) : ?>
69 + <div class="frmx-auth-error bbp-template-notice error" role="alert">
70 + <p><?php esc_html_e( 'Invalid username, email address or password. Please try again.', 'forumax' ); ?></p>
71 + </div>
72 + <?php endif; ?>
59 73 <?php
60 74 $form_html = wp_login_form( array(
61 75 'redirect' => $redirect_url,
62 76 'label_username' => esc_html__( 'Username or Email', 'forumax' ),
@@ -94,8 +108,11 @@
94 108 '$1 placeholder="' . $password_placeholder . '"$2',
95 109 $form_html
96 110 );
97 111
112 + // Marks submissions from this form so only they are redirected back on failure.
113 + $form_html = preg_replace( '/<\/form>/i', '<input type="hidden" name="forumax_login" value="1" /></form>', $form_html, 1 );
114 +
98 115 echo $form_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
99 116 ?>
100 117
101 118 <?php
@@ -107,9 +124,16 @@
107 124 </div>
108 125
109 126 <?php if ( $can_register ) : ?>
110 127 <!-- Registration Tab -->
111 - <div class="frmx-auth-panel" data-frmx-panel="register">
128 + <div class="frmx-auth-panel<?php echo 'register' === $active_tab ? ' frmx-auth-panel-active' : ''; ?>" data-frmx-panel="register">
129 + <?php if ( ! empty( $reg_errors ) ) : ?>
130 + <div class="frmx-auth-error bbp-template-notice error" role="alert">
131 + <?php foreach ( $reg_errors as $reg_error ) : ?>
132 + <p><?php echo esc_html( forumax_registration_error_message( $reg_error ) ); ?></p>
133 + <?php endforeach; ?>
134 + </div>
135 + <?php endif; ?>
112 136 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="frmx-auth-register-form">
113 137 <input type="hidden" name="action" value="forumax_register" />
114 138 <input type="hidden" name="redirect_to" value="<?php echo esc_url( $redirect_url ); ?>" />
115 139
@@ -225,11 +249,18 @@
225 249 *
226 250 * @return void
227 251 */
228 252 function forumax_login_failed_redirect( $username ) {
253 + // Only handle the Forumax form; other login forms (WooCommerce, REST,
254 + // XML-RPC, wp-login.php) keep their own error handling.
255 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- core login has no nonce; this only picks the redirect target.
256 + if ( empty( $_POST['forumax_login'] ) ) {
257 + return;
258 + }
259 +
229 260 $referrer = wp_get_referer();
230 261 if ( ! empty( $referrer ) && ! str_contains( $referrer, 'wp-login.php' ) ) {
231 - wp_redirect( add_query_arg( 'login', 'failed', $referrer ) );
262 + wp_safe_redirect( add_query_arg( 'login', 'failed', remove_query_arg( array( 'login', 'reg_error' ), $referrer ) ) );
232 263 exit;
233 264 }
234 265 }
235 266
@@ -235,8 +266,29 @@
235 266
236 267 add_action( 'wp_login_failed', 'forumax_login_failed_redirect' );
237 268
238 269 /**
270 + * Human readable message for a registration error code.
271 + *
272 + * @param string $code Error code.
273 + * @return string
274 + */
275 +function forumax_registration_error_message( $code ) {
276 + $messages = array(
277 + 'empty_username' => __( 'Please enter a username.', 'forumax' ),
278 + 'invalid_username' => __( 'This username is invalid. Please use letters, numbers and - _ . @ only.', 'forumax' ),
279 + 'existing_user_login' => __( 'This username is already registered. Please choose another one.', 'forumax' ),
280 + 'invalid_email' => __( 'Please enter a valid email address.', 'forumax' ),
281 + 'email_exists' => __( 'This email address is already registered.', 'forumax' ),
282 + 'existing_user_email' => __( 'This email address is already registered.', 'forumax' ),
283 + 'empty_password' => __( 'Please enter a password.', 'forumax' ),
284 + 'password_mismatch' => __( 'The passwords do not match.', 'forumax' ),
285 + );
286 +
287 + return $messages[ $code ] ?? __( 'Registration failed. Please check the form and try again.', 'forumax' );
288 +}
289 +
290 +/**
239 291 * Handle the custom registration form submission.
240 292 *
241 293 * Creates a new user with the provided username, email, and password,
242 294 * auto-logs them in, and redirects to the referring page.
@@ -283,10 +335,34 @@
283 335 if ( $user_pass !== $user_pass_confirm ) {
284 336 $errors[] = 'password_mismatch';
285 337 }
286 338
339 + if ( empty( $errors ) ) {
340 + if ( ! validate_username( $user_login ) ) {
341 + $errors[] = 'invalid_username';
342 + } elseif ( username_exists( $user_login ) ) {
343 + $errors[] = 'existing_user_login';
344 + }
345 +
346 + if ( email_exists( $user_email ) ) {
347 + $errors[] = 'email_exists';
348 + }
349 + }
350 +
351 + // Let CAPTCHA / anti-spam plugins that print into `register_form`
352 + // validate the submission too, as core registration does.
353 + if ( empty( $errors ) ) {
354 + $wp_errors = new WP_Error();
355 + do_action( 'register_post', $user_login, $user_email, $wp_errors );
356 + $wp_errors = apply_filters( 'registration_errors', $wp_errors, $user_login, $user_email );
357 +
358 + if ( is_wp_error( $wp_errors ) && $wp_errors->has_errors() ) {
359 + $errors = array_merge( $errors, $wp_errors->get_error_codes() );
360 + }
361 + }
362 +
287 363 if ( ! empty( $errors ) ) {
288 - wp_safe_redirect( add_query_arg( 'reg_error', implode( ',', $errors ), $referrer ) );
364 + wp_safe_redirect( add_query_arg( 'reg_error', implode( ',', array_unique( $errors ) ), remove_query_arg( array( 'login', 'reg_error' ), $referrer ) ) );
289 365 exit;
290 366 }
291 367
292 368 // Let external plugins validate registration (e.g. Envato license check).
@@ -303,11 +379,8 @@
303 379 $error_code = $user_id->get_error_code();
304 380 wp_safe_redirect( add_query_arg( 'reg_error', $error_code, $referrer ) );
305 381 exit;
306 382 }
307 -
308 - // Fire standard WordPress registration action.
309 - do_action( 'user_register', $user_id );
310 383
311 384 // Auto-login the new user.
312 385 wp_set_current_user( $user_id );
313 386 wp_set_auth_cookie( $user_id, true );