get( 'form' )->get()` and `wpforms_get_form_fields()`; * each field has `id`, `type`, `label` and, for Name, `format` * (simple / first-last / first-middle-last). * * @package Emails404 */ namespace Emails404\Providers; if ( ! defined( 'ABSPATH' ) ) { exit; } use Emails404\Form_Connections; use Emails404\Form_Source_Interface; class WPForms_Provider implements Form_Source_Interface { const SLUG = 'wpforms'; public function get_slug() { return self::SLUG; } public function get_label() { return 'WPForms'; } public function is_available() { return function_exists( 'wpforms' ); } public function register_hooks() { add_action( 'wpforms_process_complete', array( $this, 'handle_submission' ), 10, 4 ); } public function list_forms() { $handler = $this->form_handler(); if ( ! $handler ) { return array(); } $posts = $handler->get( '', array( 'posts_per_page' => -1 ) ); $forms = array(); foreach ( is_array( $posts ) ? $posts : array() as $post ) { if ( isset( $post->ID ) ) { $forms[] = $this->describe_post( $post ); } } return $forms; } public function describe_form( $form_id ) { $handler = $this->form_handler(); if ( ! $handler || ! ctype_digit( (string) $form_id ) ) { return null; } $post = $handler->get( (int) $form_id ); return is_object( $post ) && isset( $post->ID ) ? $this->describe_post( $post ) : null; } /** * @param array $fields Processed fields, keyed by field id. * @param array $entry The raw $_POST (not used). * @param array $form_data The form's settings and fields. * @param int $entry_id 0 without saved entries. */ public function handle_submission( $fields, $entry, $form_data, $entry_id = 0 ) { if ( ! is_array( $fields ) || ! is_array( $form_data ) || empty( $form_data['id'] ) ) { return; } $form = self::describe_form_data( (string) $form_data['id'], isset( $form_data['settings']['form_title'] ) ? (string) $form_data['settings']['form_title'] : '', isset( $form_data['fields'] ) && is_array( $form_data['fields'] ) ? $form_data['fields'] : array() ); Form_Connections::receive( $this, (string) $form_data['id'], self::values_from_fields( $fields ), (int) $entry_id > 0 ? 'entry-' . (int) $entry_id : wp_generate_uuid4(), $form ); } /** Field id => value, plus "{id}.first" / "{id}.last" for Name fields. */ public static function values_from_fields( array $fields ) { $values = array(); foreach ( $fields as $id => $field ) { if ( ! is_array( $field ) ) { continue; } $values[ (string) $id ] = isset( $field['value'] ) ? $field['value'] : ''; foreach ( array( 'first', 'last' ) as $part ) { if ( isset( $field[ $part ] ) ) { $values[ $id . '.' . $part ] = $field[ $part ]; } } } return $values; } /** * @param string $id * @param string $title * @param array $form_fields The form's fields (form_data['fields'] / wpforms_get_form_fields()). */ public static function describe_form_data( $id, $title, array $form_fields ) { $fields = array(); foreach ( $form_fields as $field ) { if ( ! is_array( $field ) || ! isset( $field['id'] ) ) { continue; } $key = (string) $field['id']; $type = isset( $field['type'] ) ? (string) $field['type'] : ''; $label = isset( $field['label'] ) ? (string) $field['label'] : ''; $choices = isset( $field['choices'] ) && is_array( $field['choices'] ) ? array_values( $field['choices'] ) : array(); $choice = isset( $choices[0]['label'] ) ? trim( wp_strip_all_tags( (string) $choices[0]['label'] ) ) : ''; if ( 'email' === $type ) { $fields[] = array( 'key' => $key, 'label' => $label, 'kind' => Form_Connections::KIND_EMAIL ); } elseif ( 'name' === $type ) { $format = isset( $field['format'] ) ? (string) $field['format'] : 'first-last'; if ( 'simple' === $format ) { $fields[] = array( 'key' => $key, 'label' => $label, 'kind' => Form_Connections::KIND_FULL_NAME ); } else { $fields[] = array( 'key' => $key . '.first', 'label' => $label, 'kind' => Form_Connections::KIND_FIRST_NAME ); $fields[] = array( 'key' => $key . '.last', 'label' => $label, 'kind' => Form_Connections::KIND_LAST_NAME ); } } elseif ( 'gdpr-checkbox' === $type ) { // The agreement wording is its one choice's label. $fields[] = array( 'key' => $key, 'label' => '' !== $choice ? $choice : $label, 'kind' => Form_Connections::KIND_CONSENT ); } elseif ( 'checkbox' === $type ) { $fields[] = array( 'key' => $key, 'label' => 1 === count( $choices ) && '' !== $choice ? $choice : $label, 'kind' => Form_Connections::KIND_CONSENT ); } elseif ( 'text' === $type ) { $fields[] = array( 'key' => $key, 'label' => $label, 'kind' => Form_Connections::kind_from_words( '', $label ) ); } } return array( 'id' => (string) $id, 'title' => '' !== $title ? $title : '#' . $id, 'fields' => $fields, ); } private function describe_post( $post ) { $form_fields = function_exists( 'wpforms_get_form_fields' ) ? wpforms_get_form_fields( $post ) : array(); if ( ! is_array( $form_fields ) || ! $form_fields ) { $data = json_decode( (string) $post->post_content, true ); $form_fields = isset( $data['fields'] ) && is_array( $data['fields'] ) ? $data['fields'] : array(); } return self::describe_form_data( (string) $post->ID, (string) $post->post_title, $form_fields ); } /** WPForms' form handler: `wpforms()->get( 'form' )` (current) or `wpforms()->form` (older). */ private function form_handler() { if ( ! $this->is_available() ) { return null; } $wpforms = wpforms(); if ( is_object( $wpforms ) && method_exists( $wpforms, 'get' ) ) { $handler = $wpforms->get( 'form' ); if ( is_object( $handler ) ) { return $handler; } } return is_object( $wpforms ) && isset( $wpforms->form ) && is_object( $wpforms->form ) ? $wpforms->form : null; } }