I'm updating Webform REST to use the new submission API introduced here: #2871886: Provide an API to programmatically validate and submit a webform submission

I've run into a few problems.

Example Code

The example code suggests the following:

// Check that the webform is open.
$webform = \Drupal\webform\entity\Webform::load('initial_screening'); 
$is_open = \Drupal\webform\WebformSubmissionForm::isOpen($values);

I believe this should be:

// Check that the webform is open.
$webform = \Drupal\webform\entity\Webform::load('initial_screening'); 
$is_open = \Drupal\webform\WebformSubmissionForm::isOpen($webform);

Validation

Without looking into it in any great detail, validation seems too lenient. For example, I have a number of taxonomy reference fields which seem to validate OK even if the term ID is not within the specified vocabulary.

Current working code which picks up invalid taxonomy IDs:

    // Create webform submission object.
    $webform_submission = WebformSubmission::create(['webform_id' => $webform_data['webform_id']]);

    // Don't submit webform ID.
    unset($webform_data['webform_id']);

    // Get the form object.
    $entity_form_object = \Drupal::entityTypeManager()
      ->getFormObject('webform_submission', 'default');
    $entity_form_object->setEntity($webform_submission);

    // Initialize the form state.
    $form_state = (new FormState())->setValues($webform_data);

    // Submit form.
    \Drupal::formBuilder()->submitForm($entity_form_object, $form_state);

    $errors = $form_state->getErrors();

    // Check there are no validation errors.
    if (!empty($errors)) {
      $errors = ['error' => $errors];
      return new ResourceResponse($errors);
    }

New code which validates even with invalid selections:

    if ($is_open === TRUE) {
      // Validate submission.
      $errors = \Drupal\webform\WebformSubmissionForm::validateValues($values);

      // Check there are no validation errors.
      if (!empty($errors)) {
        $errors = ['error' => $errors];
        return new ResourceResponse($errors);
      }
      else {
        $webform_submission = \Drupal\webform\WebformSubmissionForm::submitValues($values);
        return new ResourceResponse(['sid' => $webform_submission->id()]);
      }

    }

Viewing Submissions

After a successful submission using invalid term IDs, I can no longer view submissions for that webform. The error is presumably related to trying to get the label of a non existent taxonomy term:

 PHP Fatal error:  Call to a member function label() on a non-object in /modules/webform/src/Plugin/WebformElement/WebformEntityReferenceTrait.php on line 68, referer: http://local/admin/structure/webform

Submission data

$values array:

Array
(
    [webform_id] => initial_screening
    [entity_type] => 
    [entity_id] => 
    [in_draft] => 
    [uri] => /webform/initial_screening/api
    [data] => Array
        (
            [user_session] => 9
            [substances] => Array
                (
                    [0] => 35
                )

            [age] => 134
            [gender] => 13
        )

)

Comments

imclean created an issue. See original summary.

imclean’s picture

Issue summary: View changes
imclean’s picture

The main difference seems to be where the webform values are added to the submission. In the first example they're added to $form_state:

// Initialize the form state.
$form_state = (new FormState())->setValues($webform_data);

In the second example, in WebformSubmissionForm.php, they're added to the webform submission:

$webform_submission = WebformSubmission::create($values);

Should values be set in $form_state instead? See FormBuilder::submitForm

imclean’s picture

Title: Problem with new submission API » Validation problem with new submission API
imclean’s picture

Status: Active » Needs review
StatusFileSize
new567 bytes

This resolves the validation issues.

jrockowitz’s picture

@imclean the issue is that a submission's data and form state values are not the same for all elements, especially checkboxes.


# submission values
$values = [
  'checkboxes' => [
    'one',
    'two',
  ],
];

# form state values
$values = [
  'checkboxes' => [
    'one' => 'one',
    'two' => 'two',
  ],
];

I am hoping to just populate the webform submission data and use the form's methods to populate the form state values.

The taxonomy term validation issue might just be a general bug.

imclean’s picture

I did wonder if I was using the correct structure. I'm currently using the "submission values" structure in your example which seems to work when setting the values in $form_state. The numeric indexes in the "substances" array are created by PHP.

Testing so far has been restricted to my specific needs so may not be broad enough.

jrockowitz’s picture

I added an API tab to each Webform's Test tab which should make it easier for us to replicate other use cases and document validation issues.

imclean’s picture

That's the format I'm using and it seems to work with from state.

As mentioned above, I think there's an error in the example in the $is_open line.

imclean’s picture

The taxonomy term validation issue might just be a general bug.

With taxonomy or all reference fields? Form state values validate ok so something's a bit different there.

  • jrockowitz committed 2586c9f on 8.x-5.x authored by imclean
    Issue #2873492 by imclean: Validation problem with new submission API
    

  • jrockowitz committed befd191 on 2873492-form-api-validation
    Issue #2873492 by imclean: Validation problem with new submission API
    

  • jrockowitz committed 2586c9f on 2873492-form-api-validation authored by imclean
    Issue #2873492 by imclean: Validation problem with new submission API
    

  • jrockowitz committed ae23853 on 8.x-5.x authored by imclean
    Issue #2873492 by imclean: Validation problem with new submission API
    
jrockowitz’s picture

Status: Needs review » Postponed (maintainer needs more info)

@imclean I committed the patch.

Please upload an example form that I can use reproduce your issues.

imclean’s picture

Status: Postponed (maintainer needs more info) » Active
StatusFileSize
new3.01 KB
new161 bytes
new169 bytes

@jrockowitz, here's an example form using 2 taxonomy reference fields and also the vocabulary configs. Just add a few terms to each. If it makes any difference, our term IDs aren't sequential:

Substances: 16, 18, 19, 35 etc.

Age Range: 6, 7, 8, 9, 10

What we were finding is that we could submit 19 as a response to Age Range and it would be accepted.

imclean’s picture

StatusFileSize
new169 bytes

Ignore gender.yml, here's substances config.

  • jrockowitz committed 2586c9f on 2873492-validation-submission-api authored by imclean
    Issue #2873492 by imclean: Validation problem with new submission API
    
  • jrockowitz committed ae23853 on 2873492-validation-submission-api authored by imclean
    Issue #2873492 by imclean: Validation problem with new submission API
    

  • jrockowitz committed 6995289 on 2873492-validation-submission-api
    Issue #2873492 by imclean: Validation problem with new submission API
    

  • jrockowitz committed 7808ab6 on 2873492-validation-submission-api
    Issue #2873492 by imclean: Validation problem with new submission API
    
jrockowitz’s picture

Status: Active » Needs review
StatusFileSize
new7.92 KB

The #options validation handling was not being triggered because #needs_validation was not set.

imclean’s picture

Looks good. Invalid options are now failing to validate.

  • jrockowitz committed e1a6385 on 8.x-5.x
    Issue #2873492 by imclean, jrockowitz: Validation problem with new...
jrockowitz’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.