Form_Frontend_Submission_Handler::handle_form_submission( awsmug\Torro_Forms\DB_Objects\Forms\Form $form, awsmug\Torro_Forms\DB_Objects\Submissions\Submission $submission, array $data = array() )

Handles a form submission.

Description

Parameters

$form

(awsmug\Torro_Forms\DB_Objects\Forms\Form) (Required) Form object.

$submission

(awsmug\Torro_Forms\DB_Objects\Submissions\Submission) (Required) Submission object.

$data

(array) (Optional) Submission POST data.

Default value: array()

Source

File: src/db-objects/forms/form-frontend-submission-handler.php

	protected function handle_form_submission( $form, $submission, $data = array() ) {
		$container = $submission->get_current_container();
		if ( ! $container ) {
			$submission->add_error( 0, 'internal_error_container', __( 'Internal error: No current container is available for this form.', 'torro-forms' ) );
			$submission->sync_upstream();
			return;
		}

		$old_submission_status = $submission->status;

		/**
		 * Fires before a form submission is handled.
		 *
		 * If you add one or more errors to the submission, the rest of the handling is skipped, essentially making the submission fail.
		 *
		 * @since 1.0.0
		 *
		 * @param Submission $submission Submission object.
		 * @param Form       $form       Form object.
		 * @param Container  $container  Current container object.
		 * @param array      $data       Submission POST data.
		 */
		do_action( "{$this->form_manager->get_prefix()}pre_handle_submission", $submission, $form, $container, $data );

		$submission->sync_upstream();

		if ( $submission->has_errors() ) {
			return;
		}

		$validated = array();
		foreach ( $container->get_elements() as $element ) {
			$fields = isset( $data['values'][ $element->id ] ) ? (array) $data['values'][ $element->id ] : array();

			$validated[ $element->id ] = $element->validate_fields( $fields, $submission );
		}

		// Update existing submission values first.
		$submission_values = $submission->get_submission_values();
		foreach ( $submission_values as $submission_value ) {
			$field = $submission_value->field;
			if ( empty( $field ) ) {
				$field = '_main';
			}

			if ( ! isset( $validated[ $submission_value->element_id ][ $field ] ) ) {
				$submission_value->delete();
				continue;
			}

			$result = $validated[ $submission_value->element_id ][ $field ];

			if ( is_wp_error( $result ) ) {
				$submission->add_error( $submission_value->element_id, $result->get_error_code(), $result->get_error_message() );

				$error_data = $result->get_error_data();
				if ( is_array( $error_data ) && isset( $error_data['validated_value'] ) ) {
					$submission_value->value = $error_data['validated_value'];
					$submission_value->sync_upstream();
				} else {
					$submission_value->delete();
				}

				unset( $validated[ $submission_value->element_id ][ $field ] );
				continue;
			}

			$result = (array) $result;

			$value = array_shift( $result );

			if ( empty( $result ) ) {
				unset( $validated[ $submission_value->element_id ][ $field ] );

				if ( empty( $validated[ $submission_value->element_id ] ) ) {
					unset( $validated[ $submission_value->element_id ] );
				}
			}

			if ( is_wp_error( $value ) ) {
				$submission->add_error( $submission_value->element_id, $value->get_error_code(), $value->get_error_message() );
				$error_data = $value->get_error_data();
				if ( is_array( $error_data ) && isset( $error_data['validated_value'] ) ) {
					$submission_value->value = $error_data['validated_value'];
					$submission_value->sync_upstream();
				} else {
					$submission_value->delete();
				}
			} else {
				$submission_value->value = $value;
				$submission_value->sync_upstream();
			}
		}

		// Add the remaining results as new submission values.
		foreach ( $validated as $element_id => $values ) {
			foreach ( $values as $field => $result ) {
				if ( is_wp_error( $result ) ) {
					$submission->add_error( $element_id, $result->get_error_code(), $result->get_error_message() );

					$error_data = $result->get_error_data();
					if ( is_array( $error_data ) && isset( $error_data['validated_value'] ) ) {
						$this->insert_submission_value( $submission->id, $element_id, $field, $error_data['validated_value'] );
					}

					continue;
				}

				$result = (array) $result;

				foreach ( $result as $value ) {
					if ( is_wp_error( $value ) ) {
						$submission->add_error( $element_id, $value->get_error_code(), $value->get_error_message() );

						$error_data = $value->get_error_data();
						if ( is_array( $error_data ) && isset( $error_data['validated_value'] ) ) {
							$this->insert_submission_value( $submission->id, $element_id, $field, $error_data['validated_value'] );
						}
					} else {
						$this->insert_submission_value( $submission->id, $element_id, $field, $value );
					}
				}
			}
		}

		/**
		 * Fires when a form submission is handled.
		 *
		 * If you add one or more errors to the submission, this will make the submission fail.
		 *
		 * @since 1.0.0
		 *
		 * @param Submission $submission Submission object.
		 * @param Form       $form       Form object.
		 * @param Container  $container  Current container object.
		 * @param array      $data       Submission POST data.
		 */
		do_action( "{$this->form_manager->get_prefix()}handle_submission", $submission, $form, $container, $data );

		if ( $submission->has_errors() ) {
			$submission->sync_upstream();
			return;
		}

		if ( ! empty( $data['action'] ) && 'prev' === $data['action'] ) {
			$previous_container = $submission->get_previous_container();
			if ( $previous_container ) {
				$submission->set_current_container( $previous_container );
			} else {
				$submission->add_error( 0, 'internal_error_previous_container', __( 'Internal error: There is no previous container available.', 'torro-forms' ) );
			}
		} else {
			$next_container = $submission->get_next_container();
			if ( $next_container ) {
				$submission->set_current_container( $next_container );
			} else {
				$submission->set_current_container( null );
				$submission->status = 'completed';
			}
		}

		$submission->sync_upstream();

		if ( 'progressing' === $old_submission_status && 'completed' === $submission->status ) {
			/**
			 * Fires when a form submission is completed.
			 *
			 * At the point of this action, all submission data is already synchronized with the database
			 * and its status is set as 'completed'.
			 *
			 * @since 1.0.0
			 *
			 * @param Submission $submission Submission object.
			 * @param Form       $form       Form object.
			 */
			do_action( "{$this->form_manager->get_prefix()}complete_submission", $submission, $form );
		}
	}

Changelog

Changelog
Version Description
1.0.0 Introduced.