diff --git a/includes/emails/class-wpum-emails.php b/includes/emails/class-wpum-emails.php
index 70dd4f7b..6fef181c 100644
--- a/includes/emails/class-wpum-emails.php
+++ b/includes/emails/class-wpum-emails.php
@@ -402,12 +402,24 @@ public function get_tags() {
'tag' => 'login_page_url',
'function' => 'wpum_email_tag_login_page_url',
),
+ array(
+ 'name' => esc_html__( 'Login page link', 'wp-user-manager' ),
+ 'description' => esc_html__( 'Display the login page link.', 'wp-user-manager' ),
+ 'tag' => 'login_page_link',
+ 'function' => 'wpum_email_tag_login_page_link',
+ ),
array(
'name' => esc_html__( 'Password recovery url', 'wp-user-manager' ),
'description' => esc_html__( 'Display the password recovery url.', 'wp-user-manager' ),
'tag' => 'recovery_url',
'function' => 'wpum_email_tag_password_recovery_url',
),
+ array(
+ 'name' => esc_html__( 'Password recovery link', 'wp-user-manager' ),
+ 'description' => esc_html__( 'Display the password recovery url as a link.', 'wp-user-manager' ),
+ 'tag' => 'recovery_link',
+ 'function' => 'wpum_email_tag_password_recovery_link',
+ ),
);
return apply_filters( 'wpum_email_tags', $email_tags, $this );
diff --git a/includes/emails/wpum-email-functions.php b/includes/emails/wpum-email-functions.php
index 90fbc235..2bcdce8c 100644
--- a/includes/emails/wpum-email-functions.php
+++ b/includes/emails/wpum-email-functions.php
@@ -136,6 +136,21 @@ function wpum_email_tag_login_page_url( $user_id = false ) { // phpcs:ignore Gen
$login_page_url = wpum_get_core_page_id( 'login' );
$login_page_url = get_permalink( $login_page_url );
+ return $login_page_url;
+}
+
+/**
+ * Parse the {login_page_link} tag into the email to display the site login page url as a link.
+ *
+ * @param string $user_id
+ *
+ * @return string
+ */
+function wpum_email_tag_login_page_link( $user_id = false ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Required by email tag callback signature.
+
+ $login_page_url = wpum_get_core_page_id( 'login' );
+ $login_page_url = get_permalink( $login_page_url );
+
$url = $login_page_url;
if ( wpum_get_option( 'email_template' ) !== 'none' ) {
@@ -177,6 +192,30 @@ function wpum_email_tag_password_recovery_url( $user_id, $password_reset_key, $p
'action' => 'wpum-reset',
), $reset_page );
+ return $reset_page;
+}
+
+/**
+ * Parse the {recovery_link} tag into the email to display personalized password recovery url as a link.
+ *
+ * @param int $user_id
+ * @param string $password_reset_key
+ * @param string $plain_text_password
+ * @param string $tag
+ * @param string $email
+ *
+ * @return string
+ */
+function wpum_email_tag_password_recovery_link( $user_id, $password_reset_key, $plain_text_password, $tag, $email ) {
+
+ $reset_page = wpum_get_core_page_id( 'password' );
+ $reset_page = get_permalink( $reset_page );
+ $reset_page = add_query_arg( array(
+ 'login' => rawurlencode( $email->user_login ),
+ 'key' => $password_reset_key,
+ 'action' => 'wpum-reset',
+ ), $reset_page );
+
$link_color = apply_filters( 'wpum_email_tag_password_recovery_url_color', '#000' );
$output = $reset_page;
diff --git a/tests/wpunit/Emails/EmailTagsTest.php b/tests/wpunit/Emails/EmailTagsTest.php
index cb2c37f8..028dbc97 100644
--- a/tests/wpunit/Emails/EmailTagsTest.php
+++ b/tests/wpunit/Emails/EmailTagsTest.php
@@ -57,12 +57,145 @@ public function test_email_tag_replaced() {
* Test that {login_page_url} tag returns a URL.
*/
public function test_login_page_url_tag_replaced() {
+ $page_id = $this->factory()->post->create( array(
+ 'post_type' => 'page',
+ 'post_title' => 'Login Page',
+ 'post_status' => 'publish',
+ ) );
+
+ $filter = function () use ( $page_id ) {
+ return array( $page_id );
+ };
+ add_filter( 'wpum_get_option_login_page', $filter );
+
$result = wpum_email_tag_login_page_url( $this->test_user_id );
- // The result should contain some URL string or link.
+ remove_filter( 'wpum_get_option_login_page', $filter );
+
$this->assertNotEmpty( $result, 'login_page_url tag should return a non-empty value.' );
}
+ /**
+ * Test that {login_page_link} tag returns an anchor tag when email_template is set.
+ */
+ public function test_login_page_link_tag_returns_anchor() {
+ $page_id = $this->factory()->post->create( array(
+ 'post_type' => 'page',
+ 'post_title' => 'Login Page',
+ 'post_status' => 'publish',
+ ) );
+
+ $page_filter = function () use ( $page_id ) {
+ return array( $page_id );
+ };
+ add_filter( 'wpum_get_option_login_page', $page_filter );
+
+ $template_filter = function () {
+ return 'default';
+ };
+ add_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $result = wpum_email_tag_login_page_link( $this->test_user_id );
+
+ remove_filter( 'wpum_get_option_login_page', $page_filter );
+ remove_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $this->assertStringContainsString( 'factory()->post->create( array(
+ 'post_type' => 'page',
+ 'post_title' => 'Login Page',
+ 'post_status' => 'publish',
+ ) );
+
+ $page_filter = function () use ( $page_id ) {
+ return array( $page_id );
+ };
+ add_filter( 'wpum_get_option_login_page', $page_filter );
+
+ $template_filter = function () {
+ return 'none';
+ };
+ add_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $result = wpum_email_tag_login_page_link( $this->test_user_id );
+
+ remove_filter( 'wpum_get_option_login_page', $page_filter );
+ remove_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $this->assertStringNotContainsString( 'assertNotEmpty( $result );
+ }
+
+ /**
+ * Test that {recovery_link} tag returns an anchor tag when email_template is set.
+ */
+ public function test_recovery_link_tag_returns_anchor() {
+ $page_id = $this->factory()->post->create( array(
+ 'post_type' => 'page',
+ 'post_title' => 'Password Reset Page',
+ 'post_status' => 'publish',
+ ) );
+
+ $page_filter = function () use ( $page_id ) {
+ return array( $page_id );
+ };
+ add_filter( 'wpum_get_option_password_recovery_page', $page_filter );
+
+ $template_filter = function () {
+ return 'default';
+ };
+ add_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $user = get_user_by( 'id', $this->test_user_id );
+ $email = (object) array( 'user_login' => $user->user_login );
+
+ $result = wpum_email_tag_password_recovery_link( $this->test_user_id, 'test-key', '', 'recovery_link', $email );
+
+ remove_filter( 'wpum_get_option_password_recovery_page', $page_filter );
+ remove_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $this->assertStringContainsString( 'assertStringContainsString( 'test-key', $result, 'recovery_link tag should include the reset key in the URL.' );
+ }
+
+ /**
+ * Test that {recovery_link} tag returns a plain URL when email_template is none.
+ */
+ public function test_recovery_link_tag_returns_plain_url_for_none_template() {
+ $page_id = $this->factory()->post->create( array(
+ 'post_type' => 'page',
+ 'post_title' => 'Password Reset Page',
+ 'post_status' => 'publish',
+ ) );
+
+ $page_filter = function () use ( $page_id ) {
+ return array( $page_id );
+ };
+ add_filter( 'wpum_get_option_password_recovery_page', $page_filter );
+
+ $template_filter = function () {
+ return 'none';
+ };
+ add_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $user = get_user_by( 'id', $this->test_user_id );
+ $email = (object) array( 'user_login' => $user->user_login );
+
+ $result = wpum_email_tag_password_recovery_link( $this->test_user_id, 'test-key', '', 'recovery_link', $email );
+
+ remove_filter( 'wpum_get_option_password_recovery_page', $page_filter );
+ remove_filter( 'wpum_get_option_email_template', $template_filter );
+
+ $this->assertStringNotContainsString( 'assertNotEmpty( $result );
+ }
+
/**
* Test that {firstname} tag is replaced.
*/