146 lines
4.1 KiB
PHP
146 lines
4.1 KiB
PHP
<?php
|
|
|
|
class Interval
|
|
{
|
|
function __construct(
|
|
$lowerBound,
|
|
$upperBound,
|
|
bool $lowerClosed = true,
|
|
bool $upperClosed = false
|
|
) {
|
|
$this->lowerBound = $lowerBound;
|
|
$this->upperBound = $upperBound;
|
|
$this->lowerClosed = $lowerClosed;
|
|
$this->upperClosed = $upperClosed;
|
|
}
|
|
function __toString(): string
|
|
{
|
|
return ($this->lowerClosed ? "[" : "(") .
|
|
$this->lowerBound .
|
|
", " .
|
|
$this->upperBound .
|
|
($this->upperClosed ? "]" : ")");
|
|
}
|
|
function contains($value)
|
|
{
|
|
return ($this->lowerClosed
|
|
? $this->lowerBound <= $value
|
|
: $this->lowerBound < $value) &&
|
|
($this->upperClosed
|
|
? $value <= $this->upperBound
|
|
: $value < $this->upperBound);
|
|
}
|
|
// private member
|
|
//- variables
|
|
// upper/lower bounds for the interval
|
|
private $lowerBound;
|
|
private $upperBound;
|
|
// on true the bound is in the interval, otherwise not
|
|
private $lowerClosed;
|
|
private $upperClosed;
|
|
}
|
|
// data type for an age class
|
|
class AgeGroup
|
|
{
|
|
// public member
|
|
// - functions
|
|
function __construct(string $label, Interval $years)
|
|
{
|
|
$this->label = $label;
|
|
$this->years = $years;
|
|
}
|
|
function __toString(): string
|
|
{
|
|
return $this->label . " " . $this->years;
|
|
}
|
|
function years()
|
|
{
|
|
return $this->years;
|
|
}
|
|
/** factory method for AgeGroup-s
|
|
*
|
|
* @param [string] $label string denoting the AgeGroup
|
|
* @param [type] $year the year to reference the AgeGroup to
|
|
* @return AgeGroup interval of years of the age group
|
|
*/
|
|
public static function create(string $label, ?int $year = null)
|
|
{
|
|
// input sanitation
|
|
$year =
|
|
filterPosInt($year) ?? filterPosInt((new DateTime())->format("Y"));
|
|
|
|
$lowerYear = null;
|
|
$upperYear = null;
|
|
|
|
// Matching against the different age class formats
|
|
// - ..Ux
|
|
// - Jg.x-y
|
|
|
|
// Case Ux
|
|
$akUmatchString = "/(.*)U([0-9]+)(.*)/";
|
|
|
|
$matches = [];
|
|
|
|
preg_match($akUmatchString, $label, $matches);
|
|
// The found match should cover the whole string. Otherwise it isn't applicable.
|
|
if ($matches[0] == $label) {
|
|
// The x in Ux should be a positive integer.
|
|
$ageLimit = filterPosInt($matches[2]);
|
|
if ($ageLimit) {
|
|
$lowerYear = $year - $ageLimit + 1;
|
|
// lowering the lower bound according to the modifiers
|
|
if ($matches[3] == "") {
|
|
$upperYear = $year - $ageLimit + 2;
|
|
} elseif ($matches[3] == "-") {
|
|
$upperYear = $year - $ageLimit + 3;
|
|
} elseif ($matches[3] == "--") {
|
|
$upperYear = $year - $ageLimit + 4;
|
|
} elseif (
|
|
in_array($matches[1], [
|
|
"<=",
|
|
"≤",
|
|
"≤",
|
|
"≤",
|
|
"≤",
|
|
])
|
|
) {
|
|
$upperYear = $year;
|
|
}
|
|
return new AgeGroup(
|
|
$label,
|
|
new Interval($lowerYear, $upperYear, true, true)
|
|
);
|
|
}
|
|
}
|
|
|
|
// Case Jg.x-y
|
|
$akUmatchString = "/Jg\.(.*)\-{1,2}(.*)/";
|
|
|
|
$matches = [];
|
|
|
|
preg_match($akUmatchString, $label, $matches);
|
|
// The found match should cover the whole string. Otherwise it isn't applicable.
|
|
|
|
if ($matches[0] == $label) {
|
|
$lowerYear = filterPosInt($matches[1]);
|
|
$upperYear = filterPosInt($matches[2]);
|
|
|
|
return new AgeGroup(
|
|
$label,
|
|
new Interval($lowerYear, $upperYear, true, true)
|
|
);
|
|
}
|
|
|
|
return new AgeGroup(
|
|
$label,
|
|
new Interval($lowerYear, $upperYear, true, true)
|
|
);
|
|
}
|
|
|
|
// private member
|
|
// - functions
|
|
// - variables
|
|
private $label;
|
|
private $years;
|
|
}
|