
// Thêm vào cuối file functions.php của theme // Tạo AJAX endpoint cho registration (chỉ với email) add_action('wp_ajax_register_email_only', 'handle_email_only_registration'); add_action('wp_ajax_nopriv_register_email_only', 'handle_email_only_registration'); function handle_email_only_registration() { // Kiểm tra nonce để chống CSRF if (!wp_verify_nonce($_POST['nonce'], 'register_email_only_nonce')) { wp_send_json_error('Security check failed.'); return; } // Sanitize và validate input $email = sanitize_email($_POST['email']); // Validation if (!is_email($email)) { wp_send_json_error('Please enter a valid email address.'); return; } if (email_exists($email)) { wp_send_json_error('An account with this email already exists. Please sign in or use a different email.'); return; } // Tạo username từ email (hoặc bạn có thể yêu cầu username riêng) $username = sanitize_user(explode('@', $email)[0]); // Đảm bảo username là duy nhất $original_username = $username; $i = 1; while (username_exists($username)) { $username = $original_username . $i; $i++; } // Tạo mật khẩu ngẫu nhiên (người dùng sẽ đặt lại qua email) $random_password = wp_generate_password(12, true, true); // Tạo user WordPress $user_data = array( 'user_login' => $username, 'user_email' => $email, 'user_pass' => $random_password, 'display_name' => $username, 'role' => 'customer' // Gán vai trò customer cho WooCommerce ); $user_id = wp_insert_user($user_data); if (is_wp_error($user_id)) { wp_send_json_error($user_id->get_error_message()); return; } // Gửi email thông báo và link đặt mật khẩu // 'both' sẽ gửi email cho admin và user // 'user' chỉ gửi cho user wp_new_user_notification($user_id, null, 'user'); // Trả về kết quả thành công wp_send_json_success(array( 'message' => 'Registration successful! A password setup link has been sent to your email address. Please check your inbox to complete registration.', 'user_id' => $user_id )); } // Tạo nonce cho frontend (cho đăng ký email-only) add_action('wp_ajax_get_email_only_nonce', 'get_email_only_nonce'); add_action('wp_ajax_nopriv_get_email_only_nonce', 'get_email_only_nonce'); function get_email_only_nonce() { wp_send_json_success(array( 'nonce' => wp_create_nonce('register_email_only_nonce') )); } // Tạo AJAX endpoint cho yêu cầu Magic Link/OTP add_action('wp_ajax_send_login_otp', 'handle_send_login_otp'); add_action('wp_ajax_nopriv_send_login_otp', 'handle_send_login_otp'); function handle_send_login_otp() { // Kiểm tra nonce để chống CSRF if (!wp_verify_nonce($_POST['nonce'], 'login_otp_nonce')) { wp_send_json_error('Security check failed.'); return; } // Sanitize và validate input $email = sanitize_email($_POST['email']); // Validation if (!is_email($email)) { wp_send_json_error('Please enter a valid email address.'); return; } // Kiểm tra xem email có tồn tại trong hệ thống không $user = get_user_by('email', $email); if (!$user) { // Tránh tiết lộ thông tin user, chỉ báo lỗi chung wp_send_json_error('Could not find an account with that email address. Please check your email or register for a new account.'); return; } // Tạo và gửi Magic Link/OTP // WordPress không có sẵn tính năng "Magic Link" như Supabase [^4]. // Chúng ta sẽ sử dụng tính năng "Password Reset" của WordPress để mô phỏng. // Người dùng sẽ nhận được link đặt lại mật khẩu, nhưng có thể dùng nó để đăng nhập. // Hoặc bạn có thể tích hợp plugin bên thứ 3 cho Magic Link/OTP thật sự. $key = get_password_reset_key($user); if (is_wp_error($key)) { wp_send_json_error('Could not generate login link. Please try again.'); return; } $reset_link = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user->user_login), 'login'); // Gửi email cho người dùng $subject = sprintf(__('[%s] Your Login Link for Omi Dot'), get_bloginfo('name')); $message = sprintf(__('Hello %s,'), $user->display_name) . "\r\n\r\n"; $message .= __('You recently requested a login link for your Omi Dot account. Click the link below to log in:') . "\r\n\r\n"; $message .= $reset_link . "\r\n\r\n"; $message .= __('This link will expire in 24 hours. If you did not request this, please ignore this email.') . "\r\n\r\n"; $message .= sprintf(__('Thank you for using %s.'), get_bloginfo('name')) . "\r\n"; $headers = array('Content-Type: text/plain; charset=UTF-8'); $mail_sent = wp_mail($email, $subject, $message, $headers); if ($mail_sent) { wp_send_json_success(array( 'message' => 'A login link has been sent to your email address. Please check your inbox to continue.' )); } else { wp_send_json_error('Failed to send login link. Please try again later.'); } } // Tạo nonce cho frontend (cho login OTP) add_action('wp_ajax_get_login_otp_nonce', 'get_login_otp_nonce'); add_action('wp_ajax_nopriv_get_login_otp_nonce', 'get_login_otp_nonce'); function get_login_otp_nonce() { wp_send_json_success(array( 'nonce' => wp_create_nonce('login_otp_nonce') )); } // Enqueue script để có thể sử dụng admin-ajax.php // Đảm bảo hàm này chỉ được thêm một lần if (!function_exists('enqueue_register_scripts_omidot')) { add_action('wp_enqueue_scripts', 'enqueue_register_scripts_omidot'); function enqueue_register_scripts_omidot() { // Chỉ load trên trang register hoặc các trang có chứa form này if (is_page('register') || is_page('sign-up') || strpos($_SERVER['REQUEST_URI'], 'register') !== false) { wp_localize_script('jquery', 'ajax_object_omidot', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('register_email_only_nonce') )); } } } if (!function_exists('enqueue_login_scripts_omidot')) { add_action('wp_enqueue_scripts', 'enqueue_login_scripts_omidot'); function enqueue_login_scripts_omidot() { // Chỉ load trên trang login hoặc các trang có chứa form này if (is_page('login') || strpos($_SERVER['REQUEST_URI'], 'login') !== false) { wp_localize_script('jquery', 'ajax_object_login_omidot', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('login_otp_nonce') )); } } } ?>