diff --git a/cleantalk.php b/cleantalk.php index de261ff1f..a15133946 100644 --- a/cleantalk.php +++ b/cleantalk.php @@ -600,10 +600,6 @@ function apbct_write_js_errors($data) // Public actions if ( ! is_admin() && ! apbct_is_ajax() && ! apbct_is_customize_preview() ) { - // Default search - add_filter('get_search_query', 'apbct_forms__search__testSpam'); - add_action('wp_head', 'apbct_search_add_noindex', 1); - if (apbct_is_plugin_active('fluentformpro/fluentformpro.php') && apbct_is_in_uri('ff_landing=')) { add_action('wp_head', function () { echo '' . "\n"; -} - /** * Public function - Tests for Pirate contact forms * return NULL @@ -3446,53 +3382,6 @@ function apbct_form_happyforms_test_spam($is_valid, $request, $_form) return $is_valid; } -/** - * Prepare data to add honeypot to the WordPress default search form. - * Fires ct_add_honeypot_field() on hook get_search_form when: - * - method of the form is post - * - spam test of search form is enabled - * - * @param string $form_html - * @return string - */ -function apbct_form_search__add_fields($form_html) -{ - global $apbct; - - if ( !empty($form_html) && is_string($form_html) && $apbct->settings['forms__search_test'] == 1 ) { - // extract method of the form with DOMDocument - if ( class_exists('DOMDocument') ) { - libxml_use_internal_errors(true); - $dom = new DOMDocument(); - if ( @$dom->loadHTML($form_html) ) { - $search_form_dom = $dom->getElementById('searchform'); - if ( !empty($search_form_dom) ) { - $method = empty($search_form_dom->getAttribute('method')) - //default method is get for any form if no method specified - ? 'get' - : $search_form_dom->getAttribute('method'); - } - } - libxml_clear_errors(); - unset($dom); - } - - // retry extract method of the form with regex - if ( empty($method) ) { - preg_match('/form.*method="(.*?)"/', $form_html, $matches); - $method = empty($matches[1]) - ? 'get' - : trim($matches[1]); - } - - $form_method = strtolower($method); - - return str_replace('', Honeypot::generateHoneypotField('search_form', $form_method) . '', $form_html); - } - - return $form_html; -} - /** * Advanced Classifieds & Directory Pro * diff --git a/inc/cleantalk-public.php b/inc/cleantalk-public.php index f21f90544..801f04ad6 100644 --- a/inc/cleantalk-public.php +++ b/inc/cleantalk-public.php @@ -47,11 +47,6 @@ function apbct_init() add_filter('rocket_delay_js_exclusions', 'apbct_rocket_delay_js_exclusions'); } - //Search form hook init - if ( $apbct->settings['forms__search_test'] ) { - add_filter('get_search_form', 'apbct_form_search__add_fields', 999); - } - //fix for EPM registration form if ( Post::get('reg_email') && shortcode_exists('epm_registration_form') ) { unset($_POST['ct_checkjs_register_form']); diff --git a/lib/Cleantalk/Antispam/IntegrationsByClass.php b/lib/Cleantalk/Antispam/IntegrationsByClass.php index a77a0d8f5..48875d679 100755 --- a/lib/Cleantalk/Antispam/IntegrationsByClass.php +++ b/lib/Cleantalk/Antispam/IntegrationsByClass.php @@ -2,6 +2,8 @@ namespace Cleantalk\Antispam; +use Cleantalk\Antispam\IntegrationsByClass\IntegrationByClassBase; + class IntegrationsByClass { /** @@ -27,13 +29,15 @@ public function __construct($integrations) foreach ($this->integrations as $integration_name => $integration_info) { // pre-check to skip integration by plugin path - if ( isset($integration_info['plugin_path']) && !$this->isPluginActive($integration_info['plugin_path']) ) { - continue; - } + if (!isset($integration_info['wp_includes'])) { + if ( isset($integration_info['plugin_path']) && !$this->isPluginActive($integration_info['plugin_path']) ) { + continue; + } - // pre-check to skip integration by plugin class - if ( isset($integration_info['plugin_class']) && !class_exists($integration_info['plugin_class']) ) { - continue; + // pre-check to skip integration by plugin class + if ( isset($integration_info['plugin_class']) && !class_exists($integration_info['plugin_class']) ) { + continue; + } } $class = '\\Cleantalk\\Antispam\\IntegrationsByClass\\' . $integration_name; @@ -41,6 +45,9 @@ public function __construct($integrations) continue; } + /** + * @var IntegrationByClassBase $integration + */ $integration = new $class(); // Ajax work diff --git a/lib/Cleantalk/Antispam/IntegrationsByClass/WPSearchForm.php b/lib/Cleantalk/Antispam/IntegrationsByClass/WPSearchForm.php new file mode 100644 index 000000000..0a9d84090 --- /dev/null +++ b/lib/Cleantalk/Antispam/IntegrationsByClass/WPSearchForm.php @@ -0,0 +1,165 @@ +settings['forms__search_test'] ) { + add_filter('get_search_form', array($this, 'apbctFormSearchAddFields'), 999); + } + if ( ! is_admin() && ! apbct_is_ajax() && ! apbct_is_customize_preview() ) { + // Default search + add_filter('get_search_query', array($this, 'testSpam')); + add_action('wp_head', array($this, 'addNoindex'), 1); + } + } + + /** + * @return void + * @psalm-suppress PossiblyUnusedMethod + */ + public function doAdminWork() + { + } + + /** + * Prepare data to add honeypot to the WordPress default search form. + * Fires ct_add_honeypot_field() on hook get_search_form when: + * - method of the form is post + * - spam test of search form is enabled + * + * @param string $form_html + * @return string + */ + public function apbctFormSearchAddFields($form_html) + { + global $apbct; + + if ( !empty($form_html) && is_string($form_html) && $apbct->settings['forms__search_test'] == 1 ) { + // extract method of the form with DOMDocument + if ( class_exists('DOMDocument') ) { + libxml_use_internal_errors(true); + $dom = new DOMDocument(); + if ( @$dom->loadHTML($form_html) ) { + $search_form_dom = $dom->getElementById('searchform'); + if ( !empty($search_form_dom) ) { + $method = empty($search_form_dom->getAttribute('method')) + //default method is get for any form if no method specified + ? 'get' + : $search_form_dom->getAttribute('method'); + } + } + libxml_clear_errors(); + unset($dom); + } + + // retry extract method of the form with regex + if ( empty($method) ) { + preg_match('/form.*method="(.*?)"/', $form_html, $matches); + $method = empty($matches[1]) + ? 'get' + : trim($matches[1]); + } + $form_method = strtolower($method); + + $resalt = str_replace('', Honeypot::generateHoneypotField('search_form', $form_method) . '', $form_html); + return $resalt; + } + + return $form_html; + } + + /** + * Test default search string for spam + * + * @param string $search + * + * @return string + */ + public function testSpam($search) + { + global $apbct, $cleantalk_executed; + + if ( + empty($search) || + $cleantalk_executed || + $apbct->settings['forms__search_test'] == 0 || + ($apbct->settings['data__protect_logged_in'] != 1 && is_user_logged_in()) // Skip processing for logged in users. + ) { + do_action('apbct_skipped_request', __FILE__ . ' -> ' . __FUNCTION__ . '():' . __LINE__, $_POST); + return $search; + } + + $user = apbct_is_user_logged_in() ? wp_get_current_user() : null; + + $data = array( + 'message' => $search, + 'sender_email' => $user !== null ? $user->user_email : null, + 'sender_nickname' => $user !== null ? $user->user_login : null, + 'post_info' => array('comment_type' => 'site_search_wordpress'), + 'exception_action' => 0, + ); + + $base_call_result = apbct_base_call($data); + + if ( isset($base_call_result['ct_result']) ) { + $ct_result = $base_call_result['ct_result']; + + $cleantalk_executed = true; + + if ( $ct_result->allow == 0 ) { + die($ct_result->comment); + } + } + + return $search; + } + + /** + * Add no-index meta to the page of search results + * @return void + */ + public function addNoindex() + { + global $apbct; + + if ( + ! is_search() || // If it is search results + $apbct->settings['forms__search_test'] == 0 || + ($apbct->settings['data__protect_logged_in'] != 1 && is_user_logged_in()) // Skip processing for logged in users. + ) { + return; + } + + echo '' . "\n"; + echo '' . "\n"; + } +} diff --git a/lib/Cleantalk/ApbctWP/Honeypot.php b/lib/Cleantalk/ApbctWP/Honeypot.php index 495ed6a2f..c426b3b9f 100644 --- a/lib/Cleantalk/ApbctWP/Honeypot.php +++ b/lib/Cleantalk/ApbctWP/Honeypot.php @@ -117,7 +117,11 @@ private static function getHoneypotFilledFields() // AltSessions way to collect search forms honeypot if ( $apbct->settings['forms__search_test'] ) { - $honeypot_potential_values['apbct__email_id__search_form'] = AltSessions::get("apbct_search_form__honeypot_value"); + $alt_session_data = AltSessions::get("apbct_search_form__honeypot_value"); + if (!empty($alt_session_data)) { + $honeypot_potential_values['apbct__email_id__search_form'] = $alt_session_data; + $hp_exists = true; + } } // if source is filled then pass them to params as additional fields diff --git a/tests/StandaloneFunctions/PublicIntegrationsTest.php b/tests/StandaloneFunctions/PublicIntegrationsTest.php index f0fd10ee6..bee6c53e3 100644 --- a/tests/StandaloneFunctions/PublicIntegrationsTest.php +++ b/tests/StandaloneFunctions/PublicIntegrationsTest.php @@ -2,7 +2,6 @@ use PHPUnit\Framework\TestCase; use Cleantalk\ApbctWP\State; - class PublicIntegrationsTest extends TestCase { /** @@ -14,6 +13,7 @@ public function test_apbct_form_search__add_fields() global $apbct; $apbct = new State( 'cleantalk', array('settings', 'data', 'errors', 'remote_calls', 'stats', 'fw_stats') ); $apbct->settings['data__honeypot_field'] = 1; + $wp_search_form = new \Cleantalk\Antispam\IntegrationsByClass\WPSearchForm(); //define sample form test $sample_form = '
'; - $this->assertNotFalse(simplexml_load_string(apbct_form_search__add_fields($sample_form)), - 'TEST DATA:['.$sample_form.']'); + $this->assertNotFalse( + simplexml_load_string($wp_search_form->apbctFormSearchAddFields($sample_form)), + 'TEST DATA:[' . $sample_form . ']' + ); //define empty string test - $this->assertEmpty(apbct_form_search__add_fields(''), + $this->assertEmpty($wp_search_form->apbctFormSearchAddFields(''), 'TEST DATA:[EMPTY STRING]'); //define values that will be returned as is $test_data_invalid[] = array('form'=>''); @@ -36,18 +38,18 @@ public function test_apbct_form_search__add_fields() $test_data_invalid[] = new Exception(); //and walk them foreach ($test_data_invalid as $test){ - $this->assertEquals(apbct_form_search__add_fields($test),$test); + $this->assertEquals($wp_search_form->apbctFormSearchAddFields($test),$test); } //fails if signature not found in changed form - $success = (preg_match('/class=".*?apbct__email_id__search_form/', apbct_form_search__add_fields($sample_form)) || - preg_match('/id=".*?apbct_event_id/', apbct_form_search__add_fields($sample_form)) + $success = (preg_match('/class=".*?apbct__email_id__search_form/', $wp_search_form->apbctFormSearchAddFields($sample_form)) || + preg_match('/id=".*?apbct_event_id/', $wp_search_form->apbctFormSearchAddFields($sample_form)) )&& - preg_match('/class=".*?apbct_special_field/', apbct_form_search__add_fields($sample_form)); + preg_match('/class=".*?apbct_special_field/', $wp_search_form->apbctFormSearchAddFields($sample_form)); $this->assertNotFalse($success); //form won`t be changed if search form checking is not set in settings $apbct->settings['forms__search_test'] = 0; - $this->assertEquals(apbct_form_search__add_fields($sample_form),$sample_form); + $this->assertEquals($wp_search_form->apbctFormSearchAddFields($sample_form),$sample_form); } }