Files
cwsvJudo/homepage/participo/lib/participoLib/ageGroup.php
2024-04-06 12:05:41 +02:00

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], [
"<=",
"&le;",
"&#x2264;",
"&#8804;",
"",
])
) {
$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;
}