From bcfdbb954ded2e6256318f3932ddf1fb7369d90b Mon Sep 17 00:00:00 2001 From: Mykyta Synelnikov Date: Mon, 19 May 2025 14:26:39 +0300 Subject: [PATCH] Refactor email placeholders and deprecate obsolete methods Streamline placeholder handling for emails by introducing universal patterns and replacements, and update email dispatch functions for efficiency. Deprecated various redundant user and password-related methods, consolidating logic into common utility classes for better maintainability. --- includes/common/actions/class-emails.php | 25 ----- includes/common/class-users.php | 111 +++++++++++++++++--- includes/core/class-mail.php | 19 ---- includes/core/class-password.php | 23 ++--- includes/core/class-permalinks.php | 55 +++++----- includes/core/class-profile.php | 19 ++-- includes/core/class-user.php | 126 +++++++++++++---------- includes/core/um-actions-login.php | 8 +- includes/core/um-actions-register.php | 22 +++- includes/um-short-functions.php | 32 +----- 10 files changed, 233 insertions(+), 207 deletions(-) diff --git a/includes/common/actions/class-emails.php b/includes/common/actions/class-emails.php index f4c485be..fb1613dc 100644 --- a/includes/common/actions/class-emails.php +++ b/includes/common/actions/class-emails.php @@ -19,7 +19,6 @@ if ( ! class_exists( 'um\common\actions\Emails' ) ) { public function __construct() { add_filter( 'um_action_scheduler_is_hook_enabled', array( $this, 'is_enabled' ), 10, 2 ); add_action( 'um_dispatch_email', array( $this, 'send' ), 10, 3 ); - add_action( 'um_before_email_notification_sending', array( $this, 'before_email_send' ), 10, 2 ); } public function is_enabled( $is_enabled, $hook ) { @@ -52,29 +51,5 @@ if ( ! class_exists( 'um\common\actions\Emails' ) ) { UM()->mail()->send( $user_email, $template, $args ); } - - /** - * Add some custom placeholders when sending via Action Scheduler. - * - * @todo Workaround for now. Maybe we need to handle email placeholders in email class where $user_id is fetched everytime - * - * @param string $email - * @param string $template - * - * @return void - */ - public function before_email_send( $email, $template ) { - if ( ! UM()->maybe_action_scheduler()->is_hook_enabled( 'um_dispatch_email' ) ) { - return; - } - - if ( 'checkmail_email' === $template ) { - add_filter( 'um_template_tags_patterns_hook', array( UM()->user(), 'add_activation_placeholder' ) ); - add_filter( 'um_template_tags_replaces_hook', array( UM()->user(), 'add_activation_replace_placeholder' ) ); - } elseif ( 'welcome_email' === $template || 'approved_email' === $template || 'resetpw_email' === $template ) { - add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ) ); - add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ) ); - } - } } } diff --git a/includes/common/class-users.php b/includes/common/class-users.php index 1701b913..79c6a4fc 100644 --- a/includes/common/class-users.php +++ b/includes/common/class-users.php @@ -387,10 +387,22 @@ class Users { $current_user_id = get_current_user_id(); um_fetch_user( $user_id ); - add_filter( 'um_template_tags_patterns_hook', array( UM()->user(), 'add_activation_placeholder' ) ); - add_filter( 'um_template_tags_replaces_hook', array( UM()->user(), 'add_activation_replace_placeholder' ) ); - - UM()->maybe_action_scheduler()->enqueue_async_action( 'um_dispatch_email', array( $userdata->user_email, 'checkmail_email', array( 'fetch_user_id' => $user_id ) ) ); + UM()->maybe_action_scheduler()->enqueue_async_action( + 'um_dispatch_email', + array( + $userdata->user_email, + 'checkmail_email', + array( + 'fetch_user_id' => $user_id, + 'tags' => array( + '{account_activation_link}', + ), + 'tags_replace' => array( + UM()->permalinks()->activate_url( $user_id ), + ), + ), + ) + ); um_fetch_user( $current_user_id ); /** @@ -689,19 +701,48 @@ class Users { $this->reset_activation_link( $user_id ); - $email_slug = 'welcome_email'; - if ( 'awaiting_admin_review' === $old_status ) { - $email_slug = 'approved_email'; - $this->maybe_generate_password_reset_key( $userdata ); + $email_slug = 'awaiting_admin_review' === $old_status ? 'approved_email' : 'welcome_email'; + + $reset_pw_link = UM()->password()->reset_url( $user_id ); + + $tags = array( + '{password_reset_link}', + '{password}', + ); + $tags_replace = array( + $reset_pw_link, + __( 'Your set password', 'ultimate-member' ), + ); + + if ( 'welcome_email' === $email_slug ) { + $tags[] = '{action_url}'; + $tags[] = '{action_title}'; + + $set_password_required = get_user_meta( $user_id, 'um_set_password_required', true ); + if ( empty( $set_password_required ) || $this->has_status( $user_id, 'pending' ) ) { + $tags_replace[] = um_get_core_page( 'login' ); + $tags_replace[] = esc_html__( 'Login to our site', 'ultimate-member' ); + } else { + $tags_replace[] = $reset_pw_link; + $tags_replace[] = esc_html__( 'Set your password', 'ultimate-member' ); + } } $current_user_id = get_current_user_id(); um_fetch_user( $user_id ); - add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ) ); - add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ) ); - - UM()->maybe_action_scheduler()->enqueue_async_action( 'um_dispatch_email', array( $userdata->user_email, $email_slug, array( 'fetch_user_id' => $user_id ) ) ); + UM()->maybe_action_scheduler()->enqueue_async_action( + 'um_dispatch_email', + array( + $userdata->user_email, + $email_slug, + array( + 'fetch_user_id' => $user_id, + 'tags' => $tags, + 'tags_replace' => $tags_replace, + ), + ) + ); um_fetch_user( $current_user_id ); } @@ -776,10 +817,39 @@ class Users { $current_user_id = get_current_user_id(); um_fetch_user( $user_id ); - add_filter( 'um_template_tags_patterns_hook', array( UM()->password(), 'add_placeholder' ) ); - add_filter( 'um_template_tags_replaces_hook', array( UM()->password(), 'add_replace_placeholder' ) ); + $reset_pw_link = UM()->password()->reset_url( $user_id ); - UM()->maybe_action_scheduler()->enqueue_async_action( 'um_dispatch_email', array( $userdata->user_email, 'welcome_email', array( 'fetch_user_id' => $user_id ) ) ); + $tags_replace = array( + $reset_pw_link, + __( 'Your set password', 'ultimate-member' ), + ); + + $set_password_required = get_user_meta( $user_id, 'um_set_password_required', true ); + if ( empty( $set_password_required ) || $this->has_status( $user_id, 'pending' ) ) { + $tags_replace[] = um_get_core_page( 'login' ); + $tags_replace[] = esc_html__( 'Login to our site', 'ultimate-member' ); + } else { + $tags_replace[] = $reset_pw_link; + $tags_replace[] = esc_html__( 'Set your password', 'ultimate-member' ); + } + + UM()->maybe_action_scheduler()->enqueue_async_action( + 'um_dispatch_email', + array( + $userdata->user_email, + 'welcome_email', + array( + 'fetch_user_id' => $user_id, + 'tags' => array( + '{password_reset_link}', + '{password}', + '{action_url}', + '{action_title}', + ), + 'tags_replace' => $tags_replace, + ), + ) + ); um_fetch_user( $current_user_id ); @@ -860,4 +930,15 @@ class Users { return $total_users; } + + /** + * Set last login timestamp. + * + * @param int $user_id User ID. + */ + public function set_last_login( $user_id ) { + update_user_meta( $user_id, '_um_last_login', current_time( 'mysql', true ) ); + // Flush user cache after updating last_login timestamp. + UM()->user()->remove_cache( $user_id ); + } } diff --git a/includes/core/class-mail.php b/includes/core/class-mail.php index 60d7c298..4df1543d 100644 --- a/includes/core/class-mail.php +++ b/includes/core/class-mail.php @@ -348,9 +348,6 @@ if ( ! class_exists( 'um\core\Mail' ) ) { */ $message = apply_filters( 'um_email_send_message_content', $message, $slug, $args ); -// add_filter( 'um_template_tags_patterns_hook', array( &$this, 'add_placeholder' ) ); -// add_filter( 'um_template_tags_replaces_hook', array( &$this, 'add_replace_placeholder' ) ); - // Convert tags in email template. return um_convert_tags( $message, $args ); } @@ -616,12 +613,8 @@ if ( ! class_exists( 'um\core\Mail' ) ) { $placeholders[] = '{user_profile_link}'; $placeholders[] = '{site_url}'; $placeholders[] = '{admin_email}'; - $placeholders[] = '{submitted_registration}'; $placeholders[] = '{login_url}'; $placeholders[] = '{password}'; - $placeholders[] = '{account_activation_link}'; - $placeholders[] = '{action_url}'; - $placeholders[] = '{action_title}'; return $placeholders; } @@ -636,20 +629,8 @@ if ( ! class_exists( 'um\core\Mail' ) ) { $replace_placeholders[] = um_user_profile_url(); $replace_placeholders[] = get_bloginfo( 'url' ); $replace_placeholders[] = um_admin_email(); - $replace_placeholders[] = um_user_submitted_registration_formatted(); $replace_placeholders[] = um_get_core_page( 'login' ); $replace_placeholders[] = esc_html__( 'Your set password', 'ultimate-member' ); - $replace_placeholders[] = um_user( 'account_activation_link' ); - - $set_password_required = get_user_meta( um_user( 'ID' ), 'um_set_password_required', true ); - if ( empty( $set_password_required ) || 'pending' === um_user( 'status' ) ) { - $replace_placeholders[] = um_get_core_page( 'login' ); - $replace_placeholders[] = esc_html__( 'Login to our site', 'ultimate-member' ); - } else { - $replace_placeholders[] = um_user( 'password_reset_link' ); - $replace_placeholders[] = esc_html__( 'Set your password', 'ultimate-member' ); - } - return $replace_placeholders; } } diff --git a/includes/core/class-password.php b/includes/core/class-password.php index c08fbe0b..434ab902 100644 --- a/includes/core/class-password.php +++ b/includes/core/class-password.php @@ -57,11 +57,11 @@ if ( ! class_exists( 'um\core\Password' ) ) { } if ( empty( $reset_key ) ) { - $reset_key = UM()->user()->maybe_generate_password_reset_key( $user_data ); + $reset_key = UM()->common()->users()->maybe_generate_password_reset_key( $user_data ); } - // this link looks like WordPress native link e.g. wp-login.php?action=rp&key={hash}&login={user_login} - $url = add_query_arg( + // This link looks like WordPress native link e.g. wp-login.php?action=rp&key={hash}&login={user_login} + return add_query_arg( array( 'act' => 'reset_password', 'hash' => $reset_key, @@ -69,7 +69,6 @@ if ( ! class_exists( 'um\core\Password' ) ) { ), um_get_core_page( 'password-reset' ) ); - return $url; } @@ -695,31 +694,27 @@ if ( ! class_exists( 'um\core\Password' ) ) { setcookie( $name, $value, $expire, $path, COOKIE_DOMAIN, is_ssl(), true ); } - /** * UM Placeholders for reset password - * + * @depreated 2.10.5 * @param $placeholders * * @return array */ - function add_placeholder( $placeholders ) { - $placeholders[] = '{password_reset_link}'; - $placeholders[] = '{password}'; + public function add_placeholder( $placeholders ) { + _deprecated_function( __METHOD__, '2.10.5' ); return $placeholders; } - /** * UM Replace Placeholders for reset password - * + * @depreated 2.10.5 * @param $replace_placeholders * * @return array */ - function add_replace_placeholder( $replace_placeholders ) { - $replace_placeholders[] = um_user( 'password_reset_link' ); - $replace_placeholders[] = esc_html__( 'Your set password', 'ultimate-member' ); + public function add_replace_placeholder( $replace_placeholders ) { + _deprecated_function( __METHOD__, '2.10.5' ); return $replace_placeholders; } } diff --git a/includes/core/class-permalinks.php b/includes/core/class-permalinks.php index 5abe91cc..d930ab25 100644 --- a/includes/core/class-permalinks.php +++ b/includes/core/class-permalinks.php @@ -172,8 +172,7 @@ if ( ! class_exists( 'um\core\Permalinks' ) ) { $redirect = empty( $user_role_data['url_email_activate'] ) ? um_get_core_page( 'login', 'account_active' ) : trim( $user_role_data['url_email_activate'] ); } else { // Redirect to the change password page if there is no password for this user. - um_fetch_user( $user_id ); - $redirect = um_user( 'password_reset_link' ); + $redirect = UM()->password()->reset_url( $user_id ); } /** * Filter to change the redirect URL after email confirmation. @@ -204,40 +203,44 @@ if ( ! class_exists( 'um\core\Permalinks' ) ) { /** * Makes an activate link for any user * - * @return bool|string + * @return string */ - public function activate_url() { - if ( ! um_user( 'account_secret_hash' ) ) { - return false; + public function activate_url( $user_id = null ) { + if ( is_null( $user_id ) ) { + $user_id = um_user( 'ID' ); + } + + $account_secret_hash = get_user_meta( $user_id, 'account_secret_hash', true ); + if ( empty( $account_secret_hash ) ) { + return ''; } /** - * UM hook + * Filter to change the base URL for the user activation link. * - * @type filter - * @title um_activate_url - * @description Change activate user URL - * @input_vars - * [{"var":"$url","type":"string","desc":"Activate URL"}] - * @change_log - * ["Since: 2.0"] - * @usage - * - * @example - * Change activate user base URL. + * function my_after_email_confirmation_redirect( $url ) { * // your code here * return $url; * } - * ?> + * add_filter( 'um_activate_url', 'my_um_activate_url' ); */ - $url = apply_filters( 'um_activate_url', home_url() ); - $url = add_query_arg( 'act', 'activate_via_email', $url ); - $url = add_query_arg( 'hash', um_user( 'account_secret_hash' ), $url ); - $url = add_query_arg( 'user_id', um_user( 'ID' ), $url ); + $base_url = apply_filters( 'um_activate_url', home_url() ); - return $url; + return add_query_arg( + array( + 'act' => 'activate_via_email', + 'hash' => $account_secret_hash, + 'user_id' => $user_id, + ), + $base_url + ); } /** diff --git a/includes/core/class-profile.php b/includes/core/class-profile.php index b469209e..ad5d9d64 100644 --- a/includes/core/class-profile.php +++ b/includes/core/class-profile.php @@ -513,35 +513,28 @@ if ( ! class_exists( 'um\core\Profile' ) ) { @@ -1468,22 +1471,6 @@ if ( ! class_exists( 'um\core\User' ) ) { do_action( 'um_after_save_registration_details', $this->id, $submitted, $form_data ); } - /** - * Set last login for new registered users - */ - public function set_last_login() { - update_user_meta( $this->id, '_um_last_login', current_time( 'mysql', true ) ); - } - - /** - * @param \WP_User $userdata - * - * @return string|\WP_Error - */ - function maybe_generate_password_reset_key( $userdata ) { - return get_password_reset_key( $userdata ); - } - /** * Password reset email * @@ -1497,19 +1484,22 @@ if ( ! class_exists( 'um\core\User' ) ) { } $userdata = get_userdata( $user_id ); - $this->maybe_generate_password_reset_key( $userdata ); - - $mail_args = array( - 'fetch_user_id' => $user_id, - 'tags' => array( - '{password_reset_link}', - ), - 'tags_replace' => array( - UM()->password()->reset_url( $user_id ), - ), + UM()->maybe_action_scheduler()->enqueue_async_action( + 'um_dispatch_email', + array( + $userdata->user_email, + 'resetpw_email', + array( + 'fetch_user_id' => $user_id, + 'tags' => array( + '{password_reset_link}', + ), + 'tags_replace' => array( + UM()->password()->reset_url( $user_id ), + ), + ), + ) ); - - UM()->maybe_action_scheduler()->enqueue_async_action( 'um_dispatch_email', array( $userdata->user_email, 'resetpw_email', $mail_args ) ); } /** @@ -2121,30 +2111,6 @@ if ( ! class_exists( 'um\core\User' ) ) { return $hash_email_address; } - /** - * UM Placeholders for activation link in email - * - * @param $placeholders - * - * @return array - */ - public function add_activation_placeholder( $placeholders ) { - $placeholders[] = '{account_activation_link}'; - return $placeholders; - } - - /** - * UM Replace Placeholders for activation link in email - * - * @param $replace_placeholders - * - * @return array - */ - public function add_activation_replace_placeholder( $replace_placeholders ) { - $replace_placeholders[] = um_user( 'account_activation_link' ); - return $replace_placeholders; - } - /** * Set user's account status * @@ -2240,5 +2206,53 @@ if ( ! class_exists( 'um\core\User' ) ) { _deprecated_function( __METHOD__, '2.8.7', 'UM()->common()->users()->deactivate()' ); UM()->common()->users()->deactivate( um_user( 'ID' ) ); } + + /** + * @deprecated 2.10.5 + * + * @param WP_User $userdata + * + * @return string|WP_Error + */ + public function maybe_generate_password_reset_key( $userdata ) { + _deprecated_function( __METHOD__, '2.10.5', 'UM()->common()->users()->maybe_generate_password_reset_key()' ); + return UM()->common()->users()->maybe_generate_password_reset_key( $userdata ); + } + + /** + * Set last login for new registered users + * + * @deprecated 2.10.5 + * + * @return void + */ + public function set_last_login() { + _deprecated_function( __METHOD__, '2.10.5', 'UM()->common()->users()->set_last_login()' ); + UM()->common()->users()->set_last_login( $this->id ); + } + + /** + * UM Placeholders for activation link in email + * @deprecated 2.10.5 + * @param $placeholders + * + * @return array + */ + public function add_activation_placeholder( $placeholders ) { + _deprecated_function( __METHOD__, '2.10.5' ); + return $placeholders; + } + + /** + * UM Replace Placeholders for activation link in email + * @deprecated 2.10.5 + * @param $replace_placeholders + * + * @return array + */ + public function add_activation_replace_placeholder( $replace_placeholders ) { + _deprecated_function( __METHOD__, '2.10.5' ); + return $replace_placeholders; + } } } diff --git a/includes/core/um-actions-login.php b/includes/core/um-actions-login.php index 42cac3e0..ab3cd3b1 100644 --- a/includes/core/um-actions-login.php +++ b/includes/core/um-actions-login.php @@ -157,11 +157,9 @@ add_action( 'um_submit_form_errors_hook_logincheck', 'um_submit_form_errors_hook * @param $user_id */ function um_store_lastlogin_timestamp( $user_id ) { - update_user_meta( $user_id, '_um_last_login', current_time( 'mysql', true ) ); - // Flush user cache after updating last_login timestamp. - UM()->user()->remove_cache( $user_id ); + UM()->common()->users()->set_last_login( $user_id ); } -add_action( 'um_on_login_before_redirect', 'um_store_lastlogin_timestamp', 10, 1 ); +add_action( 'um_on_login_before_redirect', 'um_store_lastlogin_timestamp' ); /** @@ -171,7 +169,7 @@ function um_store_lastlogin_timestamp_( $login ) { $user = get_user_by( 'login', $login ); if ( false !== $user ) { - um_store_lastlogin_timestamp( $user->ID ); + UM()->common()->users()->set_last_login( $user->ID ); $attempts = (int) get_user_meta( $user->ID, 'password_rst_attempts', true ); if ( $attempts ) { diff --git a/includes/core/um-actions-register.php b/includes/core/um-actions-register.php index 007101e8..89f6bfe6 100644 --- a/includes/core/um-actions-register.php +++ b/includes/core/um-actions-register.php @@ -120,15 +120,27 @@ function um_send_registration_notification( $user_id ) { um_fetch_user( $user_id ); $registration_status = um_user( 'status' ); + $email_template = 'pending' !== $registration_status ? 'notification_new_user' : 'notification_review'; + $sending_args = array( + 'admin' => true, + 'fetch_user_id' => $user_id, + 'tags' => array( + '{submitted_registration}', + ), + 'tags_replace' => um_user_submitted_registration_formatted(), + ); $emails = um_multi_admin_email(); if ( ! empty( $emails ) ) { foreach ( $emails as $email ) { - if ( 'pending' !== $registration_status ) { - UM()->maybe_action_scheduler()->enqueue_async_action( 'um_dispatch_email', array( $email, 'notification_new_user', array( 'admin' => true, 'fetch_user_id' => $user_id ) ) ); - } else { - UM()->maybe_action_scheduler()->enqueue_async_action( 'um_dispatch_email', array( $email, 'notification_review', array( 'admin' => true, 'fetch_user_id' => $user_id ) ) ); - } + UM()->maybe_action_scheduler()->enqueue_async_action( + 'um_dispatch_email', + array( + $email, + $email_template, + $sending_args, + ) + ); } } } diff --git a/includes/um-short-functions.php b/includes/um-short-functions.php index df0c93da..45ac1b56 100644 --- a/includes/um-short-functions.php +++ b/includes/um-short-functions.php @@ -208,7 +208,7 @@ function um_convert_tags( $content, $args = array(), $with_kses = true ) { // Support for all usermeta keys if ( ! empty( $matches[1] ) && is_array( $matches[1] ) ) { foreach ( $matches[1] as $match ) { - $key = str_replace( 'usermeta:', '', $match ); + $key = str_replace( 'usermeta:', '', $match ); $value = um_user( $key ); if ( is_array( $value ) ) { $value = implode( ', ', $value ); @@ -219,32 +219,6 @@ function um_convert_tags( $content, $args = array(), $with_kses = true ) { return $content; } - -/** - * UM Placeholders for activation link in email - * - * @param $placeholders - * - * @return array - */ -function account_activation_link_tags_patterns( $placeholders ) { - $placeholders[] = '{account_activation_link}'; - return $placeholders; -} - -/** - * UM Replace Placeholders for activation link in email - * - * @param $replace_placeholders - * - * @return array - */ -function account_activation_link_tags_replaces( $replace_placeholders ) { - $replace_placeholders[] = um_user( 'account_activation_link' ); - return $replace_placeholders; -} - - /** * @function um_user_ip() * @@ -2583,12 +2557,12 @@ function um_user( $data, $attrs = null ) { break; case 'password_reset_link': + // Avoid using and make it directly with `UM()->password()->reset_url( $user_id )` return UM()->password()->reset_url(); - break; case 'account_activation_link': + // Avoid using and make it directly with `UM()->permalinks()->activate_url( $user_id )` return UM()->permalinks()->activate_url(); - break; case 'profile_photo': $data = um_get_user_avatar_data( um_user( 'ID' ), $attrs );