feat: password reset email event with WooNooW template
This commit is contained in:
@@ -60,6 +60,9 @@ class EmailManager {
|
|||||||
// New customer account
|
// New customer account
|
||||||
add_action('woocommerce_created_customer', [$this, 'send_new_customer_email'], 10, 3);
|
add_action('woocommerce_created_customer', [$this, 'send_new_customer_email'], 10, 3);
|
||||||
|
|
||||||
|
// Password reset - intercept WordPress default email and use our template
|
||||||
|
add_filter('retrieve_password_message', [$this, 'handle_password_reset_email'], 10, 4);
|
||||||
|
|
||||||
// Low stock / Out of stock
|
// Low stock / Out of stock
|
||||||
add_action('woocommerce_low_stock', [$this, 'send_low_stock_email'], 10, 1);
|
add_action('woocommerce_low_stock', [$this, 'send_low_stock_email'], 10, 1);
|
||||||
add_action('woocommerce_no_stock', [$this, 'send_out_of_stock_email'], 10, 1);
|
add_action('woocommerce_no_stock', [$this, 'send_out_of_stock_email'], 10, 1);
|
||||||
@@ -304,6 +307,101 @@ class EmailManager {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle password reset email - intercept WordPress default and use our template
|
||||||
|
*
|
||||||
|
* @param string $message Email message (we replace this)
|
||||||
|
* @param string $key Reset key
|
||||||
|
* @param string $user_login User login
|
||||||
|
* @param WP_User $user_data User object
|
||||||
|
* @return string Empty string to prevent WordPress sending default email
|
||||||
|
*/
|
||||||
|
public function handle_password_reset_email($message, $key, $user_login, $user_data) {
|
||||||
|
// Check if WooNooW notification system is enabled
|
||||||
|
if (!self::is_enabled()) {
|
||||||
|
return $message; // Use WordPress default
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if event is enabled
|
||||||
|
if (!$this->is_event_enabled('password_reset', 'email', 'customer')) {
|
||||||
|
return $message; // Use WordPress default
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build reset URL - use SPA route if available, otherwise WordPress default
|
||||||
|
$site_url = get_site_url();
|
||||||
|
|
||||||
|
// Check if this is a WooCommerce customer - use SPA reset page
|
||||||
|
// Otherwise fall back to WordPress default reset page
|
||||||
|
$reset_link = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
|
||||||
|
|
||||||
|
// Create a pseudo WC_Customer for template rendering
|
||||||
|
$customer = null;
|
||||||
|
if (class_exists('WC_Customer')) {
|
||||||
|
try {
|
||||||
|
$customer = new \WC_Customer($user_data->ID);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$customer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send our custom email
|
||||||
|
$this->send_password_reset_email($user_data, $key, $reset_link, $customer);
|
||||||
|
|
||||||
|
// Return empty string to prevent WordPress from sending its default plain-text email
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send password reset email using our template
|
||||||
|
*
|
||||||
|
* @param WP_User $user User object
|
||||||
|
* @param string $key Reset key
|
||||||
|
* @param string $reset_link Full reset link URL
|
||||||
|
* @param WC_Customer|null $customer WooCommerce customer object if available
|
||||||
|
*/
|
||||||
|
private function send_password_reset_email($user, $key, $reset_link, $customer = null) {
|
||||||
|
// Get email renderer
|
||||||
|
$renderer = EmailRenderer::instance();
|
||||||
|
|
||||||
|
// Build extra data for template variables
|
||||||
|
$extra_data = [
|
||||||
|
'reset_key' => $key,
|
||||||
|
'reset_link' => $reset_link,
|
||||||
|
'user_login' => $user->user_login,
|
||||||
|
'user_email' => $user->user_email,
|
||||||
|
'customer_name' => $user->display_name ?: $user->user_login,
|
||||||
|
'customer_email' => $user->user_email,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Use WC_Customer if available for better template rendering
|
||||||
|
$data = $customer ?: $user;
|
||||||
|
|
||||||
|
// Render email
|
||||||
|
$email = $renderer->render('password_reset', 'customer', $data, $extra_data);
|
||||||
|
|
||||||
|
if (!$email) {
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] Password reset email rendering failed for user: ' . $user->user_login);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send email via wp_mail
|
||||||
|
$headers = [
|
||||||
|
'Content-Type: text/html; charset=UTF-8',
|
||||||
|
'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>',
|
||||||
|
];
|
||||||
|
|
||||||
|
$sent = wp_mail($email['to'], $email['subject'], $email['body'], $headers);
|
||||||
|
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] Password reset email sent to ' . $email['to'] . ' - Result: ' . ($sent ? 'success' : 'failed'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log email sent
|
||||||
|
do_action('woonoow_email_sent', 'password_reset', 'customer', $email);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send low stock email
|
* Send low stock email
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,6 +43,22 @@ class EventRegistry {
|
|||||||
'wc_email' => 'customer_new_account',
|
'wc_email' => 'customer_new_account',
|
||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
],
|
],
|
||||||
|
'password_reset' => [
|
||||||
|
'id' => 'password_reset',
|
||||||
|
'label' => __('Password Reset', 'woonoow'),
|
||||||
|
'description' => __('When a customer requests a password reset', 'woonoow'),
|
||||||
|
'category' => 'customers',
|
||||||
|
'recipient_type' => 'customer',
|
||||||
|
'wc_email' => '',
|
||||||
|
'enabled' => true,
|
||||||
|
'variables' => [
|
||||||
|
'{reset_link}' => __('Password reset link', 'woonoow'),
|
||||||
|
'{reset_key}' => __('Password reset key', 'woonoow'),
|
||||||
|
'{user_login}' => __('Username', 'woonoow'),
|
||||||
|
'{user_email}' => __('User email', 'woonoow'),
|
||||||
|
'{site_name}' => __('Site name', 'woonoow'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
// ===== NEWSLETTER EVENTS =====
|
// ===== NEWSLETTER EVENTS =====
|
||||||
'newsletter_welcome' => [
|
'newsletter_welcome' => [
|
||||||
|
|||||||
@@ -214,6 +214,43 @@ Got questions? Our customer service team is ready to help: {support_email}
|
|||||||
[/card]';
|
[/card]';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer: Password Reset
|
||||||
|
* Sent when customer requests a password reset
|
||||||
|
*/
|
||||||
|
private static function customer_password_reset()
|
||||||
|
{
|
||||||
|
return '[card type="hero"]
|
||||||
|
## Reset Your Password 🔐
|
||||||
|
|
||||||
|
Hi {customer_name},
|
||||||
|
|
||||||
|
You\'ve requested to reset your password for your {site_name} account.
|
||||||
|
[/card]
|
||||||
|
|
||||||
|
[card type="warning"]
|
||||||
|
**Click the button below to reset your password:**
|
||||||
|
|
||||||
|
[button url="{reset_link}" style="solid"]Reset My Password[/button]
|
||||||
|
|
||||||
|
This link will expire in 24 hours for security reasons.
|
||||||
|
[/card]
|
||||||
|
|
||||||
|
[card type="basic"]
|
||||||
|
**Didn\'t request this?**
|
||||||
|
|
||||||
|
If you didn\'t request a password reset, you can safely ignore this email. Your password will remain unchanged.
|
||||||
|
|
||||||
|
For security, never share this link with anyone.
|
||||||
|
[/card]
|
||||||
|
|
||||||
|
[card type="basic" bg="#f5f5f5"]
|
||||||
|
If the button above doesn\'t work, copy and paste this link into your browser:
|
||||||
|
|
||||||
|
{reset_link}
|
||||||
|
[/card]';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customer: Newsletter Campaign
|
* Customer: Newsletter Campaign
|
||||||
* Master design template for newsletter campaigns
|
* Master design template for newsletter campaigns
|
||||||
|
|||||||
Reference in New Issue
Block a user