tags which break script execution. printf( "", esc_js( $styles ) ); } /** * Get honeypot field label. * * @since 1.9.0 * * @param array $form_data Form data. */ private function get_honeypot_label( array $form_data ): string { $labels = []; foreach ( $form_data['fields'] ?? [] as $field ) { if ( ! empty( $field['label'] ) ) { $labels[] = $field['label']; } } $words = explode( ' ', implode( ' ', $labels ) ); $count_words = count( $words ); $label_keys = (array) array_rand( $words, min( $count_words, 3 ) ); shuffle( $label_keys ); $label_words = array_map( static function ( $key ) use ( $words ) { return $words[ $key ]; }, $label_keys ); return implode( ' ', $label_words ); } /** * Add strings to the frontend. * * @since 1.9.0 * * @param array|mixed $strings Frontend strings. * * @return array Frontend strings. */ public function add_frontend_strings( $strings ): array { $strings = (array) $strings; // Store the honeypot field ID for validation and adding inline styles. $strings['hn_data'] = $this->forms_data; return $strings; } /** * Validate whether the modern Anti-Spam is enabled. * * @since 1.9.0 * * @param array $form_data Form data. * @param array $fields Fields. * @param array $entry Form submission raw data ($_POST). * * @return bool True if the entry is valid, false otherwise. * @noinspection PhpUnusedParameterInspection */ public function validate( array $form_data, array $fields, array &$entry ): bool { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh // Bail out if the modern Anti-Spam is not enabled. if ( ! $this->is_honeypot_enabled( $form_data ) ) { return true; } $honeypot_fields = array_diff_key( $entry['fields'], $form_data['fields'] ); $is_valid = true; // Compatibility with the WPML plugin (WPFML addon). // In case the form contains an Entry Preview field, they add an extra field with ID 0 to the entry. if ( isset( $entry['fields'][0] ) && defined( 'WPML_WP_FORMS_VERSION' ) && wpforms_has_field_type( 'entry-preview', $form_data ) ) { unset( $honeypot_fields[0] ); } foreach ( $honeypot_fields as $key => $honeypot_field ) { // Remove the honeypot field from the entry. unset( $entry['fields'][ $key ] ); // If the honeypot field is not empty, the entry is invalid. if ( ! empty( $honeypot_field ) ) { $is_valid = false; } } return $is_valid; } /** * Check if the modern Anti-Spam is enabled. * * @since 1.9.0 * * @param array $form_data Form data. * * @return bool True if the modern Anti-Spam is enabled, false otherwise. */ private function is_honeypot_enabled( array $form_data ): bool { static $is_enabled; if ( isset( $is_enabled ) ) { return $is_enabled; } /** * Filters whether the modern Anti-Spam is enabled. * * @since 1.9.0 * * @param bool $is_enabled True if the modern Anti-Spam is enabled, false otherwise. */ $is_enabled = (bool) apply_filters( 'wpforms_forms_anti_spam_v3_is_honeypot_enabled', ! empty( $form_data['settings']['antispam_v3'] ) ); return $is_enabled; } /** * Get the honeypot field ID. * * @since 1.9.0 * * @param array $form_data Form data. * * @return int Honeypot field ID. */ private function get_honeypot_field_id( array $form_data ): int { $max_key = max( array_keys( $form_data['fields'] ) ); // Find the first available field ID. for ( $i = 1; $i <= $max_key; $i++ ) { if ( ! isset( $form_data['fields'][ $i ] ) ) { return $i; } } // If no available field ID found, use the max ID + 1. return $max_key + 1; } /** * Update the form data on the builder settings panel. * * @since 1.9.0 * * @param array|bool $form_data Form data. * * @return array|bool */ public function init_builder_settings_form_data( $form_data ) { if ( ! $form_data ) { return $form_data; } // Update default time limit duration for the existing form. if ( empty( $form_data['settings']['anti_spam']['time_limit']['enable'] ) ) { $form_data['settings']['anti_spam']['time_limit']['duration'] = '2'; } return $form_data; } /** * Update the template form data. Set the modern Anti-Spam setting. * * @since 1.9.0 * * @param array|mixed $form_data Form data. * * @return array */ public function update_template_form_data( $form_data ): array { $form_data = (array) $form_data; // Unset the old Anti-Spam setting. unset( $form_data['settings']['antispam'] ); // Enable the modern Anti-Spam setting. $form_data['settings']['antispam_v3'] = $form_data['settings']['antispam_v3'] ?? '1'; $form_data['settings']['anti_spam'] = $form_data['settings']['anti_spam'] ?? []; // Enable the time limit setting. $form_data['settings']['anti_spam']['time_limit'] = [ 'enable' => '1', 'duration' => '2', ]; return $form_data; } }