From 01c7bdf72ec8b9f9959b3d13527c3c35af5b49fe Mon Sep 17 00:00:00 2001 From: Mykyta Synelnikov Date: Wed, 4 Jun 2025 17:39:27 +0300 Subject: [PATCH 1/3] Add login shortcode and enhance button class filters Introduce the `[um_login]` shortcode for rendering the login form, with backend logic for customization and error handling. Enhance flexibility by adding filters to dynamically modify primary button classes for login, register, and password-reset forms. --- includes/core/class-shortcodes.php | 187 ++++++++++++++++++++++++++ includes/core/um-actions-login.php | 6 +- includes/core/um-actions-register.php | 6 +- templates/password-reset.php | 31 +++-- 4 files changed, 213 insertions(+), 17 deletions(-) diff --git a/includes/core/class-shortcodes.php b/includes/core/class-shortcodes.php index d34a789f..d9c36e84 100644 --- a/includes/core/class-shortcodes.php +++ b/includes/core/class-shortcodes.php @@ -162,6 +162,193 @@ if ( ! class_exists( 'um\core\Shortcodes' ) ) { $this->emoji[':innocent:'] = $base_uri . '72x72/1f607.png'; $this->emoji[':smirk:'] = $base_uri . '72x72/1f60f.png'; $this->emoji[':expressionless:'] = $base_uri . '72x72/1f611.png'; + + // test shortcode + add_shortcode( 'um_login', array( &$this, 'login_form' ) ); + } + + public function login_form( $args = array() ) { + if ( ! UM()->is_new_ui() ) { + return ''; + } + + global $error; + + if ( is_user_logged_in() ) { + return ''; + } + + /** There is possible to use 'shortcode_atts_ultimatemember_login' filter for getting customized $atts. This filter is documented in wp-includes/shortcodes.php "shortcode_atts_{$shortcode}" */ + $args = shortcode_atts( + array( + 'login_button' => __( 'Log In', 'ultimate-member' ), + 'show_remember' => true, + 'show_forgot' => true, + 'login_redirect' => '', + 'login_redirect_url' => '', + 'form_id' => '', // backward compatibility argument + ), + $args, + 'ultimatemember_login' + ); + + $styling = UM()->options()->get( 'styling' ); + switch ( $styling ) { + case 'none': + break; + case 'layout_only': + wp_enqueue_script('um-login' ); + wp_enqueue_style( 'um-login-base' ); + break; + default: + wp_enqueue_script('um-login' ); + wp_enqueue_style( 'um-login-full' ); + break; + } + + $login_args = array( + 'form_id' => 'um-loginform', + 'um_login_form' => true, + 'um_login_form_id' => absint( $args['form_id'] ), + 'um_login_redirect' => '', // if empty then get default from role + 'um_show_forgot' => (bool) $args['show_forgot'], + 'echo' => true, + 'remember' => (bool) $args['show_remember'], + 'label_username' => __( 'Username or Email Address', 'ultimate-member' ), + 'label_password' => __( 'Password', 'ultimate-member' ), + 'label_remember' => __( 'Remember Me', 'ultimate-member' ), + 'label_log_in' => ! empty( $args['login_button'] ) ? $args['login_button'] : __( 'Log In', 'ultimate-member' ), + ); + + if ( ! isset( $_GET['redirect_to'] ) || empty( $_GET['redirect_to'] ) ) { + $redirect = um_get_predefined_page_url( 'user' ); + $login_args['redirect'] = $redirect; + } + + /** + * Filters Ultimate Member Login Form arguments for init it through `wp_login_form()`. + * + * @since 3.0 + * @hook um_login_form_args + * + * @param {array} $login_args Attributes for `wp_login_form()` function init. + * @param {array} $args Login form shortcode attributes. + * + * @return {array} Attributes for `wp_login_form()` function. + */ + $login_args = apply_filters( 'um_login_form_args', $login_args, $args ); + + $wp_error = new \WP_Error(); + + $error_codes = array( + 'empty' => sprintf( __( '%s and %s are required.', 'ultimate-member' ), $login_args['label_username'], $login_args['label_password'] ), + 'failed' => __( 'Invalid username, email address or incorrect password.', 'ultimate-member' ), + 'um_blocked_email' => __( 'This email address has been blocked.', 'ultimate-member' ), + 'um_blocked_domain' => __( 'This email address domain has been blocked.', 'ultimate-member' ), + 'um_account_inactive' => __( 'Your account has been disabled.', 'ultimate-member' ), + 'um_account_awaiting_admin_review' => __( 'Your account has not been approved yet.', 'ultimate-member' ), + 'um_account_awaiting_email_confirmation' => __( 'Your account is awaiting e-mail verification.', 'ultimate-member' ), + 'um_account_rejected' => __( 'Your membership request has been rejected.', 'ultimate-member' ), + ); + /** + * Filters Ultimate Member Login Form errors and their codes. + * + * @since 3.0 + * @hook um_login_form_error_codes + * + * @param {array} $error_codes Error codes in format $error_code => $error_message. + * @param {array} $args Login form attributes. + * + * @return {array} Error codes. + */ + $error_codes = apply_filters( 'um_login_form_error_codes', $error_codes, $args, $login_args ); + + if ( ! empty( $args['show_forgot'] ) ) { + // Change lostpassword URL only when using Ultimate Member Login Form + add_filter( 'lostpassword_url', array( &$this, 'change_lostpassword_url' ), 10, 1 ); + } + + ob_start(); + ?> + +
+ + + add( 'error', $error ); + unset( $error ); + } + + if ( ! empty( $_GET['login'] ) ) { + $error_code = sanitize_key( $_GET['login'] ); + + if ( array_key_exists( $error_code, $error_codes ) ) { + $wp_error->add( $error_code, $error_codes[ $error_code ] ); + } + } + + if ( $wp_error->has_errors() ) { + $errors = ''; + $messages = ''; + + foreach ( $wp_error->get_error_codes() as $code ) { + $severity = $wp_error->get_error_data( $code ); + foreach ( $wp_error->get_error_messages( $code ) as $error_message ) { + if ( 'message' === $severity ) { + $messages .= ' ' . $error_message . "
\n"; + } else { + $errors .= ' ' . $error_message . "
\n"; + } + } + } + + if ( ! empty( $errors ) ) { + /** This filter is documented in wp-login.php */ + echo '

' . apply_filters( 'login_errors', $errors ) . "

\n"; + } + + if ( ! empty( $messages ) ) { + /** This filter is documented in wp-login.php */ + echo '

' . apply_filters( 'login_messages', $messages ) . "

\n"; + } + } + ?> + + + + +
+ + options()->get( 'login_primary_btn_word' ); } + $primary_btn_classes = apply_filters( 'um_login_form_primary_btn_classes', array( 'um-button' ), $args ); + /** * UM hook * @@ -426,7 +428,7 @@ function um_add_submit_button_to_login( $args ) { if ( ! empty( $args['secondary_btn'] ) ) { ?>
- +
@@ -437,7 +439,7 @@ function um_add_submit_button_to_login( $args ) {
- +
diff --git a/includes/core/um-actions-register.php b/includes/core/um-actions-register.php index 007101e8..f9d44f0f 100644 --- a/includes/core/um-actions-register.php +++ b/includes/core/um-actions-register.php @@ -597,6 +597,8 @@ function um_add_submit_button_to_register( $args ) { $primary_btn_word = UM()->options()->get( 'register_primary_btn_word' ); } + $primary_btn_classes = apply_filters( 'um_register_form_primary_btn_classes', array( 'um-button' ), $args ); + $secondary_btn_word = $args['secondary_btn_word']; /** * UM hook @@ -656,7 +658,7 @@ function um_add_submit_button_to_register( $args ) {
- +
@@ -667,7 +669,7 @@ function um_add_submit_button_to_register( $args ) {
- +
diff --git a/templates/password-reset.php b/templates/password-reset.php index 6dcf9cb8..51adbeee 100644 --- a/templates/password-reset.php +++ b/templates/password-reset.php @@ -6,17 +6,18 @@ * * Call: function ultimatemember_password() * - * @version 2.7.0 + * @version 2.10.5 * * @var string $mode * @var int $form_id * @var array $args + * + * phpcs:disable WordPress.Security.NonceVerification */ if ( ! defined( 'ABSPATH' ) ) { exit; } ?> -
@@ -62,19 +63,24 @@ if ( ! defined( 'ABSPATH' ) ) { */ do_action( 'um_reset_password_page_hidden_fields', $args ); - if ( ! empty( $_GET['updated'] ) ) { ?> + if ( ! empty( $_GET['updated'] ) ) { + ?>
- + } + ?>
- +
@@ -82,7 +88,8 @@ if ( ! defined( 'ABSPATH' ) ) {
- builtin()->get_specific_fields( 'username_b' ); @@ -111,18 +118,16 @@ if ( ! defined( 'ABSPATH' ) ) { * } * ?> */ - do_action( 'um_after_password_reset_fields', $args ); ?> + do_action( 'um_after_password_reset_fields', $args ); + $primary_btn_classes = apply_filters( 'um_password_reset_form_primary_btn_classes', array( 'um-button' ), $args ); + ?>
-
- +
-
-
- Date: Thu, 5 Jun 2025 01:41:50 +0300 Subject: [PATCH 2/3] Remove unused UM login form shortcode logic. The login form shortcode functionality was outdated and no longer in use. By removing it, the codebase is simplified and unnecessary complexity is eliminated. This improves maintainability and aligns with the current state of the plugin. --- includes/core/class-shortcodes.php | 187 ----------------------------- 1 file changed, 187 deletions(-) diff --git a/includes/core/class-shortcodes.php b/includes/core/class-shortcodes.php index d9c36e84..d34a789f 100644 --- a/includes/core/class-shortcodes.php +++ b/includes/core/class-shortcodes.php @@ -162,193 +162,6 @@ if ( ! class_exists( 'um\core\Shortcodes' ) ) { $this->emoji[':innocent:'] = $base_uri . '72x72/1f607.png'; $this->emoji[':smirk:'] = $base_uri . '72x72/1f60f.png'; $this->emoji[':expressionless:'] = $base_uri . '72x72/1f611.png'; - - // test shortcode - add_shortcode( 'um_login', array( &$this, 'login_form' ) ); - } - - public function login_form( $args = array() ) { - if ( ! UM()->is_new_ui() ) { - return ''; - } - - global $error; - - if ( is_user_logged_in() ) { - return ''; - } - - /** There is possible to use 'shortcode_atts_ultimatemember_login' filter for getting customized $atts. This filter is documented in wp-includes/shortcodes.php "shortcode_atts_{$shortcode}" */ - $args = shortcode_atts( - array( - 'login_button' => __( 'Log In', 'ultimate-member' ), - 'show_remember' => true, - 'show_forgot' => true, - 'login_redirect' => '', - 'login_redirect_url' => '', - 'form_id' => '', // backward compatibility argument - ), - $args, - 'ultimatemember_login' - ); - - $styling = UM()->options()->get( 'styling' ); - switch ( $styling ) { - case 'none': - break; - case 'layout_only': - wp_enqueue_script('um-login' ); - wp_enqueue_style( 'um-login-base' ); - break; - default: - wp_enqueue_script('um-login' ); - wp_enqueue_style( 'um-login-full' ); - break; - } - - $login_args = array( - 'form_id' => 'um-loginform', - 'um_login_form' => true, - 'um_login_form_id' => absint( $args['form_id'] ), - 'um_login_redirect' => '', // if empty then get default from role - 'um_show_forgot' => (bool) $args['show_forgot'], - 'echo' => true, - 'remember' => (bool) $args['show_remember'], - 'label_username' => __( 'Username or Email Address', 'ultimate-member' ), - 'label_password' => __( 'Password', 'ultimate-member' ), - 'label_remember' => __( 'Remember Me', 'ultimate-member' ), - 'label_log_in' => ! empty( $args['login_button'] ) ? $args['login_button'] : __( 'Log In', 'ultimate-member' ), - ); - - if ( ! isset( $_GET['redirect_to'] ) || empty( $_GET['redirect_to'] ) ) { - $redirect = um_get_predefined_page_url( 'user' ); - $login_args['redirect'] = $redirect; - } - - /** - * Filters Ultimate Member Login Form arguments for init it through `wp_login_form()`. - * - * @since 3.0 - * @hook um_login_form_args - * - * @param {array} $login_args Attributes for `wp_login_form()` function init. - * @param {array} $args Login form shortcode attributes. - * - * @return {array} Attributes for `wp_login_form()` function. - */ - $login_args = apply_filters( 'um_login_form_args', $login_args, $args ); - - $wp_error = new \WP_Error(); - - $error_codes = array( - 'empty' => sprintf( __( '%s and %s are required.', 'ultimate-member' ), $login_args['label_username'], $login_args['label_password'] ), - 'failed' => __( 'Invalid username, email address or incorrect password.', 'ultimate-member' ), - 'um_blocked_email' => __( 'This email address has been blocked.', 'ultimate-member' ), - 'um_blocked_domain' => __( 'This email address domain has been blocked.', 'ultimate-member' ), - 'um_account_inactive' => __( 'Your account has been disabled.', 'ultimate-member' ), - 'um_account_awaiting_admin_review' => __( 'Your account has not been approved yet.', 'ultimate-member' ), - 'um_account_awaiting_email_confirmation' => __( 'Your account is awaiting e-mail verification.', 'ultimate-member' ), - 'um_account_rejected' => __( 'Your membership request has been rejected.', 'ultimate-member' ), - ); - /** - * Filters Ultimate Member Login Form errors and their codes. - * - * @since 3.0 - * @hook um_login_form_error_codes - * - * @param {array} $error_codes Error codes in format $error_code => $error_message. - * @param {array} $args Login form attributes. - * - * @return {array} Error codes. - */ - $error_codes = apply_filters( 'um_login_form_error_codes', $error_codes, $args, $login_args ); - - if ( ! empty( $args['show_forgot'] ) ) { - // Change lostpassword URL only when using Ultimate Member Login Form - add_filter( 'lostpassword_url', array( &$this, 'change_lostpassword_url' ), 10, 1 ); - } - - ob_start(); - ?> - -
- - Date: Thu, 5 Jun 2025 16:06:21 +0300 Subject: [PATCH 3/3] Add filters for primary button classes in UM forms Introduced new filters to customize CSS classes for primary buttons in login, registration, and password reset forms. This allows developers to extend button styling by applying custom classes via WordPress hooks. Changes enhance flexibility and improve theme compatibility. --- includes/core/um-actions-login.php | 21 ++++++++++++++++++++- includes/core/um-actions-register.php | 20 ++++++++++++++++++++ templates/password-reset.php | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/includes/core/um-actions-login.php b/includes/core/um-actions-login.php index 20e85f50..dd1ea922 100644 --- a/includes/core/um-actions-login.php +++ b/includes/core/um-actions-login.php @@ -362,7 +362,26 @@ function um_add_submit_button_to_login( $args ) { if ( ! isset( $primary_btn_word ) || $primary_btn_word == '' ){ $primary_btn_word = UM()->options()->get( 'login_primary_btn_word' ); } - + /** + * Filters the classes applied to the primary button on the login form. + * + * @hook um_login_form_primary_btn_classes + * @since 2.10.5 + * + * @param {array} $classes An array of CSS classes applied to the primary button. + * @param {array} $args An array of arguments or configurations used in the login form. + * + * @return {array} Button CSS classes. + * + * @example Extend the classes applied to the primary button on the login form. + * function my_custom_classes( $classes, $args ) { + * // Add a new class to the button + * $classes[] = 'new-button-class'; + * + * return $classes; + * } + * add_filter( 'um_login_form_primary_btn_classes', 'my_custom_classes', 10, 2 ); + */ $primary_btn_classes = apply_filters( 'um_login_form_primary_btn_classes', array( 'um-button' ), $args ); /** diff --git a/includes/core/um-actions-register.php b/includes/core/um-actions-register.php index f9d44f0f..ca5e7540 100644 --- a/includes/core/um-actions-register.php +++ b/includes/core/um-actions-register.php @@ -597,6 +597,26 @@ function um_add_submit_button_to_register( $args ) { $primary_btn_word = UM()->options()->get( 'register_primary_btn_word' ); } + /** + * Filters the classes applied to the primary button on the registration form. + * + * @hook um_register_form_primary_btn_classes + * @since 2.10.5 + * + * @param {array} $classes An array of CSS classes applied to the primary button. + * @param {array} $args An array of arguments or configurations used in the registration form. + * + * @return {array} Button CSS classes. + * + * @example Extend the classes applied to the primary button on the registration form. + * function my_custom_classes( $classes, $args ) { + * // Add a new class to the button + * $classes[] = 'new-button-class'; + * + * return $classes; + * } + * add_filter( 'um_register_form_primary_btn_classes', 'my_custom_classes', 10, 2 ); + */ $primary_btn_classes = apply_filters( 'um_register_form_primary_btn_classes', array( 'um-button' ), $args ); $secondary_btn_word = $args['secondary_btn_word']; diff --git a/templates/password-reset.php b/templates/password-reset.php index 51adbeee..0984a2f7 100644 --- a/templates/password-reset.php +++ b/templates/password-reset.php @@ -120,6 +120,26 @@ if ( ! defined( 'ABSPATH' ) ) { */ do_action( 'um_after_password_reset_fields', $args ); + /** + * Filters the classes applied to the primary button on the password reset form. + * + * @hook um_password_reset_form_primary_btn_classes + * @since 2.10.5 + * + * @param {array} $classes An array of CSS classes applied to the primary button. + * @param {array} $args An array of arguments or configurations used in the password reset form. + * + * @return {array} Button CSS classes. + * + * @example Extend the classes applied to the primary button on the password reset form. + * function my_custom_classes( $classes, $args ) { + * // Add a new class to the button + * $classes[] = 'new-button-class'; + * + * return $classes; + * } + * add_filter( 'um_password_reset_form_primary_btn_classes', 'my_custom_classes', 10, 2 ); + */ $primary_btn_classes = apply_filters( 'um_password_reset_form_primary_btn_classes', array( 'um-button' ), $args ); ?>