From d3f161664d2afa0ed2df177557119541b874d695 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 26 Oct 2025 07:44:52 +0200 Subject: [PATCH] Handle inbound birthday date parsing in StringUtilities only. --- .../src/Model/Table/SqlSourcesTable.php | 9 ++++--- app/src/Lib/Util/StringUtilities.php | 26 +++++++++++++++++++ app/src/Model/Table/PeopleTable.php | 11 +++----- app/src/Model/Table/PipelinesTable.php | 11 +++----- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/availableplugins/SqlConnector/src/Model/Table/SqlSourcesTable.php b/app/availableplugins/SqlConnector/src/Model/Table/SqlSourcesTable.php index 9d71f7d51..704de8c5b 100644 --- a/app/availableplugins/SqlConnector/src/Model/Table/SqlSourcesTable.php +++ b/app/availableplugins/SqlConnector/src/Model/Table/SqlSourcesTable.php @@ -512,12 +512,13 @@ protected function resultsToEntityData( 'valid_through' => $result->valid_through ]; - if(!empty($result->date_of_birth) && empty($eidata['date_of_birth'])) { + if(empty($eidata['date_of_birth'])) { // We take the first DoB we see. Multiple rows should have the same // DoB, if they don't that's a problem in the data that needs to be fixed. - - // We have to convert the DateTime back to a string - $eidata['date_of_birth'] = $result->date_of_birth->format('Y-m-d'); + $dob = StringUtilities::handleInboundDateOfBirth($result->date_of_birth); + if (!empty($dob)) { + $eidata['date_of_birth'] = $dob; + } } // MVEAs that have a foreign key to EIR get attached to the EIR diff --git a/app/src/Lib/Util/StringUtilities.php b/app/src/Lib/Util/StringUtilities.php index 43bb5c661..f1387d836 100644 --- a/app/src/Lib/Util/StringUtilities.php +++ b/app/src/Lib/Util/StringUtilities.php @@ -415,6 +415,32 @@ public static function foreignKeyToController(string $s): string { return Inflector::underscore(Inflector::pluralize(substr($s, 0, strlen($s)-3))); } + /** + * Handles date of birth conversion from various input formats. + * + * @param string|DateTimeImmutable $dateOfBirth Date of birth as string or DateTimeImmutable + * @return \DateTimeImmutable|null Date of birth as DateTimeImmutable or null if invalid/empty + * @since COmanage Registry v5.2.0 + */ + public static function handleInboundDateOfBirth(mixed $dateOfBirth): ?\DateTimeImmutable + { + if(!empty($dateOfBirth)) { + return match(true) { + is_string($dateOfBirth) => static function ($dateOfBirth) { + $dob = \DateTimeImmutable::createFromFormat('Y-m-d', $dateOfBirth); + return $dob->format('Y-m-d'); + }, + $dateOfBirth instanceof \DateTimeImmutable => $dateOfBirth->format('Y-m-d'), + default => static function ($dateOfBirth) { + $this->llog('warning', __d('error', 'dob.invalid', [$dateOfBirth]));; + return null; + } + }; + } + + return null; + } + /** * Localize a controller name, accounting for plugins. * diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php index af25f5a44..bd9d52b90 100644 --- a/app/src/Model/Table/PeopleTable.php +++ b/app/src/Model/Table/PeopleTable.php @@ -29,6 +29,7 @@ namespace App\Model\Table; +use App\Lib\Util\StringUtilities; use App\Model\Entity\Person; use Cake\ORM\Query; use Cake\ORM\RulesChecker; @@ -777,14 +778,8 @@ public function saveAttributeCollectorPetitionAttributes(int $personId, array $f foreach ($fields as $field) { $attribute = $field->enrollment_attribute->attribute; $value = $field->value; - if($attribute === 'date_of_birth' && is_string($value)) { - // While we're here, make sure it's in YYYY-MM-DD format. This should fail - // if the inbound attribute is invalid. - $dob = \DateTimeImmutable::createFromFormat('Y-m-d', $value); - - if($dob) { - $value = $dob->format('Y-m-d'); - } + if($attribute === 'date_of_birth') { + $value = StringUtilities::handleInboundDateOfBirth($value); } $person->$attribute = $value; } diff --git a/app/src/Model/Table/PipelinesTable.php b/app/src/Model/Table/PipelinesTable.php index 184374fcf..852eaab77 100644 --- a/app/src/Model/Table/PipelinesTable.php +++ b/app/src/Model/Table/PipelinesTable.php @@ -898,15 +898,10 @@ protected function mapAttributesToCO( // Make sure source_key is a string 'source_key' => (string)$eisAttributes['source_key'] ]; - - if(!empty($eisAttributes['date_of_birth'])) { - // While we're here, make sure it's in YYYY-MM-DD format. This should fail - // if the inbound attribute is invalid. - $dob = \DateTimeImmutable::createFromFormat('Y-m-d', $eisAttributes['date_of_birth']); - if($dob) { - $ret['date_of_birth'] = $dob->format('Y-m-d'); - } + $dob = StringUtilities::handleInboundDateOfBirth($eisAttributes['date_of_birth']); + if($dob) { + $ret['date_of_birth'] = $dob; } foreach([