wip: age based filtering of options

This commit is contained in:
Björn Fromme
2026-03-16 11:59:09 +01:00
parent cd1e5ad3ad
commit 89c42cf7e4
11 changed files with 751 additions and 27 deletions
@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
namespace App\BusProNet\XmlParser;
use App\BusProNet\Model\AgeConstraintResult;
/**
* Registry for managing and executing age constraint parsers.
*
* This registry coordinates multiple age constraint parsers and can handle
* complex constraint data with multiple types separated by semicolons
* (e.g., 'JG:2007-2009;GL:5-8').
*/
class AgeConstraintParserRegistry
{
/** @var AgeConstraintParserInterface[] */
private array $parsers = [];
public function __construct()
{
// Register built-in parsers
$this->addParser(new BirthYearConstraintParser());
}
public function addParser(AgeConstraintParserInterface $parser): void
{
$this->parsers[] = $parser;
}
public function parseConstraints(string $constraintData): AgeConstraintResult
{
// Handle multiple constraint types (semicolon-separated, e.g., 'JG:2007-2009;GL:5-8')
$constraints = array_map('trim', explode(';', $constraintData));
$results = [];
foreach ($constraints as $constraint) {
if (empty($constraint)) {
continue;
}
foreach ($this->parsers as $parser) {
if (true === $parser->canParse($constraint)) {
$results[] = $parser->parse($constraint);
break; // First matching parser wins
}
}
}
// Merge results if multiple constraints found
return $this->mergeConstraintResults($results, $constraintData);
}
private function mergeConstraintResults(array $results, string $rawData): AgeConstraintResult
{
if (empty($results)) {
return new AgeConstraintResult(type: 'unknown', rawData: $rawData);
}
if (1 === count($results)) {
return $results[0];
}
// Merge multiple constraint results
$type = 'mixed';
$ageFrom = null;
$ageTo = null;
$birthYearFrom = null;
$birthYearTo = null;
$metadata = ['merged_from' => []];
foreach ($results as $result) {
$ageFrom = $this->mergeMinValue($ageFrom, $result->ageFrom);
$ageTo = $this->mergeMaxValue($ageTo, $result->ageTo);
$birthYearFrom = $this->mergeMinValue($birthYearFrom, $result->birthYearFrom);
$birthYearTo = $this->mergeMaxValue($birthYearTo, $result->birthYearTo);
$metadata['merged_from'][] = $result->type;
}
return new AgeConstraintResult(
type: $type,
ageFrom: $ageFrom,
ageTo: $ageTo,
birthYearFrom: $birthYearFrom,
birthYearTo: $birthYearTo,
metadata: $metadata,
rawData: $rawData
);
}
private function mergeMinValue(?int $current, ?int $new): ?int
{
if (null === $current) {
return $new;
}
if (null === $new) {
return $current;
}
return max($current, $new); // Most restrictive minimum
}
private function mergeMaxValue(?int $current, ?int $new): ?int
{
if (null === $current) {
return $new;
}
if (null === $new) {
return $current;
}
return min($current, $new); // Most restrictive maximum
}
}