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
)
)
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | validation_problem_with-2873492-20.patch | 7.92 KB | jrockowitz |
| #17 | substances.yml | 169 bytes | imclean |
| #16 | age_range.yml | 169 bytes | imclean |
| #16 | gender.yml | 161 bytes | imclean |
| #16 | initial_screening.yml | 3.01 KB | imclean |
Comments
Comment #2
imclean commentedComment #3
imclean commentedThe main difference seems to be where the webform values are added to the submission. In the first example they're added to
$form_state:In the second example, in
WebformSubmissionForm.php, they're added to the webform submission:Should values be set in
$form_stateinstead? See FormBuilder::submitFormComment #4
imclean commentedComment #5
imclean commentedThis resolves the validation issues.
Comment #6
jrockowitz commented@imclean the issue is that a submission's data and form state values are not the same for all elements, especially checkboxes.
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.
Comment #7
imclean commentedI 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.
Comment #8
jrockowitz commentedI 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.
Comment #9
imclean commentedThat'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_openline.Comment #10
imclean commentedWith taxonomy or all reference fields? Form state values validate ok so something's a bit different there.
Comment #15
jrockowitz commented@imclean I committed the patch.
Please upload an example form that I can use reproduce your issues.
Comment #16
imclean commented@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.
Comment #17
imclean commentedIgnore gender.yml, here's substances config.
Comment #21
jrockowitz commentedThe #options validation handling was not being triggered because #needs_validation was not set.
Comment #22
imclean commentedLooks good. Invalid options are now failing to validate.
Comment #24
jrockowitz commented