From 4396ddcb46e657d5e22fd5ab04e25e5c6d76aba6 Mon Sep 17 00:00:00 2001 From: colemanw Date: Mon, 10 Feb 2025 08:41:48 -0500 Subject: [PATCH] Afform - DisplayOnly fields cannot be required Fixes dev/core#5710 --- .../core/Civi/Api4/Action/Afform/Submit.php | 9 +++ .../api/v4/Afform/AfformSubmitUsageTest.php | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 ext/afform/mock/tests/phpunit/api/v4/Afform/AfformSubmitUsageTest.php diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Submit.php b/ext/afform/core/Civi/Api4/Action/Afform/Submit.php index bc4942b7a89b..2a35948b6bca 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Submit.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Submit.php @@ -263,8 +263,17 @@ private static function getRequiredFieldError(AfformValidateEvent $event, string if (isset($attributes['defn']['required']) && !$attributes['defn']['required']) { return NULL; } + // InputType set to 'DisplayOnly' which skips validation + if (($attributes['defn']['input_type'] ?? NULL) === 'DisplayOnly') { + return NULL; + } + // Load full field definition, because $attributes['defn'] only has the form markup $fullDefn = FormDataModel::getField($apiEntity, $fieldName, 'create'); + // With the full definition loaded, check input_type again + if (($attributes['defn']['input_type'] ?? $fullDefn['input_type']) === 'DisplayOnly') { + return NULL; + } // we don't need to validate the file fields as it's handled separately if ($fullDefn['input_type'] === 'File') { return NULL; diff --git a/ext/afform/mock/tests/phpunit/api/v4/Afform/AfformSubmitUsageTest.php b/ext/afform/mock/tests/phpunit/api/v4/Afform/AfformSubmitUsageTest.php new file mode 100644 index 000000000000..0fbc0b6f017a --- /dev/null +++ b/ext/afform/mock/tests/phpunit/api/v4/Afform/AfformSubmitUsageTest.php @@ -0,0 +1,60 @@ + + +
+ + +
+ + +EOHTML; + + $this->useValues([ + 'layout' => $layout, + 'permission' => \CRM_Core_Permission::ALWAYS_ALLOW_PERMISSION, + ]); + + $cid = $this->saveTestRecords('Individual', [ + 'records' => [ + ['first_name' => 'One', 'last_name' => 'Person'], + ], + ])->column('id'); + + $prefill = Afform::prefill() + ->setName($this->formName) + ->setFillMode('form') + ->setArgs(['Individual1' => $cid]) + ->execute() + ->indexBy('name'); + $this->assertCount(1, $prefill['Individual1']['values']); + $this->assertEquals('One', $prefill['Individual1']['values'][0]['fields']['first_name']); + $this->assertEquals('Person', $prefill['Individual1']['values'][0]['fields']['last_name']); + + // Submit with empty first_name: should not hit a validation error because DisplayOnly fields cannot be required + $submission = [ + ['fields' => ['last_name' => 'Person']], + ]; + $result = Afform::submit() + ->setName($this->formName) + ->setValues(['Individual1' => $submission]) + ->setArgs(['Individual1' => $cid]) + ->execute(); + $this->assertSame($cid[0], $result[0]['Individual1'][0]['id']); + } + +}