fix: accept the German W as a gender on the application endpoint
This commit is contained in:
1 parent
5141673bcd
commit
e460b18661
3 files changed
+107
-5
No files matched your search
@@ -39,10 +39,24 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
class ApplicationFormSubmissionDto
|
||||
{
|
||||
/**
|
||||
* The stored vocabulary. W is not in here: it is accepted on the wire and folded into F by
|
||||
* getGender(), so nothing downstream ever sees two spellings of the same gender.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public const GENDERS = ['F', 'M', 'D'];
|
||||
|
||||
/**
|
||||
* What a payload may say, before case is folded. The TYPO3 forms are German and some of them
|
||||
* post the German W for female; refusing it - or refusing a lowercase w - would cost a whole
|
||||
* application over a spelling. Checked by validateGender() rather than Assert\Choice, because
|
||||
* Choice compares case-sensitively. Read the gender back through getGender(), never off the
|
||||
* property.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public const ACCEPTED_GENDERS = ['F', 'W', 'M', 'D'];
|
||||
|
||||
public const MAX_DETAIL_LABEL_LENGTH = 255;
|
||||
|
||||
public const MAX_DETAIL_VALUE_LENGTH = 65535;
|
||||
@@ -86,9 +100,11 @@ class ApplicationFormSubmissionDto
|
||||
#[Assert\Date(message: 'birthDate must be a date in the format YYYY-MM-DD.')]
|
||||
public readonly ?string $birthDate = null,
|
||||
// The application's own vocabulary, not BusPro's: ApplicationFormSubmission::toPayload()
|
||||
// maps F to W on the way out, exactly as Teamer::toPayload() does.
|
||||
// maps F to W on the way out, exactly as Teamer::toPayload() does. W is accepted on the
|
||||
// way in as the German spelling of F, in either case, and normalised by getGender() - the
|
||||
// storage stays F/M/D, and the W that reaches BusPro is the one toPayload() puts there.
|
||||
// Validated by validateGender(), not Assert\Choice.
|
||||
#[Assert\NotBlank(message: 'gender must not be empty.')]
|
||||
#[Assert\Choice(choices: self::GENDERS, message: 'gender must be one of F, M or D.')]
|
||||
public readonly ?string $gender = null,
|
||||
// The whole postal address, required together. Street and postcode are BusPro's own
|
||||
// Pflichtfelder for a new address (errors 891 and 890), so a submission without them is one
|
||||
@@ -180,6 +196,27 @@ class ApplicationFormSubmissionDto
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The same reasoning as validateEu(): getGender() folds case and the German W away, and what
|
||||
* survives that must be one of the three the application stores. Anything else is a 400 with
|
||||
* the vocabulary named, rather than a row nothing downstream can read.
|
||||
*/
|
||||
#[Assert\Callback]
|
||||
public function validateGender(ExecutionContextInterface $executionContext): void
|
||||
{
|
||||
if (null === $this->gender || '' === $this->gender) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($this->getGender(), self::GENDERS, true)) {
|
||||
$executionContext
|
||||
->buildViolation('gender must be one of F, W, M or D.')
|
||||
->atPath('gender')
|
||||
->addViolation()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#[Assert\Callback]
|
||||
public function validateDetails(ExecutionContextInterface $executionContext): void
|
||||
{
|
||||
@@ -240,6 +277,26 @@ class ApplicationFormSubmissionDto
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The gender as it is stored: upper-cased, with the German W for female folded into F. A form
|
||||
* posts "w" as readily as "W" and neither spelling is worth an application, so case is folded
|
||||
* here rather than demanded of the sender - the same reasoning as isEu() and getPageUid().
|
||||
*
|
||||
* Called by validateGender() as well, so this runs on unvalidated input: it returns whatever
|
||||
* the payload said, upper-cased, and it is validateGender() that decides whether that is one
|
||||
* of GENDERS. Everything after validation sees only F, M, D or null.
|
||||
*/
|
||||
public function getGender(): ?string
|
||||
{
|
||||
if (null === $this->gender) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$gender = strtoupper(trim($this->gender));
|
||||
|
||||
return 'W' === $gender ? 'F' : $gender;
|
||||
}
|
||||
|
||||
public function getPageUid(): ?int
|
||||
{
|
||||
if (null === $this->pageUid) {
|
||||
|
||||
Reference in new issue
Block a user