From cfdcf04c87e0d73fee62af34d5177e1628e81ca7 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Fri, 21 Feb 2025 15:13:47 +0000 Subject: [PATCH 01/24] adCAPTCHA integrated to Gravity form, icon changed, submit working. --- assets/adcaptcha_icon.png | Bin 0 -> 3556 bytes assets/gravity-forms_logo.svg | 1 + src/Instantiate.php | 5 + src/Plugin/GravityForms/Field.php | 147 ++++++++++++++++++++++++++++++ src/Plugin/GravityForms/Forms.php | 39 ++++++++ src/Settings/Plugins.php | 6 ++ 6 files changed, 198 insertions(+) create mode 100644 assets/adcaptcha_icon.png create mode 100644 assets/gravity-forms_logo.svg create mode 100644 src/Plugin/GravityForms/Field.php create mode 100644 src/Plugin/GravityForms/Forms.php diff --git a/assets/adcaptcha_icon.png b/assets/adcaptcha_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..337652fef7583d16e006879a685f2107c04408d4 GIT binary patch literal 3556 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 eU7^Z2tbYL`Ec^C%cU8y$0000 \ No newline at end of file diff --git a/src/Instantiate.php b/src/Instantiate.php index 99b584c..cb4ffca 100644 --- a/src/Instantiate.php +++ b/src/Instantiate.php @@ -17,6 +17,7 @@ use AdCaptcha\Plugin\WPForms\Forms as WPForms; use AdCaptcha\Plugin\Elementor\Forms as Elementor; use AdCaptcha\Plugin\FluentForms\Forms as FluentForms; +use AdCaptcha\Plugin\GravityForms\Forms as GravityForms; class Instantiate { @@ -83,6 +84,10 @@ public function setup() { 'instance' => FluentForms::class, 'plugin' => [ 'fluentform/fluentform.php' ], ], + 'GravityForms_Forms' => [ + 'instance' => GravityForms::class, + 'plugin' => [ 'gravityforms/gravityforms.php' ], + ], ]; $selected_plugins = get_option('adcaptcha_selected_plugins') ? get_option('adcaptcha_selected_plugins') : array(); diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php new file mode 100644 index 0000000..5ce8a82 --- /dev/null +++ b/src/Plugin/GravityForms/Field.php @@ -0,0 +1,147 @@ +verify = new Verify(); + $this->setup(); + } + + private function setup(): void { + error_log('✅ Initializing AdCaptcha Field.'); + + if (!class_exists('GF_Fields')) { + error_log('❌ Gravity Forms not loaded. AdCaptcha registration skipped.'); + return; + } + + if (GF_Fields::get('adcaptcha')) { + error_log('⚠️ AdCaptcha field is already registered. Skipping.'); + return; + } + + try { + if (!GF_Fields::get('adcaptcha')) { + GF_Fields::register($this); + error_log('✅ AdCaptcha field registered.'); + } else { + error_log('⚠️ AdCaptcha field already registered.'); + } + } catch (Exception $e) { + error_log('❌ Error registering AdCaptcha field: ' . $e->getMessage()); + } + + $this->setup_hooks(); + } + + private function setup_hooks(): void { + add_action('wp_enqueue_scripts', [AdCaptcha::class, 'enqueue_scripts'], 9); + add_action( 'wp_enqueue_scripts', [ Verify::class, 'get_success_token' ] ); + add_filter('gform_field_groups_form_editor', [$this, 'add_to_field_groups']); + add_filter('gform_field_content', function ($content, $field) { + if ($field->type === 'adcaptcha') { + return str_replace($field->get_field_label(false, ''), '', $content); + } + return $content; + }, 10, 2); + add_filter('gform_validation', [$this, 'verify_captcha']); + } + + public function get_field_input($form, $value = '', $entry = null) { + $form_id = $form['id']; + $field_id = (int) $this->id; + error_log("ℹ️ Rendering get_field_input() for field ID: {$field_id} in form ID: {$form_id}"); + if ($this->is_form_editor()) { + return "
AdCaptcha will be rendered here.
"; + } + + $captcha_html = AdCaptcha::ob_captcha_trigger(); + $input = "
" . + $captcha_html . + "" . + "
"; + + return $input; + } + + public function get_form_editor_field_title() { + return esc_html__('adCAPTCHA', 'adcaptcha'); + } + + public function get_form_editor_field_settings() { + return [ 'description_setting', 'error_message_setting']; + } + + public function get_form_editor_field_description() { + return esc_attr__( + 'Adds an adCAPTCHA verification field to enhance security and prevent spam submissions on your forms.', + 'adcaptcha-for-forms' + ); + } + + public function get_form_editor_field_icon() { + return plugin_dir_url( __FILE__ ) . '../../../assets/adcaptcha_icon.png'; + } + + public function add_to_field_groups($field_groups): array { + foreach ($field_groups['advanced_fields']['fields'] as $field) { + if ($field['data-type'] === 'adcaptcha') { + return $field_groups; + } + } + + error_log($this->get_form_editor_field_icon()); + $field_groups['advanced_fields']['fields'][] = [ + 'data-type' => $this->type, + 'value' => $this->get_form_editor_field_title(), + 'description' => $this->get_form_editor_field_description(), + 'label' => $this->get_form_editor_field_title(), + 'icon' => $this->get_form_editor_field_icon() + ]; + + return $field_groups; + } + + public function verify_captcha($validation_result) { + error_log('✅ Verifying AdCaptcha field running.'); + $form = $validation_result['form']; + $is_valid = true; + error_log('ℹ️ Verifying AdCaptcha field.' . print_r($form['fields'], true)); + foreach ($form['fields'] as &$field) { + if ($field->type === 'adcaptcha') { + $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'])); + error_log('ℹ️ Verifying AdCaptcha field success token.' . print_r($successToken, true)); + if (!$successToken) { + error_log("❌ AdCaptcha token is missing."); + $field->failed_validation = true; + $field->validation_message = __('Captcha token is missing.', 'adcaptcha'); + $is_valid = false; + } elseif (!$this->verify->verify_token($successToken)) { + error_log("❌ AdCaptcha verification failed."); + $field->failed_validation = true; + $field->validation_message = __('Incomplete captcha, Please try again.', 'adcaptcha'); + $is_valid = false; + } + } + } + + $validation_result['is_valid'] = $is_valid; + $validation_result['form'] = $form; + return $validation_result; + } +} \ No newline at end of file diff --git a/src/Plugin/GravityForms/Forms.php b/src/Plugin/GravityForms/Forms.php new file mode 100644 index 0000000..72671e7 --- /dev/null +++ b/src/Plugin/GravityForms/Forms.php @@ -0,0 +1,39 @@ +register_adcaptcha_field(); + }, 10, 0); + } + + + public function register_adcaptcha_field() { + // error_log( '✅ AdCaptcha field registration is running.' ); + + // if ( class_exists( 'GF_Fields' )) { + // GF_Fields::register( new Field() ); + // } else { + // error_log('❌ Gravity Forms is not loaded yet. AdCaptcha field registration skipped.'); + // } + // } + if (!GF_Fields::get('adcaptcha')) { + new Field(); + } + } +} + diff --git a/src/Settings/Plugins.php b/src/Settings/Plugins.php index ec41a74..8d777f9 100644 --- a/src/Settings/Plugins.php +++ b/src/Settings/Plugins.php @@ -53,6 +53,12 @@ public function render_plugins_settings() { 'options' => array('Forms'), 'message' => '' ), + array( + 'label' => 'GravityForms', + 'logo' => 'gravity-forms_logo.svg', + 'options' => array('Forms'), + 'message' => '' + ), ); $saved_setting = false; From f3b1b0ed9c15c4757e7f00badcac9281dd8ae95a Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Fri, 21 Feb 2025 22:11:31 +0000 Subject: [PATCH 02/24] Fixed label, icon size, error message --- src/Plugin/GravityForms/Field.php | 56 +++++++++++++++++++++---------- src/Plugin/GravityForms/Forms.php | 11 ------ 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 5ce8a82..9fc5c5c 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -4,6 +4,7 @@ use GF_Field; use GF_Fields; +use GFAPI; use AdCaptcha\Widget\AdCaptcha; use AdCaptcha\Widget\Verify; use Exception; @@ -23,22 +24,18 @@ public function __construct($data = []) { } private function setup(): void { - error_log('✅ Initializing AdCaptcha Field.'); if (!class_exists('GF_Fields')) { - error_log('❌ Gravity Forms not loaded. AdCaptcha registration skipped.'); return; } if (GF_Fields::get('adcaptcha')) { - error_log('⚠️ AdCaptcha field is already registered. Skipping.'); return; } try { if (!GF_Fields::get('adcaptcha')) { GF_Fields::register($this); - error_log('✅ AdCaptcha field registered.'); } else { error_log('⚠️ AdCaptcha field already registered.'); } @@ -60,16 +57,18 @@ private function setup_hooks(): void { return $content; }, 10, 2); add_filter('gform_validation', [$this, 'verify_captcha']); + add_action('admin_head', [$this, 'custom_admin_field_icon_style']); + add_action('admin_init', function() { + $this->update_field_label(6, 12); + }); } public function get_field_input($form, $value = '', $entry = null) { $form_id = $form['id']; $field_id = (int) $this->id; - error_log("ℹ️ Rendering get_field_input() for field ID: {$field_id} in form ID: {$form_id}"); if ($this->is_form_editor()) { return "
AdCaptcha will be rendered here.
"; } - $captcha_html = AdCaptcha::ob_captcha_trigger(); $input = "
" . $captcha_html . @@ -79,6 +78,27 @@ public function get_field_input($form, $value = '', $entry = null) { return $input; } + public function update_field_label($form_id, $field_id) { + $form = GFAPI::get_form($form_id); + if (!$form) { + return; + } + foreach ($form['fields'] as &$field) { + if ($field->id == $field_id && $field->type === 'adcaptcha') { + $field->label = __('adCAPTCHA', 'adcaptcha'); + $field['label'] = __('adCAPTCHA', 'adcaptcha'); + $result = GFAPI::update_form($form); + if (is_wp_error($result)) { + error_log("❌ Failed to update form label: " . $result->get_error_message()); + } else { + error_log("✅ Successfully updated adCAPTCHA field label."); + } + return; + } + } + error_log("⚠️ adCAPTCHA field not found in form ID {$form_id}."); + } + public function get_form_editor_field_title() { return esc_html__('adCAPTCHA', 'adcaptcha'); } @@ -87,6 +107,14 @@ public function get_form_editor_field_settings() { return [ 'description_setting', 'error_message_setting']; } + function custom_admin_field_icon_style() { + echo ''; + } + public function get_form_editor_field_description() { return esc_attr__( 'Adds an adCAPTCHA verification field to enhance security and prevent spam submissions on your forms.', @@ -104,37 +132,29 @@ public function add_to_field_groups($field_groups): array { return $field_groups; } } - - error_log($this->get_form_editor_field_icon()); $field_groups['advanced_fields']['fields'][] = [ 'data-type' => $this->type, 'value' => $this->get_form_editor_field_title(), - 'description' => $this->get_form_editor_field_description(), 'label' => $this->get_form_editor_field_title(), - 'icon' => $this->get_form_editor_field_icon() ]; return $field_groups; } public function verify_captcha($validation_result) { - error_log('✅ Verifying AdCaptcha field running.'); $form = $validation_result['form']; $is_valid = true; - error_log('ℹ️ Verifying AdCaptcha field.' . print_r($form['fields'], true)); foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha') { $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'])); - error_log('ℹ️ Verifying AdCaptcha field success token.' . print_r($successToken, true)); - if (!$successToken) { - error_log("❌ AdCaptcha token is missing."); + + if (empty($successToken) || trim($successToken) === '') { $field->failed_validation = true; - $field->validation_message = __('Captcha token is missing.', 'adcaptcha'); + $field->validation_message = __('Incomplete CAPTCHA, Please try again.', 'adcaptcha'); $is_valid = false; } elseif (!$this->verify->verify_token($successToken)) { - error_log("❌ AdCaptcha verification failed."); $field->failed_validation = true; - $field->validation_message = __('Incomplete captcha, Please try again.', 'adcaptcha'); + $field->validation_message = __('Invalid token.', 'adcaptcha'); $is_valid = false; } } diff --git a/src/Plugin/GravityForms/Forms.php b/src/Plugin/GravityForms/Forms.php index 72671e7..88eaecd 100644 --- a/src/Plugin/GravityForms/Forms.php +++ b/src/Plugin/GravityForms/Forms.php @@ -13,24 +13,13 @@ public function __construct() { } public function setup() { - error_log('✅ Gravity Forms setup is running.'); - add_action('gform_loaded', function () { - error_log('✅ gform_loaded fired, registering field now.'); $this->register_adcaptcha_field(); }, 10, 0); } public function register_adcaptcha_field() { - // error_log( '✅ AdCaptcha field registration is running.' ); - - // if ( class_exists( 'GF_Fields' )) { - // GF_Fields::register( new Field() ); - // } else { - // error_log('❌ Gravity Forms is not loaded yet. AdCaptcha field registration skipped.'); - // } - // } if (!GF_Fields::get('adcaptcha')) { new Field(); } From 6f882064387d41cafb67f10cbec63f849ef28ee1 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Mon, 24 Feb 2025 13:27:36 +0000 Subject: [PATCH 03/24] Updated error message label to adcaptcha from Untitled. Updated verify --- src/Plugin/GravityForms/Field.php | 44 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 9fc5c5c..f8cf398 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -58,9 +58,7 @@ private function setup_hooks(): void { }, 10, 2); add_filter('gform_validation', [$this, 'verify_captcha']); add_action('admin_head', [$this, 'custom_admin_field_icon_style']); - add_action('admin_init', function() { - $this->update_field_label(6, 12); - }); + add_action('admin_init', [$this, 'update_adcaptcha_label']); } public function get_field_input($form, $value = '', $entry = null) { @@ -78,25 +76,26 @@ public function get_field_input($form, $value = '', $entry = null) { return $input; } - public function update_field_label($form_id, $field_id) { - $form = GFAPI::get_form($form_id); - if (!$form) { + public function update_adcaptcha_label() { + $forms = GFAPI::get_forms(); + if (!$forms || !is_array($forms)) { return; } - foreach ($form['fields'] as &$field) { - if ($field->id == $field_id && $field->type === 'adcaptcha') { - $field->label = __('adCAPTCHA', 'adcaptcha'); - $field['label'] = __('adCAPTCHA', 'adcaptcha'); - $result = GFAPI::update_form($form); - if (is_wp_error($result)) { - error_log("❌ Failed to update form label: " . $result->get_error_message()); - } else { - error_log("✅ Successfully updated adCAPTCHA field label."); + foreach ($forms as $form) { + foreach ($form['fields'] as &$field) { + if ($field->type === 'adcaptcha') { + $field->label = __('adCAPTCHA', 'adcaptcha'); + $field['label'] = __('adCAPTCHA', 'adcaptcha'); + $result = GFAPI::update_form($form); + if (is_wp_error($result)) { + error_log("❌ Failed to update adCAPTCHA label in Form ID {$form['id']}: " . $result->get_error_message()); + } else { + error_log("✅ Successfully updated adCAPTCHA label in Form ID {$form['id']}."); + } + return; } - return; } } - error_log("⚠️ adCAPTCHA field not found in form ID {$form_id}."); } public function get_form_editor_field_title() { @@ -104,7 +103,7 @@ public function get_form_editor_field_title() { } public function get_form_editor_field_settings() { - return [ 'description_setting', 'error_message_setting']; + return [ 'description_setting', 'error_message_setting', 'label setting']; } function custom_admin_field_icon_style() { @@ -143,11 +142,11 @@ public function add_to_field_groups($field_groups): array { public function verify_captcha($validation_result) { $form = $validation_result['form']; - $is_valid = true; + $is_valid = $validation_result['is_valid']; foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha') { - $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'])); - + $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); + if (empty($successToken) || trim($successToken) === '') { $field->failed_validation = true; $field->validation_message = __('Incomplete CAPTCHA, Please try again.', 'adcaptcha'); @@ -159,8 +158,7 @@ public function verify_captcha($validation_result) { } } } - - $validation_result['is_valid'] = $is_valid; + $validation_result['is_valid'] = $is_valid; $validation_result['form'] = $form; return $validation_result; } From f818a23b5c16e2cf9100b8b3119638704682a1e9 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Mon, 24 Feb 2025 14:18:52 +0000 Subject: [PATCH 04/24] Remove label settings. --- src/Plugin/GravityForms/Field.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index f8cf398..96d21ea 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -103,7 +103,7 @@ public function get_form_editor_field_title() { } public function get_form_editor_field_settings() { - return [ 'description_setting', 'error_message_setting', 'label setting']; + return [ 'description_setting', 'error_message_setting']; } function custom_admin_field_icon_style() { From a8103a47ea66ef637ee4fbf0cbb67a2251cdd2e8 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Tue, 25 Feb 2025 10:42:25 +0000 Subject: [PATCH 05/24] Stop duplicated adcaptcha on the form field is done. --- src/Plugin/GravityForms/Field.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 96d21ea..c6c11a5 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -59,6 +59,7 @@ private function setup_hooks(): void { add_filter('gform_validation', [$this, 'verify_captcha']); add_action('admin_head', [$this, 'custom_admin_field_icon_style']); add_action('admin_init', [$this, 'update_adcaptcha_label']); + add_action('admin_footer', [$this, 'enqueue_admin_script']); } public function get_field_input($form, $value = '', $entry = null) { @@ -140,6 +141,28 @@ public function add_to_field_groups($field_groups): array { return $field_groups; } + public function enqueue_admin_script() { + ?> + + Date: Tue, 25 Feb 2025 12:10:10 +0000 Subject: [PATCH 06/24] Updated and removed duplicated hidden field to store success token --- src/Plugin/GravityForms/Field.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index c6c11a5..415d452 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -70,9 +70,16 @@ public function get_field_input($form, $value = '', $entry = null) { } $captcha_html = AdCaptcha::ob_captcha_trigger(); $input = "
" . - $captcha_html . - "" . - "
"; + $captcha_html . + "
"; + $input .= ""; return $input; } @@ -104,7 +111,7 @@ public function get_form_editor_field_title() { } public function get_form_editor_field_settings() { - return [ 'description_setting', 'error_message_setting']; + return [ 'description_setting', 'error_message_setting', 'label_placement_setting', 'css_class_setting',]; } function custom_admin_field_icon_style() { From 7b22242e120bfcd57a418f576fae97577fbd6d3c Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Wed, 26 Feb 2025 11:02:14 +0000 Subject: [PATCH 07/24] Gravity form integration done with fixed bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing Gravity Forms re-render issue where the adCAPTCHA widget was being reloaded. The preview page was initially blank, so a div was inserted to indicate “adCAPTCHA will be rendered here”, ensuring visibility during form previews. Check, if there is any security issue regarding how I worked around to keep the adCAPTCHA state success. --- src/Plugin/GravityForms/Field.php | 53 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 415d452..0d7c0d6 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -60,13 +60,46 @@ private function setup_hooks(): void { add_action('admin_head', [$this, 'custom_admin_field_icon_style']); add_action('admin_init', [$this, 'update_adcaptcha_label']); add_action('admin_footer', [$this, 'enqueue_admin_script']); + add_filter('gform_pre_render', function($form) { + if (!empty($_POST['adcaptcha_successToken'])) { + echo ""; + } + return $form; + }); + add_action('gform_preview_body_open', [$this, 'enqueue_preview_scripts']); + } + + public function enqueue_preview_scripts($form_id) { + echo ""; } public function get_field_input($form, $value = '', $entry = null) { $form_id = $form['id']; $field_id = (int) $this->id; if ($this->is_form_editor()) { - return "
AdCaptcha will be rendered here.
"; + return "
adCAPTCHA will be rendered here.
"; } $captcha_html = AdCaptcha::ob_captcha_trigger(); $input = "
" . @@ -175,18 +208,22 @@ public function verify_captcha($validation_result) { $is_valid = $validation_result['is_valid']; foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha') { + error_log(print_r($field, true)); $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); - if (empty($successToken) || trim($successToken) === '') { $field->failed_validation = true; $field->validation_message = __('Incomplete CAPTCHA, Please try again.', 'adcaptcha'); $is_valid = false; - } elseif (!$this->verify->verify_token($successToken)) { - $field->failed_validation = true; - $field->validation_message = __('Invalid token.', 'adcaptcha'); - $is_valid = false; - } - } + } + if($is_valid) { + $response = $this->verify->verify_token($successToken); + if (!$response) { + $field->failed_validation = true; + $field->validation_message = __('Invalid token.', 'adcaptcha'); + $is_valid = false; + } + } + } } $validation_result['is_valid'] = $is_valid; $validation_result['form'] = $form; From 7d2e03c386de4b1abe0918603cce849ec2f47f64 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Wed, 26 Feb 2025 11:08:07 +0000 Subject: [PATCH 08/24] removed error_log --- src/Plugin/GravityForms/Field.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 0d7c0d6..48b4ddc 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -208,7 +208,6 @@ public function verify_captcha($validation_result) { $is_valid = $validation_result['is_valid']; foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha') { - error_log(print_r($field, true)); $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); if (empty($successToken) || trim($successToken) === '') { $field->failed_validation = true; From 2c32028f5615937bc235d24fb51275f091854978 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 27 Feb 2025 16:44:30 +0000 Subject: [PATCH 09/24] By default adCAPTCHA is in the form and working. --- assets/forminator.png | Bin 0 -> 2030 bytes assets/forminator3.jpeg | Bin 0 -> 11094 bytes src/Instantiate.php | 5 ++ src/Plugin/Forminator/Forms.php | 88 ++++++++++++++++++++++++++++++++ src/Settings/Plugins.php | 6 +++ 5 files changed, 99 insertions(+) create mode 100644 assets/forminator.png create mode 100644 assets/forminator3.jpeg create mode 100644 src/Plugin/Forminator/Forms.php diff --git a/assets/forminator.png b/assets/forminator.png new file mode 100644 index 0000000000000000000000000000000000000000..c8c2c1add30832c6d1136f0aa46aee1af9249ee4 GIT binary patch literal 2030 zcmYLK3pCW}8~%PX7^Bg}rQH1@bHUVTGPz_ZLMFo z-PNEh(Z(nd?Ia{hY1~qj%M{vj*rXh)`M`R#5QZgX? zC&H$P0jath5}1ZRL|qfa;|`OU2nRkmEUHYfR@%S zPd{XGP<~NW?cLT$-g*26Ph{Vi4!3Y*b2Bc})g8Qn8&(SWg_ATEO;E_EBot1zCs6#$ zIpOUr4kO&Zox!N!lvDPyGBd66$A|zZ#nByhc<>GkKaY2PK*1?aS-V_tDD(DuQ7p$$ zs){6`{RzSzq$D_^03zT!Rt2`%GY08FQ@7cIWut z>t2M?rInh#i5}giABQ}C8VKmAf{c~BD|KsCt2ZZQ{khnY>(+FEWz^I%?rA9Ojgi%@ zR$u4YmL!GLHRqRVSbl+>i?xdTAG41o#wHJjBtC{LDqD~6+$hHKpp=oL#QSky7F->wYCO;!?{cXKdmt#PeN#O7^Yr<$++lcc!n@mA25y_|n54=tp=2Sns(8b5~? zETR;-%imf+`Go6#t13G_(G=~^!!mR`6-2x&@Dis?Osj7!E<3p+FI@~=Yetn`p`Y!R z9Mqfq@LKBHN7G0-IEwjG)2%ovx$bvoY?hvScCo(%+i2e$`VwbZzjT#!)_K3V+7f4z zJ^RUB_NPa@W~bDly@4dK(c2~79_1HV!)5T)XLi>DjP_T7 z(P!YQlSkM!l?~0#e(m%PsHP#vLpK3cbXr68S0ba+>rB`SDXt5+1G-p1z78hlP2 zdw4f0fpIUyj=z3{#wgl3u%5=(QOxmdba#o)3rHU2DOhAm_-ZuaPRDJ}cCE~CP!7Kz z@-7C&apJ8pI9fNddf9kUn94pE`R-a^5BR*K5UYB8s!z%Di{>7>un^xpUa%u^Hv zpb<<_`J)hZh3o`qNAnCMpFjcT|I&BE4=mOG<;Fjrbk8L48x){tUab$?(YHjQ&nY;o zMgD=@BDq2bb__1+2IDo;3UO9S0(#Cm@|Pv(j0%Gpw3Sw^VJ+}FQjI=zRC_YCuJwZw zaqkLAS|1n{qvN=Gd?@C?n^3+jId z);x)L4+G;TtiiUn!y%+9%NxGcR$OhFT$?pzh&r7U8{NnK z`AC%}1LBe{i8F*Zx4!P&*LGGC9%QY1i3y;C{Mkt-)c&E*I;*FX^vU4_zHIcAN zn@hP8{#Z`E?9%;wAUsY0qG2q+Pbh#lc~8_&vLCj_?VDfQC6+V>wacKiSO7|N!PqKm zm??*V&HxbfqpoS~3QyEdVBeonN&VgZOQNTVSXIk=;3dDqc@~$U<_V0{#lYdh2c?XH zR#zc$l{x6Ngj2S-4fyaonDeX1yxWtD{0!ciJ+tW4O(zy;_;SNX!!zhB!jtEhQ;k_) zbuSt(zA!pDcc>8~;=F1ozdamH*0wd>-t=|oT%w2XY5c9}%#6Y4(lRaUGcwklvVD&_ z4G&M-xZPR{x9zaN<&dq3iv*WLBTl(0p0mdHq_(4s$0y)f2GCucv%Gm17QCF94ssxJRBSx zJOcbH5D*dm0uc%EA0Yh;DE|QUFVO!3nAh>I1A(u9bYw*2|MdSqH(q)HAS8f4%orRD z1ppQV0|$b6=?CxtU|v~+gZazszkrN_i1f-J5cY2;48ngCUg-!hu<$@cxR(_G8rj&LmaLN`UuG8D$NTqC3j~*JY>w`)QOAlQ*Awk62-R z1??}kQ+>ZMQ&SVKUl`YUnye}NWokuDqcZkiO)z@I1c8#AKNXrgxGvviH|=6?@iIw2 z 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 literal 0 HcmV?d00001 diff --git a/src/Instantiate.php b/src/Instantiate.php index 99b584c..2f70f52 100644 --- a/src/Instantiate.php +++ b/src/Instantiate.php @@ -17,6 +17,7 @@ use AdCaptcha\Plugin\WPForms\Forms as WPForms; use AdCaptcha\Plugin\Elementor\Forms as Elementor; use AdCaptcha\Plugin\FluentForms\Forms as FluentForms; +use AdCaptcha\Plugin\Forminator\Forms as Forminator; class Instantiate { @@ -83,6 +84,10 @@ public function setup() { 'instance' => FluentForms::class, 'plugin' => [ 'fluentform/fluentform.php' ], ], + 'Forminator_Forms' => [ + 'instance' => Forminator::class, + 'plugin' => [ 'forminator/forminator.php' ], + ], ]; $selected_plugins = get_option('adcaptcha_selected_plugins') ? get_option('adcaptcha_selected_plugins') : array(); diff --git a/src/Plugin/Forminator/Forms.php b/src/Plugin/Forminator/Forms.php new file mode 100644 index 0000000..0832a22 --- /dev/null +++ b/src/Plugin/Forminator/Forms.php @@ -0,0 +1,88 @@ +verify = new Verify(); + } + + public function setup() { + add_action('forminator_before_form_render', [$this, 'before_form_render'], 10, 5); + add_action('forminator_before_form_render', [AdCaptcha::class, 'enqueue_scripts']); + add_action('forminator_before_form_render', [Verify::class, 'get_success_token']); + + add_filter('forminator_render_button_markup', [$this, 'captcha_trigger_filter'], 10, 2); + add_filter('forminator_cform_form_is_submittable', [$this, 'verify'], 10, 3); + add_filter('forminator_custom_form_fields', [$this, 'register_adcaptcha_field']); + } + + public function before_form_render($id, $form_type, $post_id, $form_fields, $form_settings) { + $this->has_captcha = $this->has_adcaptcha_field($form_fields); + } + + public function register_adcaptcha_field($fields) { + $fields['adcaptcha'] = [ + 'field' => 'AdCaptcha', + 'icon' => 'dashicons-shield', + 'position' => 'basic', + 'class' => 'forminator-custom-adcaptcha', + 'template' => 'adcaptcha', + 'settings' => [$this, 'adcaptcha_settings_template'], + ]; + return $fields; + } + + public function verify($can_show, $form_id, $field_data_array) { + if ($this->verified) { + error_log('[AdCaptcha] Already verified.'); + return $can_show; + } + + $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); + if (empty($successToken)) { + error_log('[AdCaptcha] No token received.'); + return [ + 'can_submit' => false, + 'error' => __('Please complete the AdCaptcha verification.', 'adcaptcha'), + ]; + } + $response = $this->verify->verify_token($successToken); + if (!$response) { + error_log('[AdCaptcha] Verification failed.'); + return [ + 'can_submit' => false, + 'error' => __('AdCaptcha verification failed. Please try again.', 'adcaptcha'), + ]; + } + + $this->verified = true; + return $can_show; + } + + public function captcha_trigger_filter($html, string $button) { + if ($this->has_captcha) { + return $html; + } + + return AdCaptcha::ob_captcha_trigger() . $html; + } + + private function has_adcaptcha_field($form_fields) { + foreach ($form_fields as $field) { + if (!empty($field['type']) && $field['type'] === 'captcha' && !empty($field['captcha_provider']) && $field['captcha_provider'] === 'adcaptcha') { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/src/Settings/Plugins.php b/src/Settings/Plugins.php index ec41a74..3e000b9 100644 --- a/src/Settings/Plugins.php +++ b/src/Settings/Plugins.php @@ -53,6 +53,12 @@ public function render_plugins_settings() { 'options' => array('Forms'), 'message' => '' ), + array( + 'label' => 'Forminator', + 'logo' => 'forminator3.jpeg', + 'options' => array('Forms'), + 'message' => '' + ) ); $saved_setting = false; From 144140d953da8aef6fa4c5b23972f04b48223977 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Mon, 3 Mar 2025 14:44:26 +0000 Subject: [PATCH 10/24] Forminator automatic integration is done --- src/Plugin/Forminator/Forms.php | 71 ++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/src/Plugin/Forminator/Forms.php b/src/Plugin/Forminator/Forms.php index 0832a22..aa21967 100644 --- a/src/Plugin/Forminator/Forms.php +++ b/src/Plugin/Forminator/Forms.php @@ -18,28 +18,52 @@ public function __construct() { public function setup() { add_action('forminator_before_form_render', [$this, 'before_form_render'], 10, 5); - add_action('forminator_before_form_render', [AdCaptcha::class, 'enqueue_scripts']); - add_action('forminator_before_form_render', [Verify::class, 'get_success_token']); - + add_action('forminator_before_form_render', [AdCaptcha::class, 'enqueue_scripts'], 9); + add_action('forminator_before_form_render', [Verify::class, 'get_success_token'], 9); add_filter('forminator_render_button_markup', [$this, 'captcha_trigger_filter'], 10, 2); + add_action( 'wp_enqueue_scripts', [ $this, 'reset_captcha_script' ], 9 ); add_filter('forminator_cform_form_is_submittable', [$this, 'verify'], 10, 3); - add_filter('forminator_custom_form_fields', [$this, 'register_adcaptcha_field']); } public function before_form_render($id, $form_type, $post_id, $form_fields, $form_settings) { $this->has_captcha = $this->has_adcaptcha_field($form_fields); } - public function register_adcaptcha_field($fields) { - $fields['adcaptcha'] = [ - 'field' => 'AdCaptcha', - 'icon' => 'dashicons-shield', - 'position' => 'basic', - 'class' => 'forminator-custom-adcaptcha', - 'template' => 'adcaptcha', - 'settings' => [$this, 'adcaptcha_settings_template'], - ]; - return $fields; + private function has_adcaptcha_field($form_fields) { + foreach ($form_fields as $field) { + if (!empty($field['type']) && $field['type'] === 'captcha' && !empty($field['captcha_provider']) && $field['captcha_provider'] === 'adcaptcha') { + return true; + } + } + return false; + } + + public function captcha_trigger_filter($html, string $button) { + if ($this->has_captcha) { + return $html; + } + return AdCaptcha::ob_captcha_trigger() . $html; + } + + + public function reset_captcha_script() { + add_action('wp_footer', function() { + echo ""; + }); } public function verify($can_show, $form_id, $field_data_array) { @@ -68,21 +92,4 @@ public function verify($can_show, $form_id, $field_data_array) { $this->verified = true; return $can_show; } - - public function captcha_trigger_filter($html, string $button) { - if ($this->has_captcha) { - return $html; - } - - return AdCaptcha::ob_captcha_trigger() . $html; - } - - private function has_adcaptcha_field($form_fields) { - foreach ($form_fields as $field) { - if (!empty($field['type']) && $field['type'] === 'captcha' && !empty($field['captcha_provider']) && $field['captcha_provider'] === 'adcaptcha') { - return true; - } - } - return false; - } -} \ No newline at end of file +} From 76db999eef2f45afd2e34fbfb818a1549af01ef5 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Tue, 4 Mar 2025 11:39:52 +0000 Subject: [PATCH 11/24] Fixed comment from PR. For readability, place functions in order. --- src/Plugin/GravityForms/Field.php | 252 ++++++++++++++++-------------- 1 file changed, 131 insertions(+), 121 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 48b4ddc..09acbf8 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -36,11 +36,9 @@ private function setup(): void { try { if (!GF_Fields::get('adcaptcha')) { GF_Fields::register($this); - } else { - error_log('⚠️ AdCaptcha field already registered.'); - } + } } catch (Exception $e) { - error_log('❌ Error registering AdCaptcha field: ' . $e->getMessage()); + throw $e; } $this->setup_hooks(); @@ -50,37 +48,142 @@ private function setup_hooks(): void { add_action('wp_enqueue_scripts', [AdCaptcha::class, 'enqueue_scripts'], 9); add_action( 'wp_enqueue_scripts', [ Verify::class, 'get_success_token' ] ); add_filter('gform_field_groups_form_editor', [$this, 'add_to_field_groups']); - add_filter('gform_field_content', function ($content, $field) { - if ($field->type === 'adcaptcha') { - return str_replace($field->get_field_label(false, ''), '', $content); - } - return $content; - }, 10, 2); + add_filter('gform_field_content', [$this, 'modify_gform_field_content'], 10, 2); add_filter('gform_validation', [$this, 'verify_captcha']); add_action('admin_head', [$this, 'custom_admin_field_icon_style']); add_action('admin_init', [$this, 'update_adcaptcha_label']); add_action('admin_footer', [$this, 'enqueue_admin_script']); - add_filter('gform_pre_render', function($form) { - if (!empty($_POST['adcaptcha_successToken'])) { - echo ""; - } - return $form; - }); + add_filter('gform_pre_render', [$this, 'handle_adcaptcha_token']); add_action('gform_preview_body_open', [$this, 'enqueue_preview_scripts']); } + public function add_to_field_groups($field_groups): array { + foreach ($field_groups['advanced_fields']['fields'] as $field) { + if ($field['data-type'] === 'adcaptcha') { + return $field_groups; + } + } + $field_groups['advanced_fields']['fields'][] = [ + 'data-type' => $this->type, + 'value' => $this->get_form_editor_field_title(), + 'label' => $this->get_form_editor_field_title(), + ]; + + return $field_groups; + } + + public function modify_gform_field_content($content, $field) { + if ($field->type === 'adcaptcha') { + return str_replace($field->get_field_label(false, ''), '', $content); + } + return $content; + } + + public function verify_captcha($validation_result) { + $form = $validation_result['form']; + $is_valid = $validation_result['is_valid']; + foreach ($form['fields'] as &$field) { + if ($field->type === 'adcaptcha') { + $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); + if (empty($successToken) || trim($successToken) === '') { + $field->failed_validation = true; + $field->validation_message = __('Incomplete CAPTCHA, Please try again.', 'adcaptcha'); + $is_valid = false; + } + if($is_valid) { + $response = $this->verify->verify_token($successToken); + if (!$response) { + $field->failed_validation = true; + $field->validation_message = __('Invalid token.', 'adcaptcha'); + $is_valid = false; + } + } + } + } + $validation_result['is_valid'] = $is_valid; + $validation_result['form'] = $form; + return $validation_result; + } + + public function custom_admin_field_icon_style() { + echo ''; + } + + public function update_adcaptcha_label() { + $forms = GFAPI::get_forms(); + if (!$forms || !is_array($forms)) { + return; + } + $errors = []; + foreach ($forms as $form) { + $updated = false; + foreach ($form['fields'] as &$field) { + if ($field->type === 'adcaptcha' && $field->label !== __('adCAPTCHA', 'adcaptcha')) { + $field->label = __('adCAPTCHA', 'adcaptcha'); + $field['label'] = __('adCAPTCHA', 'adcaptcha'); + $updated = true; + } + } + if ($updated) { + $result = GFAPI::update_form($form); + + if (is_wp_error($result)) { + $errors[] = "Failed to update adCAPTCHA label in Form ID {$form['id']}: " . $result->get_error_message(); + } + } + } + if (!empty($errors)) { + throw new Exception(implode("\n", $errors)); + } + } + + public function enqueue_admin_script() { + ?> + + + document.addEventListener('DOMContentLoaded', function() { + let adCaptchaField = document.querySelector('.adcaptcha_successToken'); + if (adCaptchaField) { + setTimeout(function() { + if (window.adcap) { + window.adcap.setVerificationState('success'); + adCaptchaField.value = '{$successToken}'; + } + }, 500); + } + }); + "; + } + return $form; + } + public function enqueue_preview_scripts($form_id) { echo " - type === 'adcaptcha') { - $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); - if (empty($successToken) || trim($successToken) === '') { - $field->failed_validation = true; - $field->validation_message = __('Incomplete CAPTCHA, Please try again.', 'adcaptcha'); - $is_valid = false; - } - if($is_valid) { - $response = $this->verify->verify_token($successToken); - if (!$response) { - $field->failed_validation = true; - $field->validation_message = __('Invalid token.', 'adcaptcha'); - $is_valid = false; - } - } - } - } - $validation_result['is_valid'] = $is_valid; - $validation_result['form'] = $form; - return $validation_result; - } } From 755d78540d9493e5c8d8e599f19f8bbdf8d367f5 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Tue, 4 Mar 2025 12:28:40 +0000 Subject: [PATCH 12/24] PR comments updated --- assets/{forminator3.jpeg => forminator.jpeg} | Bin assets/forminator.png | Bin 2030 -> 0 bytes src/Plugin/Forminator/Forms.php | 10 ---------- src/Settings/Plugins.php | 2 +- 4 files changed, 1 insertion(+), 11 deletions(-) rename assets/{forminator3.jpeg => forminator.jpeg} (100%) delete mode 100644 assets/forminator.png diff --git a/assets/forminator3.jpeg b/assets/forminator.jpeg similarity index 100% rename from assets/forminator3.jpeg rename to assets/forminator.jpeg diff --git a/assets/forminator.png b/assets/forminator.png deleted file mode 100644 index c8c2c1add30832c6d1136f0aa46aee1af9249ee4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2030 zcmYLK3pCW}8~%PX7^Bg}rQH1@bHUVTGPz_ZLMFo z-PNEh(Z(nd?Ia{hY1~qj%M{vj*rXh)`M`R#5QZgX? zC&H$P0jath5}1ZRL|qfa;|`OU2nRkmEUHYfR@%S zPd{XGP<~NW?cLT$-g*26Ph{Vi4!3Y*b2Bc})g8Qn8&(SWg_ATEO;E_EBot1zCs6#$ zIpOUr4kO&Zox!N!lvDPyGBd66$A|zZ#nByhc<>GkKaY2PK*1?aS-V_tDD(DuQ7p$$ zs){6`{RzSzq$D_^03zT!Rt2`%GY08FQ@7cIWut z>t2M?rInh#i5}giABQ}C8VKmAf{c~BD|KsCt2ZZQ{khnY>(+FEWz^I%?rA9Ojgi%@ zR$u4YmL!GLHRqRVSbl+>i?xdTAG41o#wHJjBtC{LDqD~6+$hHKpp=oL#QSky7F->wYCO;!?{cXKdmt#PeN#O7^Yr<$++lcc!n@mA25y_|n54=tp=2Sns(8b5~? zETR;-%imf+`Go6#t13G_(G=~^!!mR`6-2x&@Dis?Osj7!E<3p+FI@~=Yetn`p`Y!R z9Mqfq@LKBHN7G0-IEwjG)2%ovx$bvoY?hvScCo(%+i2e$`VwbZzjT#!)_K3V+7f4z zJ^RUB_NPa@W~bDly@4dK(c2~79_1HV!)5T)XLi>DjP_T7 z(P!YQlSkM!l?~0#e(m%PsHP#
vLpK3cbXr68S0ba+>rB`SDXt5+1G-p1z78hlP2 zdw4f0fpIUyj=z3{#wgl3u%5=(QOxmdba#o)3rHU2DOhAm_-ZuaPRDJ}cCE~CP!7Kz z@-7C&apJ8pI9fNddf9kUn94pE`R-a^5BR*K5UYB8s!z%Di{>7>un^xpUa%u^Hv zpb<<_`J)hZh3o`qNAnCMpFjcT|I&BE4=mOG<;Fjrbk8L48x){tUab$?(YHjQ&nY;o zMgD=@BDq2bb__1+2IDo;3UO9S0(#Cm@|Pv(j0%Gpw3Sw^VJ+}FQjI=zRC_YCuJwZw zaqkLAS|1n{qvN=Gd?@C?n^3+jId z);x)L4+G;TtiiUn!y%+9%NxGcR$OhFT$?pzh&r7U8{NnK z`AC%}1LBe{i8F*Zx4!P&*LGGC9%QY1i3y;C{Mkt-)c&E*I;*FX^vU4_zHIcAN zn@hP8{#Z`E?9%;wAUsY0qG2q+Pbh#lc~8_&vLCj_?VDfQC6+V>wacKiSO7|N!PqKm zm??*V&HxbfqpoS~3QyEdVBeonN&VgZOQNTVSXIk=;3dDqc@~$U<_V0{#lYdh2c?XH zR#zc$l{x6Ngj2S-4fyaonDeX1yxWtD{0!ciJ+tW4O(zy;_;SNX!!zhB!jtEhQ;k_) zbuSt(zA!pDcc>8~;=F1ozdamH*0wd>-t=|oT%w2XY5c9}%#6Y4(lRaUGcwklvVD&_ z4G&M-xZPR{x9zaN<&dq3iv*WLBTl(0p0mdHq_(4s$0y)f2verified) { - error_log('[AdCaptcha] Already verified.'); - return $can_show; - } - $successToken = sanitize_text_field(wp_unslash($_POST['adcaptcha_successToken'] ?? '')); if (empty($successToken)) { - error_log('[AdCaptcha] No token received.'); return [ 'can_submit' => false, 'error' => __('Please complete the AdCaptcha verification.', 'adcaptcha'), @@ -82,14 +75,11 @@ public function verify($can_show, $form_id, $field_data_array) { } $response = $this->verify->verify_token($successToken); if (!$response) { - error_log('[AdCaptcha] Verification failed.'); return [ 'can_submit' => false, 'error' => __('AdCaptcha verification failed. Please try again.', 'adcaptcha'), ]; } - - $this->verified = true; return $can_show; } } diff --git a/src/Settings/Plugins.php b/src/Settings/Plugins.php index 3e000b9..00e008a 100644 --- a/src/Settings/Plugins.php +++ b/src/Settings/Plugins.php @@ -55,7 +55,7 @@ public function render_plugins_settings() { ), array( 'label' => 'Forminator', - 'logo' => 'forminator3.jpeg', + 'logo' => 'forminator.jpeg', 'options' => array('Forms'), 'message' => '' ) From a6e821ed57646f499b176c1b53ad39f5d4c518c9 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Wed, 5 Mar 2025 09:13:39 +0000 Subject: [PATCH 13/24] Forminator testing done --- tests/Plugin/Forminator/ForminatorTest.php | 234 +++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 tests/Plugin/Forminator/ForminatorTest.php diff --git a/tests/Plugin/Forminator/ForminatorTest.php b/tests/Plugin/Forminator/ForminatorTest.php new file mode 100644 index 0000000..5970bec --- /dev/null +++ b/tests/Plugin/Forminator/ForminatorTest.php @@ -0,0 +1,234 @@ +alias(function ($text) { + return $text; + }); + Functions\when('get_option')->alias(function ($option_name) { + $mock_values = [ + 'adcaptcha_placement_id' => 'mocked-placement-id', + ]; + return $mock_values[$option_name] ?? null; + }); + Functions\when('sanitize_text_field')->alias(function($input) { + $sanitized = strip_tags($input); + $sanitized = preg_replace('/[\r\n\t]/', ' ', $sanitized); + $sanitized = trim($sanitized); + return $sanitized; + }); + Functions\when('__')->alias(function ($text, $domain = null) { + return $text; + }); + + $this->forms = new Forms(); + + $this->verifyMock = $this->createMock(Verify::class); + $reflection = new \ReflectionClass($this->forms); + $property = $reflection->getProperty('verify'); + $property->setAccessible(true); + $property->setValue($this->forms, $this->verifyMock); + } + + public function tearDown(): void { + global $mocked_filters; + $mocked_filters = []; + Mockery::close(); + Monkey\tearDown(); + parent::tearDown(); + } + + // Test method that verifies the existence of the 'setup' method and checks that specific WordPress hooks are properly registered with the expected callbacks and priorities. + public function testSetup() { + $this->assertTrue(method_exists($this->forms, 'setup'), 'Method setup does not exist'); + global $mocked_actions, $mocked_filters; + $this->assertContains( + ['hook' => 'forminator_before_form_render', 'callback' => [$this->forms, 'before_form_render'], 'priority' => 10, 'accepted_args' => 5], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'forminator_before_form_render', 'callback' => [AdCaptcha::class, 'enqueue_scripts'], 'priority' => 9, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'forminator_before_form_render', 'callback' => [Verify::class, 'get_success_token'], 'priority' => 9, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'wp_enqueue_scripts', 'callback' => [$this->forms, 'reset_captcha_script'], 'priority' => 9, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'forminator_render_button_markup', 'callback' => [$this->forms, 'captcha_trigger_filter'], 'priority' => 10, 'accepted_args' => 2], + $mocked_filters + ); + $this->assertContains( + ['hook' => 'forminator_cform_form_is_submittable', 'callback' => [$this->forms, 'verify'], 'priority' => 10, 'accepted_args' => 3], + $mocked_filters + ); + } + + // Tests if 'beforeFormRender' sets 'has_captcha' to true for 'adcaptcha' and false otherwise. + public function testBeforeFormRender() { + $reflection = new \ReflectionClass($this->forms); + $property = $reflection->getProperty('has_captcha'); + $property->setAccessible(true); + + $this->forms->before_form_render(1, 'contact_form', 123, [ + ['type' => 'captcha', 'captcha_provider' => 'adcaptcha'] + ], []); + $this->assertTrue($property->getValue($this->forms), "Expected has_captcha to be true"); + $this->forms->before_form_render(1, 'contact_form', 123, [ + ['type' => 'captcha', 'captcha_provider' => 'nocaptcha'] + ], []); + $this->assertFalse($property->getValue($this->forms), "Expected has_captcha to be false"); + } + + // Tests if 'hasAdcaptchaField' correctly identifies the presence of an 'adcaptcha' field in various form field scenarios. + public function testHasAdcaptchaField() { + $this->assertTrue(method_exists($this->forms, 'has_adcaptcha_field'), 'Method has_adcaptcha_field does not exist'); + + $reflection = new \ReflectionClass($this->forms); + $method = $reflection->getMethod('has_adcaptcha_field'); + $method->setAccessible(true); + + $testCases = [ + 'Valid adCaptcha field' => [ + 'input' => [['type' => 'captcha', 'captcha_provider' => 'adcaptcha']], + 'expected' => true + ], + 'Different captcha provider' => [ + 'input' => [['type' => 'captcha', 'captcha_provider' => 'nocaptcha']], + 'expected' => false + ], + 'Missing captcha provider' => [ + 'input' => [['type' => 'captcha']], + 'expected' => false + ], + 'Missing type' => [ + 'input' => [['captcha_provider' => 'adcaptcha']], + 'expected' => false + ], + 'Empty fields' => [ + 'input' => [], + 'expected' => false + ], + 'Different field type' => [ + 'input' => [['type' => 'text', 'captcha_provider' => 'adcaptcha']], + 'expected' => false + ], + 'Multiple fields with valid captcha' => [ + 'input' => [ + ['type' => 'text'], + ['type' => 'captcha', 'captcha_provider' => 'adcaptcha'] + ], + 'expected' => true + ] + ]; + foreach ($testCases as $description => $testCase) { + $result = $method->invoke($this->forms, $testCase['input']); + $this->assertSame($testCase['expected'], $result, "Failed: {$description}"); + } + } + + // Tests if 'captchaTriggerFilter' returns the original HTML when 'has_captcha' is true and prepends the captcha trigger when false. + public function testCaptchaTriggerFilter() { + $this->assertTrue(method_exists($this->forms, 'captcha_trigger_filter'), 'Method captcha_trigger_filter does not exist in Forms class'); + + $reflection = new \ReflectionClass($this->forms); + $property = $reflection->getProperty('has_captcha'); + $property->setAccessible(true); + $property->setValue($this->forms, true); + + $mockHtml = ''; + $result = $this->forms->captcha_trigger_filter($mockHtml, 'button'); + $this->assertEquals($mockHtml, $result, 'Expected HTML when has_captcha is true'); + + $property->setValue($this->forms, false); + $expectedHtml = AdCaptcha::ob_captcha_trigger() . $mockHtml; + $result = $this->forms->captcha_trigger_filter($mockHtml, 'button'); + $this->assertEquals($expectedHtml, $result, 'Expected HTML when has_captcha is false'); + } + + // Tests if 'reset_captcha_script' correctly registers a JavaScript snippet via 'wp_footer' to reset AdCaptcha after form submission. + public function testResetCaptchaScript() { + $this->assertTrue(method_exists($this->forms, 'reset_captcha_script'), 'Method reset_captcha_script does not exist in Forms class'); + Functions\expect('add_action') + ->once() + ->with('wp_footer', \Mockery::type('callable')) + ->andReturnUsing(function($hook, $callback) { + ob_start(); + $callback(); + $output = ob_get_clean(); + $expectedScript = ''; + + $this->assertStringContainsString($expectedScript, $output); + }); + $this->forms->reset_captcha_script(); + } + + public function testVerifyFailsWhenTokenIsMissing() { + Functions\when('wp_unslash')->justReturn(''); + $_POST['adcaptcha_successToken'] = ''; + $result = $this->forms->verify(true, 123, []); + + $this->assertFalse($result['can_submit']); + $this->assertEquals('Please complete the AdCaptcha verification.', $result['error']); + } + + public function testVerifyFailsWhenTokenVerificationFails() { + Functions\when('wp_unslash')->justReturn('invalid_token'); + $this->verifyMock->method('verify_token')->willReturn(false); + $result = $this->forms->verify(true, 123, []); + + $this->assertFalse($result['can_submit']); + $this->assertEquals('AdCaptcha verification failed. Please try again.', $result['error']); + } + + public function testVerifySucceedsWhenTokenIsValid() { + Functions\when('wp_unslash')->justReturn('valid_token'); + $this->verifyMock->method('verify_token')->willReturn(true); + $result = $this->forms->verify(true, 123, []); + $this->assertTrue(method_exists($this->forms, 'verify'), 'Method verify does not exist in Forms class'); + $this->assertTrue($result); + } + } \ No newline at end of file From 5c30db04b8d57b7670a042ae7ca23806d385b6fb Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Wed, 5 Mar 2025 09:20:57 +0000 Subject: [PATCH 14/24] added empty line to the end --- tests/Plugin/Forminator/ForminatorTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Plugin/Forminator/ForminatorTest.php b/tests/Plugin/Forminator/ForminatorTest.php index 5970bec..3fee1f4 100644 --- a/tests/Plugin/Forminator/ForminatorTest.php +++ b/tests/Plugin/Forminator/ForminatorTest.php @@ -231,4 +231,5 @@ public function testVerifySucceedsWhenTokenIsValid() { $this->assertTrue(method_exists($this->forms, 'verify'), 'Method verify does not exist in Forms class'); $this->assertTrue($result); } - } \ No newline at end of file + } + \ No newline at end of file From dc9a89e931a86084c930d2b051b77ed8b2c7ceaa Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 6 Mar 2025 22:51:03 +0000 Subject: [PATCH 15/24] Gravity form test --- src/Plugin/GravityForms/Field.php | 13 +- src/Plugin/GravityForms/Forms.php | 1 - .../Plugin/GravityForms/GravityFormsTest.php | 475 ++++++++++++++++++ tests/bootstrap.php | 1 + 4 files changed, 485 insertions(+), 5 deletions(-) create mode 100644 tests/Plugin/GravityForms/GravityFormsTest.php diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 09acbf8..348ac69 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -9,16 +9,18 @@ use AdCaptcha\Widget\Verify; use Exception; -if (!class_exists('GF_Field')) { +// update the condition for testing environment +if (!class_exists('GF_Field') && !defined('PHPUNIT_RUNNING')) { return; } class Field extends GF_Field { - public $type = 'adcaptcha'; + public $type; private $verify; public function __construct($data = []) { parent::__construct($data); + $this->type = 'adcaptcha'; $this->verify = new Verify(); $this->setup(); } @@ -64,7 +66,7 @@ public function add_to_field_groups($field_groups): array { } } $field_groups['advanced_fields']['fields'][] = [ - 'data-type' => $this->type, + 'data-type' => (string) $this->type, 'value' => $this->get_form_editor_field_title(), 'label' => $this->get_form_editor_field_title(), ]; @@ -199,7 +201,10 @@ public function enqueue_preview_scripts($form_id) { } public function get_field_input($form, $value = '', $entry = null) { - $form_id = $form['id']; + $form_id = $form['id'] ?? null; + if ($form_id === null) { + return ''; + } $field_id = (int) $this->id; if ($this->is_form_editor()) { return "
adCAPTCHA will be rendered here.
"; diff --git a/src/Plugin/GravityForms/Forms.php b/src/Plugin/GravityForms/Forms.php index 88eaecd..dc1ad95 100644 --- a/src/Plugin/GravityForms/Forms.php +++ b/src/Plugin/GravityForms/Forms.php @@ -25,4 +25,3 @@ public function register_adcaptcha_field() { } } } - diff --git a/tests/Plugin/GravityForms/GravityFormsTest.php b/tests/Plugin/GravityForms/GravityFormsTest.php new file mode 100644 index 0000000..cfc8561 --- /dev/null +++ b/tests/Plugin/GravityForms/GravityFormsTest.php @@ -0,0 +1,475 @@ +type = $type; + $this->id = 123; + $this->isFormEditor = $isFormEditor; + } + + public function get_field_label($input1 = false, $input2 = '') { + return 'AdCaptcha Label'; + } + + public function is_form_editor() { + return $this->isFormEditor; + } +} + +class MockGFAPI { + public static function get_forms() { + return []; + } +} + +class MockGFAPIWithFields { + public static function get_forms() { + return [ + [ // ✅ Use an array instead of an object + 'id' => 1, + 'title' => 'Test Form', + 'fields' => [ + (object) ['id' => 1, 'type' => 'text', 'label' => 'Text Field'], + (object) ['id' => 2, 'type' => 'adcaptcha', 'label' => 'Incorrect Label'], + ] + ], + [ // ✅ Use an array instead of an object + 'id' => 2, + 'title' => 'Another Form', + 'fields' => [ + (object) ['id' => 3, 'type' => 'email', 'label' => 'Email Field'], + (object) ['id' => 4, 'type' => 'adcaptcha', 'label' => 'adCAPTCHA'], + ] + ] + ]; + } + + public static function update_form($form) { + return true; + } +} + + use PHPUnit\Framework\TestCase; + use AdCaptcha\Plugin\GravityForms\Forms; + use AdCaptcha\Plugin\GravityForms\Field; + use AdCaptcha\Widget\AdCaptcha; + use AdCaptcha\Widget\Verify; + use Brain\Monkey; + use Brain\Monkey\Functions; + use Mockery; + use ReflectionClass; + + class GravityFormsTest extends TestCase { + private $forms; + private $verifyMock; + private $field; + + public function setUp(): void { + parent::setUp(); + Monkey\setUp(); + + global $mocked_actions, $mocked_filters; + $mocked_actions = []; + $mocked_filters = []; + + if (!class_exists('GF_Fields', false)) { + class_alias(MockGF_Fields::class, 'GF_Fields'); + } + if(!class_exists('GF_Field', false)) { + class_alias(MockGF_Field::class, 'GF_Field'); + } + + Functions\when('esc_html__')->alias(function ($text, $domain) { + return "[{$domain}] {$text}"; + }); + Functions\when('esc_attr__')->alias(function ($text, $domain) { + return "[{$domain}] {$text}"; + }); + Functions\when('esc_js')->alias(function ($text) { + return $text; + }); + Functions\when('esc_attr')->alias(function ($text) { + return $text; + }); + Functions\when('get_option')->alias(function ($option_name) { + $mock_values = [ + 'adcaptcha_placement_id' => 'mocked-placement-id', + ]; + return $mock_values[$option_name] ?? null; + }); + Functions\when('sanitize_text_field')->alias(function($input) { + $sanitized = strip_tags($input); + $sanitized = preg_replace('/[\r\n\t]/', ' ', $sanitized); + $sanitized = trim($sanitized); + return $sanitized; + }); + Functions\when('__')->alias(function ($text, $domain = null) { + return $text; + }); + Functions\when('plugin_dir_url')->alias(function ($path) { + return ''; + }); + + $this->forms = new Forms(); + $this->field = new Field(); + + $this->verifyMock = $this->createMock(Verify::class); + $reflection = new \ReflectionClass($this->field); + $property = $reflection->getProperty('verify'); + $property->setAccessible(true); + $property->setValue($this->field, $this->verifyMock); + } + + public function tearDown(): void { + global $mocked_filters; + $mocked_filters = []; + Mockery::close(); + Monkey\tearDown(); + parent::tearDown(); + } + + public function testSetup() { + $this->assertTrue(method_exists($this->forms, 'setup'), 'Method setup does not exist'); + global $mocked_actions; + $this->forms->setup(); + $registeredAction = array_filter($mocked_actions, function ($action) { + return $action['hook'] === 'gform_loaded'; + }); + $this->assertNotEmpty($registeredAction, 'The gform_loaded action was not registered.'); + $registeredAction = array_values($registeredAction)[0]; + $this->assertEquals(10, $registeredAction['priority'], 'Expected priority 10 for gform_loaded.'); + $this->assertEquals(0, $registeredAction['accepted_args'], 'Expected 0 accepted args for gform_loaded.'); + $this->assertInstanceOf(\Closure::class, $registeredAction['callback'], 'Expected a Closure as the callback.'); + } + + public function testRegisterAdcaptchaField() { + $this->assertTrue(method_exists($this->forms, 'register_adcaptcha_field'), 'Method register_adcaptcha_field does not exist'); + $result = $this->forms->register_adcaptcha_field(); + $this->assertNull($result, 'Expected null return value from register_adcaptcha_field'); + } + + public function testSetupHooks() { + $this->assertTrue(method_exists($this->field, 'setup_hooks'), 'Method setup_hooks does not exist'); + + global $mocked_actions, $mocked_filters; + $this->assertContains( + ['hook' => 'wp_enqueue_scripts', 'callback' => [AdCaptcha::class, 'enqueue_scripts'], 'priority' => 9, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'wp_enqueue_scripts', 'callback' => [Verify::class, 'get_success_token'], 'priority' => 10, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'admin_head', 'callback' => [$this->field, 'custom_admin_field_icon_style'], 'priority' => 10, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'admin_init', 'callback' => [$this->field, 'update_adcaptcha_label'], 'priority' => 10, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'admin_footer', 'callback' => [$this->field, 'enqueue_admin_script'], 'priority' => 10, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'gform_preview_body_open', 'callback' => [$this->field, 'enqueue_preview_scripts'], 'priority' => 10, 'accepted_args' => 1], + $mocked_actions + ); + $this->assertContains( + ['hook' => 'gform_field_groups_form_editor', 'callback' => [$this->field, 'add_to_field_groups'], 'priority' => 10, 'accepted_args' => 1], + $mocked_filters + ); + $this->assertContains( + ['hook' => 'gform_field_content', 'callback' => [$this->field, 'modify_gform_field_content'], 'priority' => 10, 'accepted_args' => 2], + $mocked_filters + ); + $this->assertContains( + ['hook' => 'gform_validation', 'callback' => [$this->field, 'verify_captcha'], 'priority' => 10, 'accepted_args' => 1], + $mocked_filters + ); + $this->assertContains( + ['hook' => 'gform_pre_render', 'callback' => [$this->field, 'handle_adcaptcha_token'], 'priority' => 10, 'accepted_args' => 1], + $mocked_filters + ); + } + + public function testAddToFieldGroups() { + $this->assertTrue(method_exists($this->field, 'add_to_field_groups'), 'Method add_to_field_groups does not exist'); + $field_groups = [ + 'advanced_fields' => [ + 'fields' => [ + ['data-type' => 'text'], + ['data-type' => 'email'], + ] + ] + ]; + $field_groups_adcaptcha = [ + 'advanced_fields' => [ + 'fields' => [ + ['data-type' => 'adcaptcha'], + ] + ] + ]; + $result = $this->field->add_to_field_groups($field_groups); + $this->assertContains( + ['data-type' => 'adcaptcha', 'value' => $this->field->get_form_editor_field_title(), 'label' => $this->field->get_form_editor_field_title()], + $result['advanced_fields']['fields'] + ); + $fieldWithAdcaptcha = $this->field->add_to_field_groups($field_groups_adcaptcha); + $this->assertEquals($field_groups_adcaptcha, $fieldWithAdcaptcha, 'Expected the field groups to remain unchanged if adcaptcha field is already present'); + } + + public function testModifyGformFieldContent() { + $this->assertTrue(method_exists($this->field, 'modify_gform_field_content'), 'Method modify_gform_field_content does not exist'); + $field = new MockGF_Field('adcaptcha'); + + $content = ''; + $expectedModifiedContent = ''; + + $modifiedContent = $this->field->modify_gform_field_content($content, $field); + $this->assertEquals($expectedModifiedContent, $modifiedContent, 'Expected label to be removed for adcaptcha fields'); + } + + public function testVerifyCaptchaFailsWhenTokenIsEmpty() { + Functions\when('wp_unslash')->justReturn(''); + $validation_result = [ + 'form' => ['fields' => [(object) ['type' => 'adcaptcha']]], + 'is_valid' => true + ]; + $result = $this->field->verify_captcha($validation_result); + $this->assertFalse($result['is_valid']); + $this->assertTrue($result['form']['fields'][0]->failed_validation); + $this->assertEquals('Incomplete CAPTCHA, Please try again.', $result['form']['fields'][0]->validation_message); + } + + public function testVerifyCaptchaFailsWhenTokenVerificationFails() { + Functions\when('wp_unslash')->justReturn('invalid_token'); + $this->verifyMock->method('verify_token')->willReturn(false); + $validation_result = [ + 'form' => ['fields' => [(object) ['type' => 'adcaptcha']]], + 'is_valid' => true + ]; + $result = $this->field->verify_captcha($validation_result); + $this->assertFalse($result['is_valid']); + $this->assertTrue($result['form']['fields'][0]->failed_validation); + $this->assertEquals('Invalid token.', $result['form']['fields'][0]->validation_message); + } + + public function testVerifyCaptchaSucceedsWhenTokenIsValid() { + Functions\when('wp_unslash')->justReturn('valid_token'); + $this->verifyMock->method('verify_token')->willReturn(true); + $validation_result = [ + 'form' => [ + 'fields' => [ + (object) [ + 'type' => 'adcaptcha', + 'failed_validation' => false, + 'validation_message' => '' + ] + ] + ], + 'is_valid' => true + ]; + $result = $this->field->verify_captcha($validation_result); + $this->assertTrue($result['is_valid']); + $this->assertFalse($result['form']['fields'][0]->failed_validation); + $this->assertEmpty($result['form']['fields'][0]->validation_message); + } + + public function testCustomAdminFieldIconStyle() { + $this->assertTrue(method_exists($this->field, 'custom_admin_field_icon_style'), 'Method custom_admin_field_icon_style does not exist'); + ob_start(); + $this->field->custom_admin_field_icon_style(); + $capturedOutput = ob_get_clean(); + $this->assertStringContainsString("#sidebar_field_info #sidebar_field_icon img { + width: 16px !important; + }", $capturedOutput, 'Expected the style to be output'); + } + + // public function testUpdateAdcaptchaLabelFormEmpty() { + // if(!class_exists('GFAPI', false)) { + // class_alias(MockGFAPI::class, 'GFAPI'); + // } + // $this->assertTrue(method_exists($this->field, 'update_adcaptcha_label'), 'Method update_adcaptcha_label does not exist'); + // $result = $this->field->update_adcaptcha_label(); + // $this->assertNull($result, 'Expected null return value from update_adcaptcha_label'); + // } + + public function testUpdateAdcaptchaLabelFormWithFields() { + if(!class_exists('GFAPI', false)) { + class_alias(MockGFAPIWithFields::class, 'GFAPI'); + } + $result = $this->field->update_adcaptcha_label(); + // var_dump($result); + // $forms = [ + // (object) [ + // 'fields' => [ + // (object) ['type' => 'text'], + // (object) ['type' => 'adcaptcha', 'label' => 'AdCaptcha Label'], + // ] + // ] + // ]; + // Functions\when('GFAPI::get_forms')->justReturn($forms); + // $this->assertTrue(method_exists($this->field, 'update_adcaptcha_label'), 'Method update_adcaptcha_label does not exist'); + // $result = $this->field->update_adcaptcha_label(); + // $this->assertNull($result, 'Expected null return value from update_adcaptcha_label'); + } + + public function testEnqueueAdminScript() { + $this->assertTrue(method_exists($this->field, 'enqueue_admin_script'), 'Method enqueue_admin_script does not exist'); + ob_start(); + $this->field->enqueue_admin_script(); + $capturedOutput = ob_get_clean(); + $this->assertStringContainsString("if (typeof window.CanFieldBeAdded !== 'function') { + return; + }", $capturedOutput, 'Expected the script to be output'); + $this->assertStringContainsString("let originalFunction = window.CanFieldBeAdded;", $capturedOutput, 'Expected the script to be output'); + $this->assertStringContainsString('window.CanFieldBeAdded = function(type) { + if (type === "adcaptcha") { + if (GetFieldsByType(["adcaptcha"]).length > 0) { + gform.instances.dialogAlert("Field Error", "Only one adCAPTCHA field can be added."); + return false; + } + } + return originalFunction(type); + };', $capturedOutput, 'Expected the script to be output'); + } + + public function testHandleAdcaptchaToken() { + $this->assertTrue(method_exists($this->field, 'handle_adcaptcha_token'), 'Method handle_adcaptcha_token does not exist'); + + $_POST = []; + $form = ['id' => 1]; + ob_start(); + $result = $this->field->handle_adcaptcha_token($form); + $capturedOutput = ob_get_clean(); + $this->assertEquals($form, $result, 'Expected the form to be returned unchanged'); + $this->assertEmpty($capturedOutput, 'Expected no script output when success token is missing'); + + $_POST['adcaptcha_successToken'] = 'mocked-success-token'; + ob_start(); + $this->field->handle_adcaptcha_token($form); + $capturedOutput = ob_get_clean(); + $this->assertStringContainsString("document.addEventListener('DOMContentLoaded', function()", $capturedOutput, 'Expected the script to be output'); + $this->assertStringContainsString("let adCaptchaField = document.querySelector('.adcaptcha_successToken');", $capturedOutput, 'Expected the script to be output'); + $this->assertStringContainsString("if (adCaptchaField) { + setTimeout(function() { + if (window.adcap) { + window.adcap.setVerificationState('success'); + adCaptchaField.value = 'mocked-success-token'; + } + }, 500); + }", $capturedOutput, 'Expected the script to be output'); + } + + public function testEnqueuePreviewScripts() { + $this->assertTrue(method_exists($this->field, 'enqueue_preview_scripts'), 'Method enqueue_preview_scripts does not exist'); + $formID = 1; + ob_start(); + $this->field->enqueue_preview_scripts($formID); + $capturedOutput = ob_get_clean(); + $this->assertStringContainsString("document.addEventListener('DOMContentLoaded', function()", $capturedOutput, 'The enqueue_preview_scripts method was not called correctly.'); + $this->assertStringContainsString("let captchaContainer = document.querySelector('.ginput_container_adcaptcha');", $capturedOutput, 'The enqueue_preview_scripts method was not called correctly.'); + $this->assertStringContainsString("if (captchaContainer) { + let messageDiv = document.createElement('div'); + messageDiv.className = 'ginput_container adcaptcha-message'; + messageDiv.innerText = 'adCAPTCHA will be rendered here.'; + captchaContainer.prepend(messageDiv); + }", $capturedOutput, 'The enqueue_preview_scripts method was not called correctly.'); + } + + public function testGetFieldInput() { + $this->assertTrue(method_exists($this->field, 'get_field_input'), 'Method get_field_input does not exist'); + $form = ['id' => null]; + $result = $this->field->get_field_input($form, '', null); + $this->assertEmpty($result, 'Expected an empty string when form ID is missing'); + $form = ['id' => 1]; + $result = $this->field->get_field_input($form, '', null); + $this->assertEquals("
adCAPTCHA will be rendered here.
", $result, 'Expected the adCAPTCHA message to be rendered'); + + $form_id = 1; + $field_id = 123; + $this->field->isFormEditor = false; + $result = $this->field->get_field_input($form, '', null); + $this->assertStringContainsString("document.addEventListener('DOMContentLoaded', function() { + var hiddenToken = document.querySelector('.adcaptcha_successToken'); + if (hiddenToken) { + hiddenToken.id = 'input_{$form_id}_{$field_id}'; + } + });", $result, 'Expected CAPTCHA HTML to be rendered when is_form_editor is false'); + } + + public function testGetFormEditorFieldTitle() { + $this->assertTrue( + method_exists($this->field, 'get_form_editor_field_title'), + 'Method get_form_editor_field_title does not exist' + ); + $expectedText = 'adCAPTCHA'; + $expectedDomain = 'adcaptcha'; + $result = $this->field->get_form_editor_field_title(); + $this->assertEquals( + "[{$expectedDomain}] {$expectedText}", + $result, + 'Expected the title to match the expected text with correct text domain' + ); + } + + public function testGetFormEditorFieldSettings() { + $this->assertTrue(method_exists($this->field, 'get_form_editor_field_settings'), 'Method get_form_editor_field_settings does not exist'); + $data = [ 'description_setting', 'error_message_setting', 'label_placement_setting', 'css_class_setting',]; + $result = $this->field->get_form_editor_field_settings(); + $this->assertIsArray($result, 'Expected an array to be returned'); + $this->assertEquals($data, $result, 'Expected the array keys to match the expected data'); + } + + public function testGetFormEditorFieldDescription() { + $this->assertTrue( + method_exists($this->field, 'get_form_editor_field_description'), + 'Method get_form_editor_field_description does not exist' + ); + $expectedText = 'Adds an adCAPTCHA verification field to enhance security and prevent spam submissions on your forms.'; + $expectedDomain = 'adcaptcha-for-forms'; + $result = $this->field->get_form_editor_field_description(); + $this->assertEquals( + "[{$expectedDomain}] {$expectedText}", + $result, + 'Expected the description to match the expected text with correct text domain' + ); + } + + public function testGetFromEditorFieldIcon() { + $this->assertTrue(method_exists($this->field, 'get_form_editor_field_icon'), 'Method get_form_editor_field_icon does not exist'); + $icon_url = $this->field->get_form_editor_field_icon(); + $this->assertStringContainsString( + '../../../assets/adcaptcha_icon.png', + $icon_url, + 'Expected the icon URL to be correctly formed' + ); + } + } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8935796..3bb7f7e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,5 @@ Date: Fri, 7 Mar 2025 15:58:49 +0000 Subject: [PATCH 16/24] Test is done. Modify the WPErrorMock.php and the Gravity form update_adcaptcha_label error handeling. Removed the throw Exception(implode("\n", $errors)); As this will stop the test and the code. --- src/Plugin/GravityForms/Field.php | 17 +- .../Plugin/GravityForms/GravityFormsTest.php | 166 +++++++++++------- tests/mocks/WPErrorMock.php | 6 +- tests/test_helpers.php | 2 +- 4 files changed, 119 insertions(+), 72 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 348ac69..99797e6 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -126,20 +126,21 @@ public function update_adcaptcha_label() { foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha' && $field->label !== __('adCAPTCHA', 'adcaptcha')) { $field->label = __('adCAPTCHA', 'adcaptcha'); - $field['label'] = __('adCAPTCHA', 'adcaptcha'); + // $field['label'] = __('adCAPTCHA', 'adcaptcha'); $updated = true; } } - if ($updated) { - $result = GFAPI::update_form($form); - - if (is_wp_error($result)) { - $errors[] = "Failed to update adCAPTCHA label in Form ID {$form['id']}: " . $result->get_error_message(); - } + if (!$updated) { + continue; } + $result = GFAPI::update_form($form); + if (function_exists('is_wp_error') && is_wp_error($result)) { + $errorMessage = "Failed to update adCAPTCHA label in Form ID {$form['id']}: " . $result->get_error_message(); + $errors[] = $errorMessage; + } } if (!empty($errors)) { - throw new Exception(implode("\n", $errors)); + return $errors; } } diff --git a/tests/Plugin/GravityForms/GravityFormsTest.php b/tests/Plugin/GravityForms/GravityFormsTest.php index cfc8561..b3fb9d4 100644 --- a/tests/Plugin/GravityForms/GravityFormsTest.php +++ b/tests/Plugin/GravityForms/GravityFormsTest.php @@ -4,8 +4,7 @@ * * @package AdCaptcha */ - - namespace AdCaptcha\Tests\Plugin\GravityForms; +namespace AdCaptcha\Tests\Plugin\GravityForms; class MockGF_Fields { public static bool $wasCalled = false; @@ -41,38 +40,40 @@ public function is_form_editor() { } } -class MockGFAPI { - public static function get_forms() { - return []; - } -} - -class MockGFAPIWithFields { - public static function get_forms() { - return [ - [ // ✅ Use an array instead of an object - 'id' => 1, - 'title' => 'Test Form', - 'fields' => [ - (object) ['id' => 1, 'type' => 'text', 'label' => 'Text Field'], - (object) ['id' => 2, 'type' => 'adcaptcha', 'label' => 'Incorrect Label'], - ] - ], - [ // ✅ Use an array instead of an object - 'id' => 2, - 'title' => 'Another Form', - 'fields' => [ - (object) ['id' => 3, 'type' => 'email', 'label' => 'Email Field'], - (object) ['id' => 4, 'type' => 'adcaptcha', 'label' => 'adCAPTCHA'], - ] - ] - ]; - } - - public static function update_form($form) { - return true; - } -} +// class MockGFAPIWithFields { +// public static function get_forms() { +// return [ +// [ +// 'id' => 6, +// 'title' => 'TestGravity5.0', +// 'fields' => [ +// (object) [ +// 'id' => 1, +// 'type' => 'name', +// 'label' => 'Name', +// ], +// (object) [ +// 'id' => 18, +// 'type' => 'checkbox', +// 'label' => 'Untitled', +// ], +// (object) [ +// 'id' => 45, +// 'type' => 'adcaptcha', +// 'label' => 'dummyLabel', +// ], +// ] +// ] +// ]; +// } + +// public static function update_form($form) { +// if ($form[0]['id'] === 6) { +// return new WP_Error('update_failed', 'Simulated update failure'); +// } +// return true; +// } +// } use PHPUnit\Framework\TestCase; use AdCaptcha\Plugin\GravityForms\Forms; @@ -83,11 +84,14 @@ public static function update_form($form) { use Brain\Monkey\Functions; use Mockery; use ReflectionClass; + use Tests\Mocks\WPErrorMock; + use Exception; class GravityFormsTest extends TestCase { private $forms; private $verifyMock; private $field; + private $mockGFAPI; public function setUp(): void { parent::setUp(); @@ -103,6 +107,9 @@ class_alias(MockGF_Fields::class, 'GF_Fields'); if(!class_exists('GF_Field', false)) { class_alias(MockGF_Field::class, 'GF_Field'); } + if(!class_exists('WP_Error', false)) { + class_alias(WPErrorMock::class, 'WP_Error'); + } Functions\when('esc_html__')->alias(function ($text, $domain) { return "[{$domain}] {$text}"; @@ -135,8 +142,10 @@ class_alias(MockGF_Field::class, 'GF_Field'); return ''; }); + $this->mockGFAPI = Mockery::mock('alias:GFAPI'); + $this->forms = new Forms(); - $this->field = new Field(); + $this->field = new Field($this->mockGFAPI); $this->verifyMock = $this->createMock(Verify::class); $reflection = new \ReflectionClass($this->field); @@ -153,6 +162,7 @@ public function tearDown(): void { parent::tearDown(); } + // Tests if the 'setup' method exists and properly registers the 'gform_loaded' action with the expected parameters. public function testSetup() { $this->assertTrue(method_exists($this->forms, 'setup'), 'Method setup does not exist'); global $mocked_actions; @@ -167,12 +177,14 @@ public function testSetup() { $this->assertInstanceOf(\Closure::class, $registeredAction['callback'], 'Expected a Closure as the callback.'); } + // Tests if the 'register_adcaptcha_field' method exists and returns null as expected. public function testRegisterAdcaptchaField() { $this->assertTrue(method_exists($this->forms, 'register_adcaptcha_field'), 'Method register_adcaptcha_field does not exist'); $result = $this->forms->register_adcaptcha_field(); $this->assertNull($result, 'Expected null return value from register_adcaptcha_field'); } + // Tests if the 'setup_hooks' method exists and correctly registers expected actions and filters. public function testSetupHooks() { $this->assertTrue(method_exists($this->field, 'setup_hooks'), 'Method setup_hooks does not exist'); @@ -219,6 +231,7 @@ public function testSetupHooks() { ); } + // Tests if 'add_to_field_groups' correctly adds the adCAPTCHA field to advanced fields and avoids duplication. public function testAddToFieldGroups() { $this->assertTrue(method_exists($this->field, 'add_to_field_groups'), 'Method add_to_field_groups does not exist'); $field_groups = [ @@ -245,6 +258,7 @@ public function testAddToFieldGroups() { $this->assertEquals($field_groups_adcaptcha, $fieldWithAdcaptcha, 'Expected the field groups to remain unchanged if adcaptcha field is already present'); } + // Tests if 'modify_gform_field_content' removes the label from adCAPTCHA fields while keeping other content unchanged. public function testModifyGformFieldContent() { $this->assertTrue(method_exists($this->field, 'modify_gform_field_content'), 'Method modify_gform_field_content does not exist'); $field = new MockGF_Field('adcaptcha'); @@ -256,6 +270,7 @@ public function testModifyGformFieldContent() { $this->assertEquals($expectedModifiedContent, $modifiedContent, 'Expected label to be removed for adcaptcha fields'); } + // Tests if 'verify_captcha' fails validation when the CAPTCHA token is empty. public function testVerifyCaptchaFailsWhenTokenIsEmpty() { Functions\when('wp_unslash')->justReturn(''); $validation_result = [ @@ -268,6 +283,7 @@ public function testVerifyCaptchaFailsWhenTokenIsEmpty() { $this->assertEquals('Incomplete CAPTCHA, Please try again.', $result['form']['fields'][0]->validation_message); } + // Tests if 'verify_captcha' fails validation when token verification fails. public function testVerifyCaptchaFailsWhenTokenVerificationFails() { Functions\when('wp_unslash')->justReturn('invalid_token'); $this->verifyMock->method('verify_token')->willReturn(false); @@ -281,6 +297,7 @@ public function testVerifyCaptchaFailsWhenTokenVerificationFails() { $this->assertEquals('Invalid token.', $result['form']['fields'][0]->validation_message); } + // Tests if 'verify_captcha' passes validation when a valid token is provided. public function testVerifyCaptchaSucceedsWhenTokenIsValid() { Functions\when('wp_unslash')->justReturn('valid_token'); $this->verifyMock->method('verify_token')->willReturn(true); @@ -302,6 +319,7 @@ public function testVerifyCaptchaSucceedsWhenTokenIsValid() { $this->assertEmpty($result['form']['fields'][0]->validation_message); } + // Tests if 'custom_admin_field_icon_style' outputs the expected CSS styles. public function testCustomAdminFieldIconStyle() { $this->assertTrue(method_exists($this->field, 'custom_admin_field_icon_style'), 'Method custom_admin_field_icon_style does not exist'); ob_start(); @@ -312,35 +330,56 @@ public function testCustomAdminFieldIconStyle() { }", $capturedOutput, 'Expected the style to be output'); } - // public function testUpdateAdcaptchaLabelFormEmpty() { - // if(!class_exists('GFAPI', false)) { - // class_alias(MockGFAPI::class, 'GFAPI'); - // } - // $this->assertTrue(method_exists($this->field, 'update_adcaptcha_label'), 'Method update_adcaptcha_label does not exist'); - // $result = $this->field->update_adcaptcha_label(); - // $this->assertNull($result, 'Expected null return value from update_adcaptcha_label'); - // } + // Tests that 'update_adcaptcha_label' returns null when there are no forms to update. + public function testUpdateAdcaptchaLabelFormEmpty() { + $this->assertTrue(method_exists($this->field, 'update_adcaptcha_label'), 'Method update_adcaptcha_label does not exist'); + $this->mockGFAPI->shouldReceive('get_forms') + ->once() + ->andReturn([]); + $result = $this->field->update_adcaptcha_label(); + $this->assertNull($result, 'Expected null return value from update_adcaptcha_label'); + } + // Tests updating the adCAPTCHA label in a form and handles a simulated update failure. public function testUpdateAdcaptchaLabelFormWithFields() { - if(!class_exists('GFAPI', false)) { - class_alias(MockGFAPIWithFields::class, 'GFAPI'); - } - $result = $this->field->update_adcaptcha_label(); - // var_dump($result); - // $forms = [ - // (object) [ - // 'fields' => [ - // (object) ['type' => 'text'], - // (object) ['type' => 'adcaptcha', 'label' => 'AdCaptcha Label'], - // ] - // ] - // ]; - // Functions\when('GFAPI::get_forms')->justReturn($forms); - // $this->assertTrue(method_exists($this->field, 'update_adcaptcha_label'), 'Method update_adcaptcha_label does not exist'); - // $result = $this->field->update_adcaptcha_label(); - // $this->assertNull($result, 'Expected null return value from update_adcaptcha_label'); + $mockedForms = [ + [ + 'id' => 6, + 'title' => 'TestGravity5.0', + 'fields' => [ + (object) [ + 'id' => 1, + 'type' => 'name', + 'label' => 'Name', + ], + (object) [ + 'id' => 18, + 'type' => 'checkbox', + 'label' => 'Untitled', + ], + (object) [ + 'id' => 45, + 'type' => 'adcaptcha', + 'label' => 'dummyLabel', + ], + ], + ], + ]; + $wpMock = new WPErrorMock(); + $this->mockGFAPI->shouldReceive('get_forms') + ->once() + ->andReturn($mockedForms); + + $this->mockGFAPI->shouldReceive('update_form') + ->with(Mockery::on(function ($form) { + return $form['id'] === 6; + })) + ->andReturn(new \WP_Error('update_failed', 'Simulated update failure')); + $result = $this->field->update_adcaptcha_label(); + $this->assertEquals('Failed to update adCAPTCHA label in Form ID 6: Simulated update failure', $result[0], 'Expected error message when update fails'); } + // Tests that 'enqueue_admin_script' outputs the expected JavaScript for limiting adCAPTCHA field additions. public function testEnqueueAdminScript() { $this->assertTrue(method_exists($this->field, 'enqueue_admin_script'), 'Method enqueue_admin_script does not exist'); ob_start(); @@ -361,6 +400,7 @@ public function testEnqueueAdminScript() { };', $capturedOutput, 'Expected the script to be output'); } + // Tests that 'handle_adcaptcha_token' correctly returns the form and outputs a script when a success token is present. public function testHandleAdcaptchaToken() { $this->assertTrue(method_exists($this->field, 'handle_adcaptcha_token'), 'Method handle_adcaptcha_token does not exist'); @@ -388,6 +428,7 @@ public function testHandleAdcaptchaToken() { }", $capturedOutput, 'Expected the script to be output'); } + // Tests that 'enqueue_preview_scripts' outputs the expected JavaScript for rendering adCAPTCHA in preview mode. public function testEnqueuePreviewScripts() { $this->assertTrue(method_exists($this->field, 'enqueue_preview_scripts'), 'Method enqueue_preview_scripts does not exist'); $formID = 1; @@ -404,6 +445,7 @@ public function testEnqueuePreviewScripts() { }", $capturedOutput, 'The enqueue_preview_scripts method was not called correctly.'); } + // Tests that 'get_field_input' returns the correct HTML output based on form ID and editor mode. public function testGetFieldInput() { $this->assertTrue(method_exists($this->field, 'get_field_input'), 'Method get_field_input does not exist'); $form = ['id' => null]; @@ -425,6 +467,7 @@ public function testGetFieldInput() { });", $result, 'Expected CAPTCHA HTML to be rendered when is_form_editor is false'); } + // Tests that 'get_form_editor_field_title' returns the expected title with the correct text domain. public function testGetFormEditorFieldTitle() { $this->assertTrue( method_exists($this->field, 'get_form_editor_field_title'), @@ -440,6 +483,7 @@ public function testGetFormEditorFieldTitle() { ); } + // Tests that 'get_form_editor_field_settings' returns an array with the expected field settings. public function testGetFormEditorFieldSettings() { $this->assertTrue(method_exists($this->field, 'get_form_editor_field_settings'), 'Method get_form_editor_field_settings does not exist'); $data = [ 'description_setting', 'error_message_setting', 'label_placement_setting', 'css_class_setting',]; @@ -448,6 +492,7 @@ public function testGetFormEditorFieldSettings() { $this->assertEquals($data, $result, 'Expected the array keys to match the expected data'); } + // Tests that 'get_form_editor_field_description' returns the expected description with the correct text domain. public function testGetFormEditorFieldDescription() { $this->assertTrue( method_exists($this->field, 'get_form_editor_field_description'), @@ -463,6 +508,7 @@ public function testGetFormEditorFieldDescription() { ); } + // Tests that 'get_form_editor_field_icon' returns the correct icon URL. public function testGetFromEditorFieldIcon() { $this->assertTrue(method_exists($this->field, 'get_form_editor_field_icon'), 'Method get_form_editor_field_icon does not exist'); $icon_url = $this->field->get_form_editor_field_icon(); diff --git a/tests/mocks/WPErrorMock.php b/tests/mocks/WPErrorMock.php index e549fd5..ca22560 100644 --- a/tests/mocks/WPErrorMock.php +++ b/tests/mocks/WPErrorMock.php @@ -29,11 +29,11 @@ public function get_error_messages() { public function get_error_message($code = '') { if (empty($code)) { - return array_shift($this->errors); + $code = array_key_first($this->errors); } - return isset($this->errors[$code]) ? $this->errors[$code][0] : null; + + return isset($this->errors[$code]) ? $this->errors[$code][0] : ''; } - public function get_error_data($code = '') { return isset($this->error_data[$code]) ? $this->error_data[$code] : null; } diff --git a/tests/test_helpers.php b/tests/test_helpers.php index 49c2b75..1c4a93f 100644 --- a/tests/test_helpers.php +++ b/tests/test_helpers.php @@ -47,4 +47,4 @@ function check_hook_registration($mocked_hooks, $hook_name, $priority = 10, $acc } } return false; -} \ No newline at end of file +} From 5293b1ce2e2b6f67086f1bcf96153f0b1a276884 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Fri, 7 Mar 2025 17:05:25 +0000 Subject: [PATCH 17/24] Updated GravityForm removing error handle. ALso updated test --- src/Plugin/GravityForms/Field.php | 14 +--- .../Plugin/GravityForms/GravityFormsTest.php | 80 ------------------- 2 files changed, 2 insertions(+), 92 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 99797e6..f607cf4 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -120,27 +120,17 @@ public function update_adcaptcha_label() { if (!$forms || !is_array($forms)) { return; } - $errors = []; foreach ($forms as $form) { $updated = false; foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha' && $field->label !== __('adCAPTCHA', 'adcaptcha')) { $field->label = __('adCAPTCHA', 'adcaptcha'); - // $field['label'] = __('adCAPTCHA', 'adcaptcha'); $updated = true; } } - if (!$updated) { - continue; + if ($updated) { + GFAPI::update_form($form); } - $result = GFAPI::update_form($form); - if (function_exists('is_wp_error') && is_wp_error($result)) { - $errorMessage = "Failed to update adCAPTCHA label in Form ID {$form['id']}: " . $result->get_error_message(); - $errors[] = $errorMessage; - } - } - if (!empty($errors)) { - return $errors; } } diff --git a/tests/Plugin/GravityForms/GravityFormsTest.php b/tests/Plugin/GravityForms/GravityFormsTest.php index b3fb9d4..9d9c873 100644 --- a/tests/Plugin/GravityForms/GravityFormsTest.php +++ b/tests/Plugin/GravityForms/GravityFormsTest.php @@ -40,41 +40,6 @@ public function is_form_editor() { } } -// class MockGFAPIWithFields { -// public static function get_forms() { -// return [ -// [ -// 'id' => 6, -// 'title' => 'TestGravity5.0', -// 'fields' => [ -// (object) [ -// 'id' => 1, -// 'type' => 'name', -// 'label' => 'Name', -// ], -// (object) [ -// 'id' => 18, -// 'type' => 'checkbox', -// 'label' => 'Untitled', -// ], -// (object) [ -// 'id' => 45, -// 'type' => 'adcaptcha', -// 'label' => 'dummyLabel', -// ], -// ] -// ] -// ]; -// } - -// public static function update_form($form) { -// if ($form[0]['id'] === 6) { -// return new WP_Error('update_failed', 'Simulated update failure'); -// } -// return true; -// } -// } - use PHPUnit\Framework\TestCase; use AdCaptcha\Plugin\GravityForms\Forms; use AdCaptcha\Plugin\GravityForms\Field; @@ -84,8 +49,6 @@ public function is_form_editor() { use Brain\Monkey\Functions; use Mockery; use ReflectionClass; - use Tests\Mocks\WPErrorMock; - use Exception; class GravityFormsTest extends TestCase { private $forms; @@ -107,9 +70,6 @@ class_alias(MockGF_Fields::class, 'GF_Fields'); if(!class_exists('GF_Field', false)) { class_alias(MockGF_Field::class, 'GF_Field'); } - if(!class_exists('WP_Error', false)) { - class_alias(WPErrorMock::class, 'WP_Error'); - } Functions\when('esc_html__')->alias(function ($text, $domain) { return "[{$domain}] {$text}"; @@ -143,7 +103,6 @@ class_alias(WPErrorMock::class, 'WP_Error'); }); $this->mockGFAPI = Mockery::mock('alias:GFAPI'); - $this->forms = new Forms(); $this->field = new Field($this->mockGFAPI); @@ -340,45 +299,6 @@ public function testUpdateAdcaptchaLabelFormEmpty() { $this->assertNull($result, 'Expected null return value from update_adcaptcha_label'); } - // Tests updating the adCAPTCHA label in a form and handles a simulated update failure. - public function testUpdateAdcaptchaLabelFormWithFields() { - $mockedForms = [ - [ - 'id' => 6, - 'title' => 'TestGravity5.0', - 'fields' => [ - (object) [ - 'id' => 1, - 'type' => 'name', - 'label' => 'Name', - ], - (object) [ - 'id' => 18, - 'type' => 'checkbox', - 'label' => 'Untitled', - ], - (object) [ - 'id' => 45, - 'type' => 'adcaptcha', - 'label' => 'dummyLabel', - ], - ], - ], - ]; - $wpMock = new WPErrorMock(); - $this->mockGFAPI->shouldReceive('get_forms') - ->once() - ->andReturn($mockedForms); - - $this->mockGFAPI->shouldReceive('update_form') - ->with(Mockery::on(function ($form) { - return $form['id'] === 6; - })) - ->andReturn(new \WP_Error('update_failed', 'Simulated update failure')); - $result = $this->field->update_adcaptcha_label(); - $this->assertEquals('Failed to update adCAPTCHA label in Form ID 6: Simulated update failure', $result[0], 'Expected error message when update fails'); - } - // Tests that 'enqueue_admin_script' outputs the expected JavaScript for limiting adCAPTCHA field additions. public function testEnqueueAdminScript() { $this->assertTrue(method_exists($this->field, 'enqueue_admin_script'), 'Method enqueue_admin_script does not exist'); From 2004e3134dcc5417bb745209bbe071cc619ce58a Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Mon, 10 Mar 2025 10:43:09 +0000 Subject: [PATCH 18/24] Update Field.php --- src/Plugin/GravityForms/Field.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Plugin/GravityForms/Field.php b/src/Plugin/GravityForms/Field.php index 09acbf8..53c6d72 100644 --- a/src/Plugin/GravityForms/Field.php +++ b/src/Plugin/GravityForms/Field.php @@ -118,27 +118,18 @@ public function update_adcaptcha_label() { if (!$forms || !is_array($forms)) { return; } - $errors = []; foreach ($forms as $form) { $updated = false; foreach ($form['fields'] as &$field) { if ($field->type === 'adcaptcha' && $field->label !== __('adCAPTCHA', 'adcaptcha')) { $field->label = __('adCAPTCHA', 'adcaptcha'); - $field['label'] = __('adCAPTCHA', 'adcaptcha'); $updated = true; } } if ($updated) { - $result = GFAPI::update_form($form); - - if (is_wp_error($result)) { - $errors[] = "Failed to update adCAPTCHA label in Form ID {$form['id']}: " . $result->get_error_message(); - } + GFAPI::update_form($form); } } - if (!empty($errors)) { - throw new Exception(implode("\n", $errors)); - } } public function enqueue_admin_script() { From da3b93ddbf6060ad7254da413ff1be10c63940b1 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 3 Apr 2025 17:52:09 +0300 Subject: [PATCH 19/24] Update plugin Version --- adcaptcha.php | 4 ++-- readme.txt | 3 +++ src/Settings/Settings.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/adcaptcha.php b/adcaptcha.php index c343201..96ac568 100644 --- a/adcaptcha.php +++ b/adcaptcha.php @@ -2,7 +2,7 @@ /** * Plugin Name: adCAPTCHA for WordPress * Description: Secure your site. Elevate your brand. Boost Ad Revenue. - * Version: 1.6.0 + * Version: 1.7.0 * Requires at least: 6.4.2 * Requires PHP: 7.4 * Author: adCAPTCHA @@ -21,7 +21,7 @@ use AdCaptcha\Instantiate; -const PLUGIN_VERSION_ADCAPTCHA = '1.6.0'; +const PLUGIN_VERSION_ADCAPTCHA = '1.7.0'; define('ADCAPTCHA_ERROR_MESSAGE', __( 'Please complete the I am human box.', 'adcaptcha' )); if ( ! function_exists( 'adcaptcha_uninstall' ) ) { diff --git a/readme.txt b/readme.txt index 8fc40c7..2988195 100644 --- a/readme.txt +++ b/readme.txt @@ -157,3 +157,6 @@ During verification, the adCAPTCHA service may briefly receive the user's IP add = 1.6.0 = - Added feature to disable the WooCommerce checkout endpoint. + += 1.7.0 = +- Feature: Added support for Gravity Forms and Forminator. \ No newline at end of file diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index 192572e..14f3384 100644 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -81,6 +81,6 @@ public function change_admin_footer_text() { } public function change_admin_footer_version() { - return 'Version 1.6.0'; + return 'Version 1.7.0'; } } From d52497fe41aec4be5afc84a75289cd98dd57997a Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 3 Apr 2025 17:55:01 +0300 Subject: [PATCH 20/24] Empty line in readme --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 2988195..8025568 100644 --- a/readme.txt +++ b/readme.txt @@ -159,4 +159,4 @@ During verification, the adCAPTCHA service may briefly receive the user's IP add - Added feature to disable the WooCommerce checkout endpoint. = 1.7.0 = -- Feature: Added support for Gravity Forms and Forminator. \ No newline at end of file +- Feature: Added support for Gravity Forms and Forminator. From 8523144b629aa45ef86b6a42232afc107b7526dd Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 3 Apr 2025 18:00:31 +0300 Subject: [PATCH 21/24] Updated supported list --- readme.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.txt b/readme.txt index 8025568..da8b80c 100644 --- a/readme.txt +++ b/readme.txt @@ -46,6 +46,10 @@ adCAPTCHA offers a unique proposition in the digital space by combining Security **Fluent Forms** +**Gravity Forms** + +**Forminator** + == Advance Features == **Woocommerce** From 0a217a3df19dbb7ef1c65ed730407e4572d6c89c Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 3 Apr 2025 18:16:38 +0300 Subject: [PATCH 22/24] Update Readme file --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c4145c6..811332a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,10 @@ ### Fluent Forms +### Gravity Forms + +### Forminator + ## Advance Features * Able to trigger adCAPTCHA on the "Place order" button. From 33bcd363d549f6dc1fad8cb38115dd69f5ea4d38 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 3 Apr 2025 18:20:55 +0300 Subject: [PATCH 23/24] Stable tag update --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index da8b80c..3cfafc9 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Contributors: adCAPTCHA Tags: spam, anti-spam, block bots, security, adCAPTCHA Requires at least: 6.0 Tested up to: 6.5.2 -Stable tag: 1.6.0 +Stable tag: 1.7.0 Requires PHP: 7.4 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html From b30fdc580e5c8980792595435050310da6bee578 Mon Sep 17 00:00:00 2001 From: Istvan Vas Date: Thu, 3 Apr 2025 18:29:48 +0300 Subject: [PATCH 24/24] Fixing error from conflict --- src/Instantiate.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Instantiate.php b/src/Instantiate.php index 2d4057c..c300fdc 100644 --- a/src/Instantiate.php +++ b/src/Instantiate.php @@ -89,11 +89,11 @@ public function setup() { 'Forminator_Forms' => [ 'instance' => Forminator::class, 'plugin' => [ 'forminator/forminator.php' ], - + ], 'GravityForms_Forms' => [ 'instance' => GravityForms::class, - 'plugin' => [ 'gravityforms/gravityforms.php' ], - ], + 'plugin' => [ 'gravityforms/gravityforms.php' ] + ] ]; $selected_plugins = get_option('adcaptcha_selected_plugins') ? get_option('adcaptcha_selected_plugins') : array();