forms" is ticked, skips spam, drafts and failed * submissions where the plugin says so, and never throws into the form plugin. * * @package Wapadesk */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** Runs a handler only when the plugin's forms are switched on; errors are recorded, never thrown. */ function wapadesk_guard( $plugin, $callback ) { if ( ! wapadesk_form_enabled( $plugin, '*' ) ) { return; } try { $callback(); } catch ( Throwable $e ) { wapadesk_status_error( $plugin . ': ' . $e->getMessage() ); } } /** The page the form was sent from: the post being viewed, else the referring page. */ function wapadesk_page_url( $post_id = 0 ) { $post_id = (int) $post_id; if ( $post_id > 0 ) { $url = get_permalink( $post_id ); if ( is_string( $url ) ) { return $url; } } return (string) wp_get_referer(); } // Ninja Forms: after validation and all form actions (Submission.php, ninja_forms_after_submission). add_action( 'ninja_forms_after_submission', 'wapadesk_ninjaforms', 20, 1 ); function wapadesk_ninjaforms( $data ) { wapadesk_guard( 'ninjaforms', function () use ( $data ) { $fields = array(); foreach ( isset( $data['fields'] ) ? (array) $data['fields'] : array() as $id => $f ) { if ( ! is_array( $f ) || in_array( isset( $f['type'] ) ? $f['type'] : '', array( 'submit', 'html', 'hr', 'spam', 'recaptcha', 'hidden' ), true ) ) { continue; } $fields[] = wapadesk_field( isset( $f['key'] ) ? $f['key'] : $id, isset( $f['label'] ) ? $f['label'] : '', isset( $f['type'] ) ? $f['type'] : 'text', isset( $f['value'] ) ? $f['value'] : '' ); } $form_id = isset( $data['form_id'] ) ? $data['form_id'] : ''; $title = isset( $data['settings']['title'] ) ? $data['settings']['title'] : ''; wapadesk_capture( 'ninjaforms', $form_id, $title, $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // Formidable Forms: after the entry is saved (FrmEntry.php, frm_after_create_entry). Child entries are skipped. add_action( 'frm_after_create_entry', 'wapadesk_formidable', 30, 3 ); function wapadesk_formidable( $entry_id, $form_id, $args = array() ) { wapadesk_guard( 'formidable', function () use ( $entry_id, $form_id, $args ) { if ( ( is_array( $args ) && ! empty( $args['is_child'] ) ) || ! class_exists( 'FrmField' ) || ! class_exists( 'FrmEntry' ) ) { return; } $entry = FrmEntry::getOne( $entry_id, true ); $metas = is_object( $entry ) && isset( $entry->metas ) ? (array) $entry->metas : array(); $fields = array(); foreach ( (array) FrmField::get_all_for_form( $form_id ) as $field ) { if ( ! is_object( $field ) || ! isset( $metas[ $field->id ] ) || in_array( $field->type, array( 'submit', 'html', 'captcha', 'hidden', 'divider', 'break', 'end_divider' ), true ) ) { continue; } $value = $metas[ $field->id ]; if ( is_array( $value ) && in_array( $field->type, array( 'name', 'address' ), true ) ) { $value = implode( ' ', array_filter( array_map( 'strval', $value ) ) ); } $fields[] = wapadesk_field( $field->id, $field->name, $field->type, $value ); } $form = class_exists( 'FrmForm' ) ? FrmForm::getOne( $form_id ) : null; $title = is_object( $form ) && isset( $form->name ) ? $form->name : ''; wapadesk_capture( 'formidable', $form_id, $title, $fields, 'entry-' . $entry_id, wapadesk_page_url() ); } ); } // Fluent Forms: after the entry is stored (SubmissionHandlerService.php, fluentform/submission_inserted). add_action( 'fluentform/submission_inserted', 'wapadesk_fluentforms', 20, 3 ); function wapadesk_fluentforms( $insert_id, $form_data, $form ) { wapadesk_guard( 'fluentforms', function () use ( $insert_id, $form_data, $form ) { $inputs = array(); if ( class_exists( '\FluentForm\App\Modules\Form\FormFieldsParser' ) && is_object( $form ) ) { $inputs = (array) \FluentForm\App\Modules\Form\FormFieldsParser::getInputs( $form, array( 'admin_label', 'element', 'raw' ) ); } $fields = array(); foreach ( (array) $form_data as $name => $value ) { if ( '_' === substr( (string) $name, 0, 1 ) || in_array( $name, array( 'g-recaptcha-response', 'cf-turnstile-response', 'h-captcha-response' ), true ) ) { continue; } $meta = isset( $inputs[ $name ] ) ? (array) $inputs[ $name ] : array(); $type = isset( $meta['element'] ) ? $meta['element'] : 'text'; $label = ! empty( $meta['admin_label'] ) ? $meta['admin_label'] : wapadesk_humanise( $name ); // The name field (element input_name, default key "names") holds first_name / last_name. if ( is_array( $value ) && ( 'input_name' === $type || isset( $value['first_name'] ) || isset( $value['last_name'] ) ) ) { $value = implode( ' ', array_filter( array_map( 'strval', $value ) ) ); $label = 'Name'; $type = 'name'; } $fields[] = wapadesk_field( $name, $label, $type, $value ); } $form_id = is_object( $form ) && isset( $form->id ) ? $form->id : ''; $title = is_object( $form ) && isset( $form->title ) ? $form->title : ''; wapadesk_capture( 'fluentforms', $form_id, $title, $fields, 'entry-' . $insert_id, wapadesk_page_url() ); } ); } // Forminator: the fields are read before saving, and sent only when the save succeeded // (abstract-class-front-action.php; spam, drafts and abandoned forms use other hooks). $GLOBALS['wapadesk_forminator'] = array(); add_action( 'forminator_custom_form_submit_before_set_fields', 'wapadesk_forminator_fields', 20, 3 ); function wapadesk_forminator_fields( $entry, $form_id, $field_data_array ) { if ( ! wapadesk_form_enabled( 'forminator', '*' ) ) { return; } $fields = array(); foreach ( (array) $field_data_array as $f ) { if ( ! is_array( $f ) || ! isset( $f['name'] ) ) { continue; } $name = (string) $f['name']; // Forminator names fields "-", e.g. email-1, phone-1, name-1. $type = preg_replace( '/-\d+$/', '', $name ); $value = isset( $f['value'] ) ? $f['value'] : ''; if ( is_array( $value ) && in_array( $type, array( 'name', 'address' ), true ) ) { $value = implode( ' ', array_filter( array_map( 'strval', $value ) ) ); } if ( in_array( $type, array( 'captcha', 'html', 'section', 'page-break', 'hidden', 'stripe', 'paypal' ), true ) ) { continue; } $fields[] = wapadesk_field( $name, ucfirst( str_replace( '-', ' ', $type ) ), $type, $value ); } $GLOBALS['wapadesk_forminator'][ (string) $form_id ] = $fields; } add_action( 'forminator_form_after_save_entry', 'wapadesk_forminator_saved', 20, 3 ); function wapadesk_forminator_saved( $form_id, $response, $entry_id = 0 ) { wapadesk_guard( 'forminator', function () use ( $form_id, $response, $entry_id ) { $fields = isset( $GLOBALS['wapadesk_forminator'][ (string) $form_id ] ) ? $GLOBALS['wapadesk_forminator'][ (string) $form_id ] : array(); unset( $GLOBALS['wapadesk_forminator'][ (string) $form_id ] ); if ( ! is_array( $response ) || empty( $response['success'] ) || empty( $fields ) ) { return; } $title = (string) get_the_title( (int) $form_id ); wapadesk_capture( 'forminator', $form_id, $title, $fields, $entry_id ? 'entry-' . $entry_id : wp_generate_uuid4(), wapadesk_page_url() ); } ); } // Everest Forms: after validation, entry save and email (class-evf-form-task.php, everest_forms_process_complete). add_action( 'everest_forms_process_complete', 'wapadesk_everest', 20, 4 ); function wapadesk_everest( $fields_in, $entry, $form_data, $entry_id ) { wapadesk_guard( 'everest', function () use ( $fields_in, $form_data, $entry_id ) { $fields = array(); foreach ( (array) $fields_in as $id => $f ) { if ( ! is_array( $f ) ) { continue; } $fields[] = wapadesk_field( $id, isset( $f['name'] ) ? $f['name'] : '', isset( $f['type'] ) ? $f['type'] : 'text', isset( $f['value'] ) ? $f['value'] : '' ); } $form_id = isset( $form_data['id'] ) ? $form_data['id'] : ''; $title = isset( $form_data['settings']['form_title'] ) ? $form_data['settings']['form_title'] : ''; wapadesk_capture( 'everest', $form_id, $title, $fields, $entry_id ? 'entry-' . $entry_id : wp_generate_uuid4(), wapadesk_page_url() ); } ); } // Jetpack Forms: after the feedback post is saved (class-contact-form.php); spam is skipped. add_action( 'grunion_after_feedback_post_inserted', 'wapadesk_jetpack', 20, 4 ); function wapadesk_jetpack( $post_id, $visible_fields = array(), $is_spam = false, $entry_values = array() ) { wapadesk_guard( 'jetpack', function () use ( $post_id, $is_spam, $entry_values ) { $class = '\Automattic\Jetpack\Forms\ContactForm\Feedback'; if ( $is_spam || ! class_exists( $class ) ) { return; } $feedback = $class::get( $post_id ); if ( ! is_object( $feedback ) ) { return; } $fields = array(); foreach ( (array) $feedback->get_fields() as $f ) { if ( ! is_object( $f ) ) { continue; } $fields[] = wapadesk_field( $f->get_form_field_id(), $f->get_label(), $f->get_type(), $f->get_value() ); } $form_id = method_exists( $feedback, 'get_form_id' ) ? (string) $feedback->get_form_id() : ''; $title = is_array( $entry_values ) && isset( $entry_values['entry_title'] ) ? 'Form on ' . $entry_values['entry_title'] : 'Jetpack form'; wapadesk_capture( 'jetpack', '' !== $form_id ? $form_id : 'inline', $title, $fields, 'feedback-' . $post_id, wapadesk_page_url() ); } ); } // Kadence Blocks: the basic form block (form-ajax.php) and the advanced form (advanced-form-ajax.php). add_action( 'kadence_blocks_form_submission', 'wapadesk_kadence', 20, 4 ); function wapadesk_kadence( $form_args, $fields_in, $form_id, $post_id ) { wapadesk_guard( 'kadence', function () use ( $fields_in, $form_id, $post_id ) { $fields = array(); foreach ( (array) $fields_in as $i => $f ) { if ( is_array( $f ) ) { $fields[] = wapadesk_field( 'f' . $i, isset( $f['label'] ) ? $f['label'] : '', isset( $f['type'] ) ? $f['type'] : 'text', isset( $f['value'] ) ? $f['value'] : '' ); } } $page = (string) get_the_title( (int) $post_id ); wapadesk_capture( 'kadence', $form_id, '' !== $page ? 'Form on ' . $page : 'Kadence form', $fields, wp_generate_uuid4(), wapadesk_page_url( $post_id ) ); } ); } add_action( 'kadence_blocks_advanced_form_submission', 'wapadesk_kadence_advanced', 20, 3 ); function wapadesk_kadence_advanced( $form_args, $processed_fields, $post_id ) { wapadesk_guard( 'kadence', function () use ( $processed_fields, $post_id ) { $fields = array(); foreach ( (array) $processed_fields as $i => $f ) { if ( is_array( $f ) ) { $id = ! empty( $f['uniqueID'] ) ? $f['uniqueID'] : ( ! empty( $f['name'] ) ? $f['name'] : 'f' . $i ); $fields[] = wapadesk_field( $id, isset( $f['label'] ) ? $f['label'] : '', isset( $f['type'] ) ? $f['type'] : 'text', isset( $f['value'] ) ? $f['value'] : '' ); } } wapadesk_capture( 'kadence', $post_id, (string) get_the_title( (int) $post_id ), $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // Spectra form block: label => value, after Spectra's own email was sent (class-uagb-forms.php). add_action( 'uagb_form_success', 'wapadesk_spectra', 20, 1 ); function wapadesk_spectra( $form_data ) { wapadesk_guard( 'spectra', function () use ( $form_data ) { $fields = array(); foreach ( (array) $form_data as $label => $value ) { $fields[] = wapadesk_field( sanitize_title( $label ), $label, is_string( $value ) && is_email( trim( $value ) ) ? 'email' : 'text', $value ); } // phpcs:disable WordPress.Security.NonceVerification.Missing -- Spectra checked its nonce before this action. $block = isset( $_POST['block_id'] ) ? sanitize_key( wp_unslash( $_POST['block_id'] ) ) : 'form'; $post = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0; // phpcs:enable $page = $post ? (string) get_the_title( $post ) : ''; wapadesk_capture( 'spectra', $block, '' !== $page ? 'Form on ' . $page : 'Spectra form', $fields, wp_generate_uuid4(), wapadesk_page_url( $post ) ); } ); } // Beaver Builder contact form module (Pro): a fixed set of fields, after its email (fl_module_contact_form_after_send). add_action( 'fl_module_contact_form_after_send', 'wapadesk_beaver', 20, 6 ); function wapadesk_beaver( $mailto, $subject, $template, $headers, $settings, $result ) { wapadesk_guard( 'beaver', function () { $fields = array(); // phpcs:disable WordPress.Security.NonceVerification.Missing -- Beaver Builder checked the request before sending. foreach ( array( 'name' => 'Name', 'email' => 'Email', 'phone' => 'Phone', 'subject' => 'Subject', 'message' => 'Message', ) as $key => $label ) { if ( isset( $_POST[ $key ] ) ) { $fields[] = wapadesk_field( $key, $label, 'message' === $key ? 'textarea' : $key, sanitize_textarea_field( wp_unslash( $_POST[ $key ] ) ) ); } } $node = isset( $_POST['node_id'] ) ? sanitize_key( wp_unslash( $_POST['node_id'] ) ) : 'form'; // phpcs:enable wapadesk_capture( 'beaver', $node, 'Beaver Builder contact form', $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // WS Form: after the form's actions; partial saves are skipped (class-ws-form-api-submit.php, wsf_submit_post_complete). add_action( 'wsf_submit_post_complete', 'wapadesk_wsform', 20, 1 ); function wapadesk_wsform( $submit ) { wapadesk_guard( 'wsform', function () use ( $submit ) { if ( ! is_object( $submit ) || ( isset( $submit->post_mode ) && 'submit' !== $submit->post_mode ) ) { return; } $fields = array(); foreach ( isset( $submit->meta ) ? (array) $submit->meta : array() as $key => $m ) { if ( 0 !== strpos( (string) $key, 'field_' ) || ! is_array( $m ) ) { continue; } $label = ''; if ( function_exists( 'wsf_field_get_object' ) && isset( $submit->form_object, $m['id'] ) ) { $obj = wsf_field_get_object( $submit->form_object, $m['id'] ); $label = is_object( $obj ) && isset( $obj->label ) ? $obj->label : ''; } $fields[] = wapadesk_field( $key, $label, isset( $m['type'] ) ? $m['type'] : 'text', isset( $m['value'] ) ? $m['value'] : '' ); } $form_id = isset( $submit->form_id ) ? $submit->form_id : ''; $title = function_exists( 'wsf_form_get_label_by_id' ) ? (string) wsf_form_get_label_by_id( $form_id ) : ''; wapadesk_capture( 'wsform', $form_id, $title, $fields, isset( $submit->id ) ? 'entry-' . $submit->id : wp_generate_uuid4(), wapadesk_page_url() ); } ); } // MetForm: after validation and storing (core/entries/action.php, metform_after_store_form_data). add_action( 'metform_after_store_form_data', 'wapadesk_metform', 20, 4 ); function wapadesk_metform( $form_id, $form_data, $form_settings, $attributes ) { wapadesk_guard( 'metform', function () use ( $form_id, $form_data ) { $map = array(); if ( class_exists( '\MetForm\Core\Entries\Action' ) ) { $map = (array) \MetForm\Core\Entries\Action::instance()->get_fields( $form_id ); } $fields = array(); foreach ( (array) $form_data as $name => $value ) { if ( ! isset( $map[ $name ] ) ) { continue; // Only the form's own inputs, not nonces or internal keys. } $meta = (array) $map[ $name ]; $label = ! empty( $meta['mf_input_label'] ) ? $meta['mf_input_label'] : wapadesk_humanise( $name ); $type = isset( $meta['widgetType'] ) ? preg_replace( '/^mf-/', '', $meta['widgetType'] ) : 'text'; $type = 'gdpr-consent' === $type ? 'consent' : $type; $fields[] = wapadesk_field( $name, $label, $type, $value ); } wapadesk_capture( 'metform', $form_id, (string) get_the_title( (int) $form_id ), $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // JetFormBuilder: after the form's actions; failed submissions are skipped (form-handler.php). add_action( 'jet-form-builder/form-handler/after-send', 'wapadesk_jetformbuilder', 20, 2 ); function wapadesk_jetformbuilder( $handler, $is_success ) { wapadesk_guard( 'jetformbuilder', function () use ( $handler, $is_success ) { if ( ! $is_success || ! function_exists( 'jet_fb_context' ) ) { return; } $context = jet_fb_context(); $fields = array(); foreach ( (array) $context->get_request() as $name => $value ) { $type = method_exists( $context, 'get_field_type' ) ? (string) $context->get_field_type( $name ) : 'text'; $label = method_exists( $context, 'get_setting' ) ? (string) $context->get_setting( 'label', $name ) : ''; $fields[] = wapadesk_field( $name, '' !== $label ? $label : wapadesk_humanise( $name ), '' !== $type ? $type : 'text', $value ); } $form_id = is_object( $handler ) && method_exists( $handler, 'get_form_id' ) ? $handler->get_form_id() : ''; wapadesk_capture( 'jetformbuilder', $form_id, (string) get_the_title( (int) $form_id ), $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // HappyForms: after validation and email; spambots never reach it (class-message-controller.php). add_action( 'happyforms_submission_success', 'wapadesk_happyforms', 20, 3 ); function wapadesk_happyforms( $submission, $form, $extra = array() ) { wapadesk_guard( 'happyforms', function () use ( $submission, $form ) { $fields = array(); foreach ( isset( $form['parts'] ) ? (array) $form['parts'] : array() as $part ) { $id = isset( $part['id'] ) ? $part['id'] : ''; if ( '' === $id || ! isset( $submission[ $id ] ) ) { continue; } $fields[] = wapadesk_field( $id, isset( $part['label'] ) ? $part['label'] : '', isset( $part['type'] ) ? $part['type'] : 'text', $submission[ $id ] ); } wapadesk_capture( 'happyforms', isset( $form['ID'] ) ? $form['ID'] : '', isset( $form['post_title'] ) ? $form['post_title'] : '', $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // weForms: after the entry is inserted (class-ajax.php, weforms_entry_submission). add_action( 'weforms_entry_submission', 'wapadesk_weforms', 20, 4 ); function wapadesk_weforms( $entry_id, $form_id, $page_id, $form_settings ) { wapadesk_guard( 'weforms', function () use ( $entry_id, $form_id, $page_id ) { if ( ! function_exists( 'weforms_get_entry_data' ) ) { return; } $data = weforms_get_entry_data( $entry_id ); $meta = isset( $data['fields'] ) ? (array) $data['fields'] : array(); $values = isset( $data['data'] ) ? (array) $data['data'] : array(); $fields = array(); foreach ( $meta as $key => $m ) { if ( ! isset( $values[ $key ] ) ) { continue; } $fields[] = wapadesk_field( $key, isset( $m['label'] ) ? $m['label'] : $key, isset( $m['type'] ) ? $m['type'] : 'text', $values[ $key ] ); } wapadesk_capture( 'weforms', $form_id, (string) get_the_title( (int) $form_id ), $fields, 'entry-' . $entry_id, wapadesk_page_url( $page_id ) ); } ); } // Otter Blocks form: after the record is saved and the email sent (class-form-server.php, otter_form_after_submit). add_action( 'otter_form_after_submit', 'wapadesk_otter', 20, 1 ); function wapadesk_otter( $form_data ) { wapadesk_guard( 'otter', function () use ( $form_data ) { if ( ! is_object( $form_data ) || ! method_exists( $form_data, 'get_fields' ) ) { return; } $fields = array(); foreach ( (array) $form_data->get_fields() as $i => $f ) { $f = (array) $f; if ( ! isset( $f['value'] ) ) { continue; } $fields[] = wapadesk_field( 'f' . $i, isset( $f['label'] ) ? $f['label'] : '', isset( $f['type'] ) ? $f['type'] : 'text', $f['value'] ); } $id = method_exists( $form_data, 'get_form_option_id' ) ? (string) $form_data->get_form_option_id() : 'form'; wapadesk_capture( 'otter', '' !== $id ? $id : 'form', 'Otter form', $fields, wp_generate_uuid4(), wapadesk_page_url() ); } ); } // SureForms: label => value after a successful submit (form-submit.php, srfm_form_submit). add_action( 'srfm_form_submit', 'wapadesk_sureforms', 20, 1 ); function wapadesk_sureforms( $response ) { wapadesk_guard( 'sureforms', function () use ( $response ) { $response = (array) $response; $fields = array(); foreach ( isset( $response['data'] ) ? (array) $response['data'] : array() as $label => $value ) { $hint = strtolower( (string) $label ); $type = is_string( $value ) && is_email( trim( $value ) ) ? 'email' : ( preg_match( '/phone|mobile|tel\b/', $hint ) ? 'phone' : 'text' ); $fields[] = wapadesk_field( sanitize_title( $label ), $label, $type, $value ); } $form_id = isset( $response['form_id'] ) ? $response['form_id'] : ''; $entry_id = isset( $response['entry_id'] ) ? (int) $response['entry_id'] : 0; wapadesk_capture( 'sureforms', $form_id, isset( $response['form_name'] ) ? $response['form_name'] : '', $fields, $entry_id ? 'entry-' . $entry_id : wp_generate_uuid4(), wapadesk_page_url() ); } ); }