在本系列的前兩個教程中,我們構建了用于登錄和注冊新用戶的自定義頁面。現在,登錄流程中只剩下一個部分需要探索和替換:如果用戶忘記密碼并想要重置 wordpress 密碼,會發生什么?
在本教程中,我們將解決最后一步并完成我們在整個系列中構建的個性化登錄插件。
WordPress 中的密碼重置功能或多或少遵循當今網站上的標準方法:
- 用戶通過輸入用戶名或電子郵件地址并請求 WordPress 重置密碼來啟動重置。
- 創建臨時密碼重置令牌并將其存儲在用戶數據中。包含此令牌的鏈接將發送到用戶的電子郵件地址。
- 用戶點擊鏈接。
- 在重置密碼頁面上,令牌會經過驗證,如果它與用戶的數據匹配,他們就可以選擇一個新密碼。
就像登錄和新用戶注冊一樣,此功能是通過 wp-login.php 處理的。因此,我們如何自定義此流程的總體思路現在大部分都是以前的教程所熟悉的。
如果您尚未閱讀前兩個教程,最好從第 1 部分開始并按順序瀏覽該系列。您可以按照教程自行編寫代碼,也可以從鏈接的 github 存儲庫下載完整的源代碼。
現在,讓我們開始替換流程中的第一個屏幕。
啟動 WordPress 重置密碼
當用戶到達您的登錄頁面但不記得他們在該網站上使用的密碼時,就會開始重置 WP 密碼。
為此,我們在本系列第一部分的登錄表單底部放置了一個忘記密碼?消息模板鏈接。默認情況下,在 WordPress 支持的網站上,此鏈接指向 wp-login.php?action=lostpassword,頁面如下所示:
要將此頁面替換為自定義頁面,我們將創建一個函數來將用戶重定向到我們的自定義頁面,并將該函數掛鉤到 WordPress 操作。
在這種情況下,我們有兩個選項可供選擇:我們可以使用操作 lost_password,該操作在頁面渲染之前調用,或者我們在之前的教程中使用的操作: login_form_{action},這次是login_form_lostpassword。
我們可以采取兩種方法,但為了限制執行的不必要代碼的數量,讓我們選擇后一個選項。
但首先,讓我們創建新的 WordPress 自定義密碼重置頁面:
第 1 步:創建重置密碼頁面 p>
正如您所記得的,在第 1 部分中,我們使用 plugin_activated 回調函數創建了一個在插件激活時創建 WordPress 頁面的函數。
在此函數中,將新頁面的定義添加到 $page_definitions 數組的末尾。在 WordPress 密碼重置流程中,我們還需要第二個頁面來選擇新密碼。因此,為了節省時間,我們現在還添加第二頁。
為了清楚起見,這是整個數組(添加了最后兩個頁面定義):
// Information needed for creating the plugin's pages $page_definitions = array( 'member-login' => array( 'title' => __( 'Sign In', 'personalize-login' ), 'content' => '[custom-login-form]' ), 'member-account' => array( 'title' => __( 'Your Account', 'personalize-login' ), 'content' => '[account-info]' ), 'member-register' => array( 'title' => __( 'Register', 'personalize-login' ), 'content' => '[custom-register-form]' ), 'member-password-lost' => array( 'title' => __( 'Forgot Your Password?', 'personalize-login' ), 'content' => '[custom-password-lost-form]' ), 'member-password-reset' => array( 'title' => __( 'Pick a New Password', 'personalize-login' ), 'content' => '[custom-password-reset-form]' ) );
插件激活回調僅在插件被顯式激活時調用,因此要創建這些新頁面,您必須停用插件,然后再次激活它。
現在,創建頁面后,我們可以將用戶重定向到 member-password-lost 而不是 wp-login?action=lostpassword。
第 2 步:將用戶重定向到自定義頁面
正如我上面提到的,我們將使用操作 login_form_{action} 或 login_form_lostpassword 在 wp-login 之前切入.php 有機會呈現“丟失密碼?”的默認版本。屏幕。
在插件的構造函數中,添加以下行:
add_action( 'login_form_lostpassword', array( $this, 'redirect_to_custom_lostpassword' ) );
然后,創建函數 redirect_to_custom_lostpassword。
此函數將檢查請求方法:目前,我們僅對使用 GET 方法發送的請求進行操作,因為這些是用于顯示屏幕的請求。稍后我們將看看 POST 發生了什么。
/** * Redirects the user to the custom "Forgot your password?" page instead of * wp-login.php?action=lostpassword. */ public function redirect_to_custom_lostpassword() { if ( 'GET' == $_SERVER['REQUEST_METHOD'] ) { if ( is_user_logged_in() ) { $this->redirect_logged_in_user(); exit; } wp_redirect( home_url( 'member-password-lost' ) ); exit; } }
該功能實際上與我們在上一篇教程中用于將用戶重定向到自定義注冊頁面的功能相同,只是將重定向替換為我們上面創建的新頁面的頁面slug(對于某些人來說這是一個好地方)也許將來會重構?)。
現在,如果您在登錄頁面上點擊忘記了 WordPress 密碼?,您將被重定向到 WordPress 自定義密碼重置頁面。接下來,讓我們創建一個短代碼來添加用于啟動密碼重置的 WordPress 密碼表單。
第 3 步:為 WordPress 更改密碼表單創建簡碼
在創建用于啟動 WordPress 密碼重置的頁面時,我們將短代碼 [custom-lost-password-form] 添加到其正文中。現在,為了用表單替換短代碼,讓我們創建一個短代碼處理程序。
在插件的構造函數中,添加以下行:
add_shortcode( 'custom-password-lost-form', array( $this, 'render_password_lost_form' ) );
然后,創建用于渲染表單的函數:
/** * A shortcode for rendering the form used to initiate the password reset. * * @param array $attributes Shortcode attributes. * @param string $content The text content for shortcode. Not used. * * @return string The shortcode output */ public function render_password_lost_form( $attributes, $content = null ) { // Parse shortcode attributes $default_attributes = array( 'show_title' => false ); $attributes = shortcode_atts( $default_attributes, $attributes ); if ( is_user_logged_in() ) { return __( 'You are already signed in.', 'personalize-login' ); } else { return $this->get_template_html( 'password_lost_form', $attributes ); } }
現在,這個函數的大部分內容你已經很熟悉了:首先我們解析短代碼參數(show_title 用于決定是否應該在啟動密碼重置的表單之前呈現標題) 。然后,如果用戶未登錄,該函數將呈現一個包含 WordPress 忘記密碼表單的模板。
現在讓我們添加該模板。在 templates 目錄中,創建一個新文件,并將其命名為 password_lost_form.php。然后,將以下代碼添加到該模板:
<div id="password-lost-form" class="widecolumn"> <?php if ( $attributes['show_title'] ) : ?><h3><?php _e( 'Forgot Your Password?', 'personalize-login' ); ?></h3> <?php endif; ?><p> <?php _e( "Enter your email address and we'll send you a link you can use to pick a new password.", 'personalize_login' ); ?></p> <form id="lostpasswordform" action="<?php%20echo%20wp_lostpassword_url();%20?>" method="post"> <p class="form-row"> <label for="user_login"><?php _e( 'Email', 'personalize-login' ); ?><input type="text" name="user_login" id="user_login"></label></p> <p class="lostpassword-submit"> <input type="submit" name="submit" class="lostpassword-button" value="<?php _e( 'Reset Password', 'personalize-login' ); ?>"></p> </form> </div>
如果 show_title 屬性設置為 true(第 2-4 行),模板首先顯示標題。
接下來是關于第 6-13 行的一些說明和實際表格。正如您在第 15 行中看到的,表單將發布到 WordPress 函數 wp_lostpassword_url 返回的網址,該網址與我們在重定向用戶時在上面看到的網址相同到我們的自定義頁面。
此表單僅包含一個文本字段,user_login(第 18 行)。在此字段中,默認的 WordPress 重置密碼功能接受用戶的用戶名或電子郵件。由于我們使用電子郵件作為用戶名,因此它們是相同的,因此我們只要求字段標簽中的電子郵件(第 17 行)。
添加此模板后,當您點擊登錄頁面上的忘記密碼?消息模板鏈接時,您將看到如下所示的頁面(如果使用 WordPress 默認主題)就像二十十五)
第 4 步:處理 WordPress 帳戶恢復表單提交
現在我們已經創建了 WordPress 密碼表單,是時候看看用戶提交它時會發生什么了。
為了讓我們在不訴諸黑客的情況下進行正確的錯誤處理,我們需要自己編寫一些功能 – 盡可能使用 wp-login.php 中的輔助函數,自然。
為此,我們將在 login_form_lostpassword 操作中添加一個新函數來處理 POST 請求。
該函數將使用 retrieve_password 函數定義在 wp-login.php 中來查找用戶并啟動密碼更新過程。然后,根據是否有錯誤,該函數將用戶重定向到正確的頁面:如果出現錯誤,則返回到忘記密碼? 消息模板頁面,成功后,進入登錄頁面。
在構造函數中,添加以下行:
add_action( 'login_form_lostpassword', array( $this, 'do_password_lost' ) );
然后,創建函數:
/** * Initiates password reset. */ public function do_password_lost() { if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) { $errors = retrieve_password(); if ( is_wp_error( $errors ) ) { // Errors found $redirect_url = home_url( 'member-password-lost' ); $redirect_url = add_query_arg( 'errors', join( ',', $errors->get_error_codes() ), $redirect_url ); } else { // Email sent $redirect_url = home_url( 'member-login' ); $redirect_url = add_query_arg( 'checkemail', 'confirm', $redirect_url ); } wp_redirect( $redirect_url ); exit; } }
該函數首先檢查請求方法(在第 5 行上)。由于我們對提交密碼丟失表單時的情況感興趣,因此該函數僅在找到 POST 請求時才會跳轉。 GET 請求已由我們之前創建的函數 redirect_to_custom_lostpassword 處理。
然后,在第 6 行,我們調用 WordPress 函數 retrieve_password。該函數的名稱有點誤導:該函數并不真正檢索密碼,而是檢查表單中的數據,然后通過創建重置 WP 密碼令牌并將其通過電子郵件發送給用戶,為 WordPress 密碼重置準備用戶帳戶。
如果出現錯誤(第 7 行),我們會將用戶重定向回頁面 member-password-lost,并將錯誤代碼作為請求參數傳遞( 第 8-10 行,實際重定向在第 17 行完成)。
如果一切順利,用戶將被重定向到帶有請求參數 checkemail 設置的登錄頁面(第 12-14 行),以便我們可以向用戶。
現在,如果您提交 WordPress 密碼表單,一切都應該正常。但為了使用戶體驗完整,我們需要返回到呈現丟失密碼和登錄表單的短代碼,并顯示錯誤和成功通知。
讓我們從積極的方面開始,添加成功消息。
在短代碼函數 render_login_form 中,在 get_template_html 調用之前添加以下行:
// Check if the user just requested a new password $attributes['lost_password_sent'] = isset( $_REQUEST['checkemail'] ) && $_REQUEST['checkemail'] == 'confirm';
在表單模板中,使用上面的屬性添加一條消息:
<?php if ( $attributes['lost_password_sent'] ) : ?><p class="login-info"> <?php _e( 'Check your email for a link to reset your password.', 'personalize-login' ); ?></p> <?php endif; ?>
現在,成功啟動密碼重置后,登錄表單應如下所示:
要顯示錯誤,我們將返回到丟失的 WordPress 更改密碼表單。
首先,在短代碼處理程序 render_password_lost_form 中,在渲染模板之前,添加以下行以遍歷錯誤代碼并收集數組 中匹配的錯誤消息$attributes[‘errors’]:
// Retrieve possible errors from request parameters $attributes['errors'] = array(); if ( isset( $_REQUEST['errors'] ) ) { $error_codes = explode( ',', $_REQUEST['errors'] ); foreach ( $error_codes as $error_code ) { $attributes['errors'] []= $this->get_error_message( $error_code ); } }
然后,在模板中,我們將呈現錯誤:
<?php if ( count( $attributes['errors'] ) > 0 ) : ?> <?php foreach ( $attributes['errors'] as $error ) : ?><p> <?php echo $error; ?></p> <?php endforeach; ?><?php endif; ?>
最后,將錯誤消息添加到我們的函數 get_error_messages:
// Lost password case 'empty_username': return __( 'You need to enter your email address to continue.', 'personalize-login' ); case 'invalid_email': case 'invalidcombo': return __( 'There are no users registered with this email address.', 'personalize-login' );
接下來,為了完成密碼重置流程的第一步,我們來看看如何自定義發送給用戶的電子郵件。
第 5 步:自定義 WordPress 更改密碼電子郵件
正如我們之前看到的,當發送重置 WP 密碼的請求時,在函數 retrieve_password 中,會發送一封 WordPress 更改密碼電子郵件,其中包含有關操作的快速說明和一個鏈接可用于完成密碼重置。
消息簡短而切題。它完成了它應該做的事情,但您可能想要對其進行自定義以賦予其個人風格,并可能使其更具描述性。
默認文本被硬編碼在 wp-login.php 中,但在發送消息之前,WordPress 為插件開發人員提供了使用兩個過濾器替換它的機會。
首先,要替換消息正文,您可以使用過濾器 retrieve_password_message。我們現在就開始吧。
在插件的構造函數中,添加以下行:
add_filter( 'retrieve_password_message', array( $this, 'replace_retrieve_password_message' ), 10, 4 );
然后,創建函數 replace_retrieve_password_message:
/** * Returns the message body for the password reset mail. * Called through the retrieve_password_message filter. * * @param string $message Default mail message. * @param string $key The activation key. * @param string $user_login The username for the user. * @param WP_User $user_data WP_User object. * * @return string The mail message to send. */ public function replace_retrieve_password_message( $message, $key, $user_login, $user_data ) { // Create new message $msg = __( 'Hello!', 'personalize-login' ) . "rnrn"; $msg .= sprintf( __( 'You asked us to reset your password for your account using the email address %s.', 'personalize-login' ), $user_login ) . "rnrn"; $msg .= __( "If this was a mistake, or you didn't ask for a password reset, just ignore this email and nothing will happen.", 'personalize-login' ) . "rnrn"; $msg .= __( 'To reset your password, visit the following address:', 'personalize-login' ) . "rnrn"; $msg .= site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' ) . "rnrn"; $msg .= __( 'Thanks!', 'personalize-login' ) . "rn"; return $msg; }
該函數接收四個參數:
- $message 是發送給用戶的消息的默認版本。我們將忽略此參數并從頭開始創建我們自己的文本。
- $key 是用于驗證用戶密碼重置請求的令牌。它需要包含在密碼重置鏈接中。
- $user_login 是用戶的用戶名(在我們的例子中是電子郵件地址),密碼重置鏈接中也需要它。
- $user_data 包含有關用戶的一些數據。我們暫時忽略這一點,但如果您愿意,可以在自己的自定義中進一步探索它。
大部分函數只是將消息創建為一系列字符串連接。用于完成密碼重置的 URL 是在第 18 行創建的。
為了進行更完整的自定義,一種想法是添加一個設置字段來編輯密碼檢索消息的內容,并使用它而不是以這種方式在函數內編碼消息。
如果您愿意,可以使用過濾器 retrieve_password_title 以同樣的方式替換電子郵件標題。過濾器函數采用一個參數,即要發送給用戶的默認標題,并且應返回新標題。
進一步自定義的另一種方法是替換整個消息并發送 HTML 消息,例如使用我在之前關于使用 Mandrill 從 WordPress 發送電子郵件的教程中解釋的方法。在這種情況下,我將使用 Mandrill API 在上面的過濾器函數中發送消息并返回 false,以便 WordPress 不會再次嘗試發送電子郵件。
您現在已經完成了 WordPress 密碼重置過程的第一步:用戶可以要求重置 WP 密碼,該過程由 WordPress 啟動。
接下來,我們將了解當用戶單擊 WordPress 更改密碼電子郵件中的鏈接時會發生什么。
重置 WordPress 密碼
正如我們在上面看到的,啟動 WordPress 重置密碼后,用戶將被重定向回登錄頁面,并附有檢查電子郵件的說明。
在 WordPress 更改密碼電子郵件中,有一個返回 wp-login.php 的鏈接,其中參數 login 和 key 用于識別用戶并驗證 WordPress 密碼重置請求。當用戶單擊鏈接時,WordPress 會驗證用戶和密鑰的有效性,如果一切正常,則讓用戶設置新密碼。
該功能運行良好,我們將使用其中的一部分,調用 wp-login.php 中的現有輔助函數,但同樣,由于操作和過濾器在 WordPress 中的組織方式密碼重置代碼,我們必須重寫一些代碼才能完成定制。
第 1 步:將用戶重定向到您的 WordPress 自定義密碼重置頁面
首先,我們將首先將用戶重定向到我們自己的 WordPress 自定義密碼重置頁面(我們在本教程開始時創建的頁面)。
現在,您可能已經熟悉了:與我們在登錄和注冊操作以及重置 WP 密碼流程中的第一頁中所做的相同,我們將使用操作 login_form_{action} 在 WordPress 執行任何操作之前將密碼重置操作轉移到我們自己的自定義函數。
有兩個 wp-login.php 操作用于相同的功能,rp 和 resetpass,所以我們需要將它們重定向到同一函數,redirect_to_custom_password_reset。
在插件的構造函數中,添加以下行:
add_action( 'login_form_rp', array( $this, 'redirect_to_custom_password_reset' ) ); add_action( 'login_form_resetpass', array( $this, 'redirect_to_custom_password_reset' ) );
然后,創建函數:
/** * Redirects to the custom password reset page, or the login page * if there are errors. */ public function redirect_to_custom_password_reset() { if ( 'GET' == $_SERVER['REQUEST_METHOD'] ) { // Verify key / login combo $user = check_password_reset_key( $_REQUEST['key'], $_REQUEST['login'] ); if ( ! $user || is_wp_error( $user ) ) { if ( $user && $user->get_error_code() === 'expired_key' ) { wp_redirect( home_url( 'member-login?login=expiredkey' ) ); } else { wp_redirect( home_url( 'member-login?login=invalidkey' ) ); } exit; } $redirect_url = home_url( 'member-password-reset' ); $redirect_url = add_query_arg( 'login', esc_attr( $_REQUEST['login'] ), $redirect_url ); $redirect_url = add_query_arg( 'key', esc_attr( $_REQUEST['key'] ), $redirect_url ); wp_redirect( $redirect_url ); exit; } }
該函數首先檢查這是一個 GET 請求。 POST 發送到同一 URL 的請求將在下面處理。
然后,在第 8 行,我們調用 WordPress 函數 check_password_reset_key 來驗證通過重置 WP 密碼鏈接傳遞的參數是否有效。如果出現錯誤,我們會將用戶重定向回登錄頁面,并將錯誤代碼作為請求參數(第 9-16 行)。我們很快就會添加顯示錯誤的代碼。
如果參數已成功驗證并且允許用戶更新其密碼,該功能將繼續將用戶重定向到我們的 WordPress 自定義密碼重置頁面(仍為空)member-password-reset。
在第 19-20 行,我們將參數 key 和 login 添加到重定向 URL,以便其他人可以使用它們檢查用戶何時嘗試在下一個屏幕上設置新密碼。默認版本的 WordPress 密碼重置使用 Cookie,但為了教程的目的,我決定使用請求參數以使代碼更易于理解。
接下來,讓我們創建一個自定義版本的重置 WordPress 密碼表單。
第 2 步:顯示 WordPress 更改密碼表單
點擊WordPress更改密碼電子郵件鏈接后向用戶顯示的重置WordPress密碼表單,默認情況下如下所示:
這是一個簡單的表單,有兩個字段,pass1 和 pass2,一個用于輸入 WordPress 密碼,另一個用于重新輸入密碼以檢查是否有拼寫錯誤。
要創建此表單的自定義版本,我們將使用短代碼。
首先,在插件的構造函數中添加以下行:
add_shortcode( 'custom-password-reset-form', array( $this, 'render_password_reset_form' ) );
然后,創建用于渲染表單的函數:
/** * A shortcode for rendering the form used to reset a user's password. * * @param array $attributes Shortcode attributes. * @param string $content The text content for shortcode. Not used. * * @return string The shortcode output */ public function render_password_reset_form( $attributes, $content = null ) { // Parse shortcode attributes $default_attributes = array( 'show_title' => false ); $attributes = shortcode_atts( $default_attributes, $attributes ); if ( is_user_logged_in() ) { return __( 'You are already signed in.', 'personalize-login' ); } else { if ( isset( $_REQUEST['login'] ) && isset( $_REQUEST['key'] ) ) { $attributes['login'] = $_REQUEST['login']; $attributes['key'] = $_REQUEST['key']; // Error messages $errors = array(); if ( isset( $_REQUEST['error'] ) ) { $error_codes = explode( ',', $_REQUEST['error'] ); foreach ( $error_codes as $code ) { $errors []= $this->get_error_message( $code ); } } $attributes['errors'] = $errors; return $this->get_template_html( 'password_reset_form', $attributes ); } else { return __( 'Invalid password reset link.', 'personalize-login' ); } } }
該函數的核心從第 17 行開始,我們在其中檢查用戶識別參數登錄名和密鑰是否存在。如果不是,則密碼重置鏈接無效,我們只會呈現一條錯誤消息(第 34 行)。
如果檢查正常,這兩個變量將添加到 $attributes 數組中,以使它們可用于表單模板(第 18-19 行)。
然后,在第 21-30 行,我們已經使用本教程中早期表單中相同的錯誤傳遞方法,為提交 WordPress 帳戶恢復表單時可能發生的錯誤做好了準備。 p>
最后,在第 32 行,該函數讀取模板并將其返回到 WordPress 進行渲染。
接下來讓我們創建模板。在 templates 目錄中,創建一個新文件,并將其命名為 password_reset_form.php。添加以下內容:
<div id="password-reset-form" class="widecolumn"> <?php if ( $attributes['show_title'] ) : ?><h3><?php _e( 'Pick a New Password', 'personalize-login' ); ?></h3> <?php endif; ?><form name="resetpassform" id="resetpassform" action="<?php%20echo%20site_url(%20'wp-login.php?action=resetpass'%20);%20?>" method="post" autocomplete="off"> <input type="hidden" id="user_login" name="rp_login" value="<?php echo esc_attr( $attributes['login'] ); ?>" autocomplete="off"><input type="hidden" name="rp_key" value="<?php echo esc_attr( $attributes['key'] ); ?>"><?php if ( count( $attributes['errors'] ) > 0 ) : ?> <?php foreach ( $attributes['errors'] as $error ) : ?><p> <?php echo $error; ?></p> <?php endforeach; ?><?php endif; ?><p> <label for="pass1"><?php _e( 'New password', 'personalize-login' ) ?></label> <input type="password" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off"></p> <p> <label for="pass2"><?php _e( 'Repeat new password', 'personalize-login' ) ?></label> <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off"></p> <p class="description"><?php echo wp_get_password_hint(); ?></p> <p class="resetpass-submit"> <input type="submit" name="submit" id="resetpass-button" class="button" value="<?php _e( 'Reset Password', 'personalize-login' ); ?>"></p> </form> </div>
表單以可選標題開頭,如果簡碼屬性 show_title 設置為 true(第 2-4 行),則顯示該標題。
實際的形式緊跟在標題之后。請注意,該表單將發布到 wp-login.php?action=resetpass(第 6 行),與密碼重置電子郵件中的鏈接中使用的 URL 相同,但除外該電子郵件鏈接使用了簡短版本 rp,而不是 resetpass。
在表單的開頭(第7-8行),我們設置了兩個隱藏字段rp_key和rp_login來傳遞key 和 login 參數傳遞給表單處理程序,該處理程序將使用它們來驗證密碼更改請求。
在第10-16行,模板將打印出錯誤(如果有)。此代碼與本教程前面的短代碼模板中的代碼完全相同。
這兩個字段在18-25行中打印出來,后面是一些有關選擇良好 WordPress 密碼的說明以及用于提交 WordPress 更改密碼表單的按鈕。
WordPress 更改密碼表單現在應如下所示:
第 3 步:處理 WordPress 重置密碼操作
當用戶通過單擊 WordPress 重置密碼按鈕提交表單時,其內容將發送到 wp-login.php?action=resetpass,相同的 URL我們在上面使用了將用戶重定向到我們的自定義密碼重置頁面。
當然,當我們自己創建表單時,我們也可以使用不同的 URL。但是,通過保留此默認 URL 并使用 login_form_resetpass (和 login_form_rp,只是為了確定)操作來替換默認功能,我們可以確保沒有人意外結束調用默認版本的密碼重置。
為此,請再次向構造函數添加兩行:
add_action( 'login_form_rp', array( $this, 'do_password_reset' ) ); add_action( 'login_form_resetpass', array( $this, 'do_password_reset' ) );
然后,創建函數:
/** * Resets the user's password if the password reset form was submitted. */ public function do_password_reset() { if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) { $rp_key = $_REQUEST['rp_key']; $rp_login = $_REQUEST['rp_login']; $user = check_password_reset_key( $rp_key, $rp_login ); if ( ! $user || is_wp_error( $user ) ) { if ( $user && $user->get_error_code() === 'expired_key' ) { wp_redirect( home_url( 'member-login?login=expiredkey' ) ); } else { wp_redirect( home_url( 'member-login?login=invalidkey' ) ); } exit; } if ( isset( $_POST['pass1'] ) ) { if ( $_POST['pass1'] != $_POST['pass2'] ) { // Passwords don't match $redirect_url = home_url( 'member-password-reset' ); $redirect_url = add_query_arg( 'key', $rp_key, $redirect_url ); $redirect_url = add_query_arg( 'login', $rp_login, $redirect_url ) $redirect_url = add_query_arg( 'error', 'password_reset_mismatch', $redirect_url ); wp_redirect( $redirect_url ); exit; } if ( empty( $_POST['pass1'] ) ) { // Password is empty $redirect_url = home_url( 'member-password-reset' ); $redirect_url = add_query_arg( 'key', $rp_key, $redirect_url ); $redirect_url = add_query_arg( 'login', $rp_login, $redirect_url ); $redirect_url = add_query_arg( 'error', 'password_reset_empty', $redirect_url ); wp_redirect( $redirect_url ); exit; } // Parameter checks OK, reset password reset_password( $user, $_POST['pass1'] ); wp_redirect( home_url( 'member-login?password=changed' ) ); } else { echo "Invalid request."; } exit; } }
該函數首先檢查請求方法,應該是 POST; GET 請求已被上面的重定向函數處理。
然后,它從表單數據中收集密鑰和登錄參數,并使用它們來驗證第 9 行上的密碼重置鏈接,使用 WordPress 函數 check_password_reset_key (我們已經在重定向函數中使用了相同的函數)。
在 第 10-18 行 中,我們再次檢查密碼重置密鑰檢查中可能存在的錯誤,將用戶重定向到忘記密碼?消息模板頁面進行渲染的錯誤。
然后,如果重置密鑰有效,我們可以專注于 WordPress 帳戶恢復表單。
首先,該函數檢查兩個密碼是否匹配(第 21-31 行),然后檢查它們是否為空(第 33-43 行)。在這兩種情況下,用戶都會被重定向回我們的密碼重置頁面,URL 中包含 key 和 login 參數,讓用戶重試密碼更新。 p>
最后,如果所有檢查均成功(如果您愿意,可以隨意添加更多檢查),該函數將使用函數 reset_password 重置 WordPress 密碼(位于 第 46 行) )并將用戶重定向到登錄頁面,并將參數 password=changed 附加到 URL 以顯示通知。
WordPress 密碼現已成功更新,剩下的就是顯示成功通知并添加錯誤消息。
首先,讓我們添加通知。在短代碼函數 render_login_form 中,添加以下檢查:
// Check if user just updated password $attributes['password_updated'] = isset( $_REQUEST['password'] ) && $_REQUEST['password'] == 'changed';
然后,在渲染表單之前將實際消息添加到模板 login_form.php:
<?php if ( $attributes['password_updated'] ) : ?><p class="login-info"> <?php _e( 'Your password has been changed. You can sign in now.', 'personalize-login' ); ?></p> <?php endif; ?>
由于我們已經添加了對呈現上述錯誤消息的支持,剩下的就是將描述性錯誤消息添加到我們的函數 get_error_message 中。
在 switch…case 構造中的 default 分支之前添加以下行:
// Reset password case 'expiredkey': case 'invalidkey': return __( 'The password reset link you used is not valid anymore.', 'personalize-login' ); case 'password_reset_mismatch': return __( "The two passwords you entered don't match.", 'personalize-login' ); case 'password_reset_empty': return __( "Sorry, we don't accept empty passwords.", 'personalize-login' );
結論
就是這樣!重置 WP 密碼功能已準備就緒,因此我們現在已經完成了 WordPress 登錄體驗的自定義,從注冊新用戶到登錄并重置丟失的密碼。
我希望本系列為您提供了足夠的工具,以便您能夠更好地進行進一步的自定義(例如,通過向密碼重置流程添加新步驟),并更好地了解 wp-login.php 內部發生的情況。
現在,去定制更多內容!