honeypot; } /** * @return bool */ public function validate() { if ( ! $this->is_option_on() || ! $this->check_honeypot_filter() ) { // Never flag as honeypot spam if disabled. return true; } return ! $this->is_honeypot_spam(); } /** * @return bool */ private function is_honeypot_spam() { $is_honeypot_spam = $this->is_legacy_honeypot_spam(); if ( ! $is_honeypot_spam ) { $field_id = $this->get_honeypot_field_id(); if ( ! $field_id ) { return false; } $value = $this->get_honeypot_field_value( $field_id ); $is_honeypot_spam = '' !== $value; } $atts = array( 'form' => $this->get_form(), ); /** * Filters the honeypot spam check. * * @param bool $is_honeypot_spam Set to `true` if is spam. * @param array $atts Contains `form` and `fields`. */ return apply_filters( 'frm_process_honeypot', $is_honeypot_spam, $atts ); } /** * Check the old frm_verify key. We'll continue to consider any entry with an frm_verify value as spam. * * @return bool */ private function is_legacy_honeypot_spam() { $legacy_honeypot_value = FrmAppHelper::get_param( 'frm_verify', '', 'get', 'sanitize_text_field' ); return '' !== $legacy_honeypot_value; } /** * @return mixed either true, or false. */ private function check_honeypot_filter() { $form = $this->get_form(); return apply_filters( 'frm_run_honeypot', true, compact( 'form' ) ); } /** * @param int $form_id Form ID. * * @return void */ public static function maybe_render_field( $form_id ) { $honeypot = new self( $form_id ); if ( ! $honeypot->should_render_field() ) { return; } $max_field_id = FrmDb::get_var( 'frm_fields', array(), 'id', array( 'order_by' => 'id DESC', ) ); global $frm_vars; $offset = isset( $frm_vars['honeypot_selectors'] ) ? count( $frm_vars['honeypot_selectors'] ) + 1 : 1; $honeypot_field_id = $max_field_id ? $max_field_id + $offset : $offset; $class = class_exists( 'FrmProFormState' ) ? 'FrmProFormState' : 'FrmFormState'; $class::set_initial_value( 'honeypot_field_id', $honeypot_field_id ); $honeypot->render_field( $honeypot_field_id ); self::maybe_print_honeypot_css(); } /** * Maybe print honeypot JS. * * @since 6.21 * * @return void */ public static function maybe_print_honeypot_js() { if ( FrmAppHelper::is_admin() || ! self::is_enabled() ) { return; } $css = self::get_honeypot_field_css(); if ( ! $css ) { return; } // There must be no empty lines inside the script. Otherwise, wpautop adds

tags which break script execution. printf( "", esc_js( $css ) ); global $frm_vars; self::$printed_honeypot_selectors = $frm_vars['honeypot_selectors']; } /** * Maybe print honeypot CSS in case JS doesn't run. * * @since 6.21 * * @return void */ public static function maybe_print_honeypot_css() { // Print the CSS if form is loaded by API. if ( ! FrmFormsHelper::form_is_loaded_by_api() ) { return; } $css = self::get_honeypot_field_css(); if ( $css ) { echo ''; } } /** * Gets honeypot field CSS. * * @return string */ private static function get_honeypot_field_css() { global $frm_vars; if ( empty( $frm_vars['honeypot_selectors'] ) ) { return ''; } $selectors = $frm_vars['honeypot_selectors']; if ( self::$printed_honeypot_selectors ) { $selectors = array_diff( $selectors, self::$printed_honeypot_selectors ); if ( ! $selectors ) { return ''; } } return sprintf( '%s {visibility:hidden;overflow:hidden;width:0;height:0;position:absolute;}', implode( ',', $selectors ) ); } /** * @return bool */ public function should_render_field() { return $this->is_option_on() && $this->check_honeypot_filter(); } /** * @param int $honeypot_field_id * * @return void */ public function render_field( $honeypot_field_id = 0 ) { if ( ! $honeypot_field_id ) { return; } $field_id = $honeypot_field_id; $field_key = $this->get_honeypot_field_key(); $input_attrs = array( 'id' => 'field_' . $field_key, 'type' => 'text', 'class' => 'frm_form_field form-field frm_verify', 'name' => 'item_meta[' . $field_id . ']', 'value' => $this->get_honeypot_field_value( $field_id ), ); $container_id = 'frm_field_' . $field_id . '_container'; $this->track_html_id( $container_id ); // phpcs:disable Generic.WhiteSpace.ScopeIndent ?>

/>
'item_meta', 'default' => array(), 'type' => 'post', ) ); if ( ! $item_meta || ! is_array( $item_meta ) ) { return ''; } return $item_meta[ $field_id ] ?? ''; } /** * Generate a random class name for our honeypot so it is less easy to detect. * * @return string The generated class name. */ public static function generate_class_name() { $class_name = self::get_honeypot_class_name(); if ( 'frm_verify' !== $class_name ) { // Re-use the option. // We can't generate a new class too often or the field may not be hidden. return $class_name; } $prefix = 'frm__'; $class_name = $prefix . uniqid(); update_option( 'frm_honeypot_class', $class_name ); return $class_name; } /** * @return string The current class name to use the for Honeypot field. */ private static function get_honeypot_class_name() { $option = get_option( 'frm_honeypot_class' ); if ( ! is_string( $option ) ) { // For backward compatibility use the old class name. return 'frm_verify'; } return $option; } }