verifier = $verifier;
$this->init_hooks();
}
/**
* Initialize all form hooks.
*/
private function init_hooks() {
// Enqueue script
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('login_enqueue_scripts', array($this, 'enqueue_scripts'));
// 1. WordPress Login Form
if ($this->verifier->is_enabled('enable_wp_login')) {
add_action('login_form', array($this, 'render_widget'));
add_filter('authenticate', array($this, 'verify_wp_login'), 30, 3);
}
// 2. WordPress Registration Form
if ($this->verifier->is_enabled('enable_wp_register')) {
add_action('register_form', array($this, 'render_widget'));
add_filter('registration_errors', array($this, 'verify_wp_register'), 10, 3);
}
// 3. WordPress Comments Form
if ($this->verifier->is_enabled('enable_wp_comments')) {
add_action('comment_form_after_fields', array($this, 'render_widget'));
add_action('comment_form_logged_in_after_fields', array($this, 'render_widget'));
add_filter('preprocess_comment', array($this, 'verify_wp_comment'));
}
// 4. WordPress Lost Password Form
if ($this->verifier->is_enabled('enable_wp_lostpassword')) {
add_action('lostpassword_form', array($this, 'render_widget'));
add_action('lostpassword_post', array($this, 'verify_wp_lostpassword'), 10, 1);
}
// 5. WooCommerce Login Form
if ($this->verifier->is_enabled('enable_wc_login')) {
add_action('woocommerce_login_form', array($this, 'render_widget'));
add_filter('woocommerce_process_login_errors', array($this, 'verify_wc_login'), 10, 3);
}
// 6. WooCommerce Register Form
if ($this->verifier->is_enabled('enable_wc_register')) {
add_action('woocommerce_register_form', array($this, 'render_widget'));
add_filter('woocommerce_process_registration_errors', array($this, 'verify_wc_register'), 10, 4);
}
// 7. WooCommerce Lost Password Form
if ($this->verifier->is_enabled('enable_wc_lostpassword')) {
add_action('woocommerce_lostpassword_form', array($this, 'render_widget'));
add_action('woocommerce_lostpassword_post', array($this, 'verify_wc_lostpassword'));
}
// 8. WooCommerce Checkout Form
if ($this->verifier->is_enabled('enable_wc_checkout')) {
add_action('woocommerce_review_order_before_submit', array($this, 'render_widget'));
add_action('woocommerce_checkout_process', array($this, 'verify_wc_checkout'));
}
// 9 & 10. WPForms (Lite & Pro)
if ($this->verifier->is_enabled('enable_wpforms_lite') || $this->verifier->is_enabled('enable_wpforms_pro')) {
add_action('wpforms_display_submit_before', array($this, 'render_widget_wpforms'), 10, 1);
add_action('wpforms_process', array($this, 'verify_wpforms'), 10, 3);
}
}
/**
* Enqueue the Shielda widget script.
*/
public function enqueue_scripts() {
if ($this->script_enqueued) {
return;
}
$site_key = $this->verifier->get_site_key();
if (empty($site_key)) {
return;
}
$script_url = SHIELDA_WIDGET_JS_URL;
wp_enqueue_script(
'shielda-widget',
$script_url,
array(),
SHIELDA_VERSION,
array('strategy' => 'defer', 'in_footer' => false)
);
// Add inline CSS for widget layout
$custom_css = "
.shielda-captcha-wrapper {
margin: 14px 0;
display: flex;
flex-direction: column;
align-items: flex-start;
clear: both;
}
.shielda-captcha-wrapper .darban-captcha {
min-height: 80px;
width: 100%;
max-width: 360px;
}
#loginform .shielda-captcha-wrapper,
#registerform .shielda-captcha-wrapper,
#lostpasswordform .shielda-captcha-wrapper {
margin-bottom: 20px;
}
";
wp_add_inline_style('login', $custom_css);
wp_register_style('shielda-inline-style', false);
wp_enqueue_style('shielda-inline-style');
wp_add_inline_style('shielda-inline-style', $custom_css);
$this->script_enqueued = true;
}
/**
* Render the CAPTCHA widget DOM element.
*/
public function render_widget() {
$site_key = $this->verifier->get_site_key();
if (empty($site_key)) {
return;
}
$this->enqueue_scripts();
echo '
';
}
/**
* Render widget for WPForms.
*
* @param array $form_data
*/
public function render_widget_wpforms($form_data) {
$this->render_widget();
}
/* ── Verification Methods ──────────────────────────────────── */
/**
* Verify WordPress Login.
*
* @param WP_User|WP_Error|null $user
* @param string $username
* @param string $password
* @return WP_User|WP_Error
*/
public function verify_wp_login($user, $username, $password) {
// Skip verification if already an error or if empty credentials (standard WP behavior)
if (empty($username) || empty($password)) {
return $user;
}
// Don't verify if already errored
if (is_wp_error($user) && $user->get_error_code() !== '') {
return $user;
}
$check = $this->verifier->verify();
if (!$check['success']) {
return new WP_Error('shielda_captcha_error', '' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']));
}
return $user;
}
/**
* Verify WordPress Registration.
*
* @param WP_Error $errors
* @param string $sanitized_user_login
* @param string $user_email
* @return WP_Error
*/
public function verify_wp_register($errors, $sanitized_user_login, $user_email) {
$check = $this->verifier->verify();
if (!$check['success']) {
$errors->add('shielda_captcha_error', '' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']));
}
return $errors;
}
/**
* Verify WordPress Comment.
*
* @param array $commentdata
* @return array
*/
public function verify_wp_comment($commentdata) {
// Allow pingbacks / trackbacks without captcha
if (isset($commentdata['comment_type']) && in_array($commentdata['comment_type'], array('pingback', 'trackback'), true)) {
return $commentdata;
}
$check = $this->verifier->verify();
if (!$check['success']) {
wp_die(
'' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']),
esc_html__('بررسی کپچا ناموفق بود', 'shielda-captcha'),
array('back_link' => true)
);
}
return $commentdata;
}
/**
* Verify WordPress Lost Password.
*
* @param WP_Error|null $errors
*/
public function verify_wp_lostpassword($errors) {
$check = $this->verifier->verify();
if (!$check['success']) {
if (is_wp_error($errors)) {
$errors->add('shielda_captcha_error', '' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']));
} else {
wp_die(
'' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']),
esc_html__('بررسی کپچا ناموفق بود', 'shielda-captcha'),
array('back_link' => true)
);
}
}
}
/**
* Verify WooCommerce Login.
*
* @param WP_Error $validation_error
* @param string $username
* @param string $password
* @return WP_Error
*/
public function verify_wc_login($validation_error, $username, $password) {
if (empty($username) || empty($password)) {
return $validation_error;
}
$check = $this->verifier->verify();
if (!$check['success']) {
$validation_error->add('shielda_captcha_error', '' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']));
}
return $validation_error;
}
/**
* Verify WooCommerce Registration.
*
* @param WP_Error $errors
* @param string $username
* @param string $password
* @param string $email
* @return WP_Error
*/
public function verify_wc_register($errors, $username, $password, $email) {
$check = $this->verifier->verify();
if (!$check['success']) {
$errors->add('shielda_captcha_error', '' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']));
}
return $errors;
}
/**
* Verify WooCommerce Lost Password.
*/
public function verify_wc_lostpassword() {
$check = $this->verifier->verify();
if (!$check['success']) {
if (function_exists('wc_add_notice')) {
wc_add_notice('' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']), 'error');
}
}
}
/**
* Verify WooCommerce Checkout.
*/
public function verify_wc_checkout() {
$check = $this->verifier->verify();
if (!$check['success']) {
if (function_exists('wc_add_notice')) {
wc_add_notice('' . esc_html__('خطای امنیتی شیلدا:', 'shielda-captcha') . ' ' . esc_html($check['message']), 'error');
}
}
}
/**
* Verify WPForms submission.
*
* @param array $fields
* @param array $entry
* @param array $form_data
*/
public function verify_wpforms($fields, $entry, $form_data) {
$check = $this->verifier->verify();
if (!$check['success']) {
if (function_exists('wpforms')) {
wpforms()->process->errors[$form_data['id']]['header'] = esc_html($check['message']);
}
}
}
}