From 1856a5bfb885ca6b4610dabf8e92926b86223181 Mon Sep 17 00:00:00 2001 From: marko Date: Mon, 1 Apr 2024 09:41:39 +0200 Subject: [PATCH 1/2] updated submodules --- submodules/Makefile.materialize | 5 +++++ submodules/buildVideoJs.sh | 5 +++++ submodules/lite-youtube-embed | 2 +- submodules/materialize | 2 +- submodules/parsedown | 2 +- submodules/wkOrg | 2 +- 6 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 submodules/Makefile.materialize create mode 100755 submodules/buildVideoJs.sh diff --git a/submodules/Makefile.materialize b/submodules/Makefile.materialize new file mode 100644 index 0000000..b47348c --- /dev/null +++ b/submodules/Makefile.materialize @@ -0,0 +1,5 @@ +.PHONY: build + +build: + npm install + npm run release \ No newline at end of file diff --git a/submodules/buildVideoJs.sh b/submodules/buildVideoJs.sh new file mode 100755 index 0000000..f737d7f --- /dev/null +++ b/submodules/buildVideoJs.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash + +cd video.js +npm install +npm run release \ No newline at end of file diff --git a/submodules/lite-youtube-embed b/submodules/lite-youtube-embed index f9fc3a2..217b3cd 160000 --- a/submodules/lite-youtube-embed +++ b/submodules/lite-youtube-embed @@ -1 +1 @@ -Subproject commit f9fc3a2475ade166d0cf7bb3e3caa3ec236ee74e +Subproject commit 217b3cde1aa44ab943c99fc17b4cca7d6b3613f3 diff --git a/submodules/materialize b/submodules/materialize index 68e5224..93e673c 160000 --- a/submodules/materialize +++ b/submodules/materialize @@ -1 +1 @@ -Subproject commit 68e5224811ba6b568316de60da5af66d9a569a48 +Subproject commit 93e673c19fd6e1dee2b1dc77ac0e7c95fd39fbe9 diff --git a/submodules/parsedown b/submodules/parsedown index 77947ed..1ff0382 160000 --- a/submodules/parsedown +++ b/submodules/parsedown @@ -1 +1 @@ -Subproject commit 77947eda2fdaf06b181c63a7db13e38968306aee +Subproject commit 1ff038273949df7d6a455352659a878f3c89b29c diff --git a/submodules/wkOrg b/submodules/wkOrg index 11d239a..a419b06 160000 --- a/submodules/wkOrg +++ b/submodules/wkOrg @@ -1 +1 @@ -Subproject commit 11d239a57b2eccbaf98938cce90153fd6b3e3cfd +Subproject commit a419b0680f9982daaa31e23e786af022de353c1f From 658db494423330e0c3ac30e08e440636e10b79e1 Mon Sep 17 00:00:00 2001 From: marko Date: Sat, 6 Apr 2024 12:05:41 +0200 Subject: [PATCH 2/2] introduced AgeGroup as class --- .../participo/lib/participoLib/ageGroup.php | 145 +++++ .../participo/lib/participoLib/eventPage.php | 188 +++--- homepage/participo/lib/participoLib/shiai.php | 594 ++++++++++-------- 3 files changed, 584 insertions(+), 343 deletions(-) create mode 100644 homepage/participo/lib/participoLib/ageGroup.php diff --git a/homepage/participo/lib/participoLib/ageGroup.php b/homepage/participo/lib/participoLib/ageGroup.php new file mode 100644 index 0000000..82978a8 --- /dev/null +++ b/homepage/participo/lib/participoLib/ageGroup.php @@ -0,0 +1,145 @@ +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; +} diff --git a/homepage/participo/lib/participoLib/eventPage.php b/homepage/participo/lib/participoLib/eventPage.php index 2283940..177cae9 100644 --- a/homepage/participo/lib/participoLib/eventPage.php +++ b/homepage/participo/lib/participoLib/eventPage.php @@ -1,96 +1,132 @@ eventId = filterId($eventId); - } + public function __construct($eventId = null) + { + $this->eventId = filterId($eventId); + } - public function init() - { - $params = participo::parseParams( - ['eventId' => function ($param) {return filterId($param); }] - ); - $this->eventId = $params['eventId']; + public function init() + { + $params = participo::parseParams([ + "eventId" => function ($param) { + return filterId($param); + }, + ]); + $this->eventId = $params["eventId"]; - return; - } + return; + } - public function getHtmlNotFound() - { - return '
Der Event "' . $this->id . '" existiert leider nicht!
' - . '

Anstehende Termine

' - . eventPlaner::getHtmlEventTable( - eventPlaner::getComingWkEvents() - ); - } + public function getHtmlNotFound() + { + return '
Der Event "' . + $this->id . + '" existiert leider nicht!
' . + "

Anstehende Termine

" . + eventPlaner::getHtmlEventTable(eventPlaner::getComingWkEvents()); + } - public function getHtml() - { - if (!$this->event()) { - return $this->getHtmlNotFound(); - } + public function getHtml() + { + if (!$this->event()) { + return $this->getHtmlNotFound(); + } - $html = ''; + $html = ""; - $html .= - '
' - . '
' - . '
Termine
' - . '
-
' - . '
Datum
' . $this->event()->htmlDate() . '
' - . '
Deadline zum Einschreiben:
' . $this->event()->htmlDeadline() . '
' - . '
'; - // Not all Events have a shiai linked to them - if ($this->event()->shiai()) { - $html .= - '
Wettkampfdetails
' . $this->event()->shiai()->getHtmlDetails() . '
'; - } - $html .= - '
Einschreibungen
' . $this->event()->getHtmlStarterStatistic() . '
' - . '
Eigene, gemeldete Starter
' . $this->event()->getHtmlStarterList() . '
' - . '
' - . '
'; + $html .= + "
" . + "
" . + "
Termine
" . + '
+
' . + "
Datum
" . + $this->event()->htmlDate() . + "
" . + "
Deadline zum Einschreiben:
" . + $this->event()->htmlDeadline() . + "
" . + "
"; + // Not all Events have a shiai linked to them + if ($this->event()->shiai()) { + $html .= + "
Wettkampfdetails
" . + $this->event() + ->shiai() + ->getHtmlDetails() . + "
"; + } + $html .= + "
Einschreibungen
" . + $this->event()->getHtmlStarterStatistic() . + "
" . + "
Eigene, gemeldete Starter
" . + $this->event()->getHtmlStarterList() . + "
" . + "
" . + "
"; - $html .= - '
'; - foreach ($this->event()->shiai()->ageGroups() as $ageClass => $starterList) { - $html .= - '
' . - '
' . (!empty($ageClass) ? $ageClass : 'keiner Altersklasse zugeordnet') . '
' - . '
+ $html .= "
"; + + foreach ( + $this->event() + ->shiai() + ->ageGroups() + as $ageClass => $starterList + ) { + $html .= + "
" . + "
" . + (!empty($ageClass) + ? AgeGroup::create($ageClass) + : "keiner Altersklasse zugeordnet") . + "
" . + '
    '; - foreach ($starterList as $starter) { - if (!array_key_exists($starter->getId(), $this->event()->getStarter())) { - $html .= - '
  • ' . $starter->getName() . ', ' . $starter->getFirstname() . ' - ' . $starter->yearOfBirth() . ' + foreach ($starterList as $starter) { + if ( + !array_key_exists( + $starter->getId(), + $this->event()->getStarter() + ) + ) { + $html .= + "
  • " . + $starter->getName() . + ", " . + $starter->getFirstname() . + " - " . + $starter->yearOfBirth() . + '
  • '; - } - } - $html .= ' + } + } + $html .= '
'; - } - $html .= '
'; + } + $html .= "
"; - return $html; - } + return $html; + } - public function html() - { - echo($this->getHtml()); - } + public function html() + { + echo $this->getHtml(); + } - private function event(bool $forceLoading = false) - { - if (!$this->event || $forceLoading) { - $this->event = Event::loadFromDb($this->eventId); - } - return $this->event; - } + private function event(bool $forceLoading = false) + { + if (!$this->event || $forceLoading) { + $this->event = Event::loadFromDb($this->eventId); + } + return $this->event; + } - private $eventId = null; - private $event = null; + private $eventId = null; + private $event = null; } diff --git a/homepage/participo/lib/participoLib/shiai.php b/homepage/participo/lib/participoLib/shiai.php index 1419556..9122ce8 100644 --- a/homepage/participo/lib/participoLib/shiai.php +++ b/homepage/participo/lib/participoLib/shiai.php @@ -1,313 +1,373 @@ id = filterId($id); - $this->date = DateTime::createFromFormat('Y-m-d', $date); - $this->name = $name; - $this->ageclasses = $ageclasses ? self::akListString2jgArray($ageclasses) : null; - $this->place = $place; - $this->announcementUrl = $announcementUrl; - $this->routeUrl = $routeUrl; - $this->galleryUrl = $galleryUrl; - $this->promoImgUrl = $promoImgUrl; - } + public function __construct( + $id, + $date, + $name, + $ageclasses, + $place, + $announcementUrl, + $routeUrl, + $galleryUrl = null, + $promoImgUrl = null + ) { + //! @todo input validation and sanitation + $this->id = filterId($id); + $this->date = DateTime::createFromFormat("Y-m-d", $date); + $this->name = $name; + $this->ageclasses = $ageclasses + ? self::akListString2jgArray($ageclasses) + : null; + $this->place = $place; + $this->announcementUrl = $announcementUrl; + $this->routeUrl = $routeUrl; + $this->galleryUrl = $galleryUrl; + $this->promoImgUrl = $promoImgUrl; + } - public static function fromArray(array $shiai){ - $id = $shiai['id'] ?? null; - $date = $shiai['date'] ?? null; - $name = $shiai['name'] ?? null; - $ageclasses = $shiai['ageclasses'] ?? null; - $place = $shiai['place'] ?? null; - $announcementUrl = $shiai['announcementUrl'] ?? null; - $routeUrl = $shiai['routeUrl'] ?? null; - // gallery stuff removed for now + public static function fromArray(array $shiai) + { + $id = $shiai["id"] ?? null; + $date = $shiai["date"] ?? null; + $name = $shiai["name"] ?? null; + $ageclasses = $shiai["ageclasses"] ?? null; + $place = $shiai["place"] ?? null; + $announcementUrl = $shiai["announcementUrl"] ?? null; + $routeUrl = $shiai["routeUrl"] ?? null; + // gallery stuff removed for now - return new Shiai($id, $date, $name, $ageclasses, $place, $announcementUrl, $routeUrl); - } + return new Shiai( + $id, + $date, + $name, + $ageclasses, + $place, + $announcementUrl, + $routeUrl + ); + } - public function asArray(){ - return [ - 'id'=>$this->id, - 'date'=>$this->date->format('Y-m-d'), - 'name'=>$this->name, - // @todo at least in theory this should again hold age categories - 'ageclasses'=>implode(" ", $this->ageclasses), - 'place'=>$this->place, - 'announcementUrl'=>$this->announcementUrl, - 'routeUrl'=>$this->announcementUrl - ]; - } + public function asArray() + { + return [ + "id" => $this->id, + "date" => $this->date->format("Y-m-d"), + "name" => $this->name, + // @todo at least in theory this should again hold age categories + "ageclasses" => implode(" ", $this->ageclasses), + "place" => $this->place, + "announcementUrl" => $this->announcementUrl, + "routeUrl" => $this->announcementUrl, + ]; + } - public function getId() - { - return $this->id; - } + public function getId() + { + return $this->id; + } - public function getHtmlName() - { - $name = ($this->name != null ? $this->name : 'Wettkampf ohne Namen'); - foreach (['meisterschaft', 'turnier', 'randori'] as $fragment) { - $name = str_replace($fragment, '­' . $fragment, $name); - } - return $name; - } + public function getHtmlName() + { + $name = $this->name != null ? $this->name : "Wettkampf ohne Namen"; + foreach (["meisterschaft", "turnier", "randori"] as $fragment) { + $name = str_replace($fragment, "­" . $fragment, $name); + } + return $name; + } - public function getHtmlDate() - { - return ($this->date != null ? $this->date->format('Y-m-d') : 'fehlendes Datum'); - } + public function getHtmlDate() + { + return $this->date != null + ? $this->date->format("Y-m-d") + : "fehlendes Datum"; + } - public function getAgeClasses() - { - return ($this->ageclasses != null ? $this->ageclasses : '-'); - } + public function getAgeClasses() + { + return $this->ageclasses != null ? $this->ageclasses : "-"; + } - public function getPlace() - { - return ($this->place != null ? $this->place : '-'); - } + public function getPlace() + { + return $this->place != null ? $this->place : "-"; + } - public function getAnnouncementUrl() - { - return $this->announcementUrl; - } + public function getAnnouncementUrl() + { + return $this->announcementUrl; + } - public function getRouteUrl() - { - return $this->routeUrl; - } + public function getRouteUrl() + { + return $this->routeUrl; + } - public static function loadFromDb(int $id) - { - $id = filterId($id); + public static function loadFromDb(int $id) + { + $id = filterId($id); - $query = 'SELECT * FROM `cwsvjudo`.`wettkampfkalender` WHERE `lfdeNr` = :id;'; - $params = [':id' => ['value' => $id, 'data_type' => PDO::PARAM_INT]]; - $response = dbConnector::query($query, $params); + $query = + "SELECT * FROM `cwsvjudo`.`wettkampfkalender` WHERE `lfdeNr` = :id;"; + $params = [":id" => ["value" => $id, "data_type" => PDO::PARAM_INT]]; + $response = dbConnector::query($query, $params); - // ids are considered unique. so every other count then 1 is treated as error to prevent unprivileged access - if (count($response) != 1) { - return null; - } - return self::fromDbArray($response[0]); - } + // ids are considered unique. so every other count then 1 is treated as error to prevent unprivileged access + if (count($response) != 1) { + return null; + } + return self::fromDbArray($response[0]); + } - /** select shiai from the database - * - * - by default, only coming events will be returned - */ - public static function dbSelect(){ - $query = "SELECT `".self::$tableName."`.* FROM `".self::$tableName."` WHERE `Datum` >= CURDATE();"; - $response = dbConnector::query($query); + /** select shiai from the database + * + * - by default, only coming events will be returned + */ + public static function dbSelect() + { + $query = + "SELECT `" . + self::$tableName . + "`.* FROM `" . + self::$tableName . + "` WHERE `Datum` >= CURDATE();"; + $response = dbConnector::query($query); - return $response; - } + return $response; + } - public static function fromDbArray($member) - { - return new shiai( - $member['lfdeNr'] ?? null, - $member['Datum'] ?? null, - $member['Veranstaltung'] ?? '', - $member['Altersklassen'] ?? null, - $member['Ort'] ?? '', - $member['Ausschreibung'] ?? null, - $member['Routenplaner'] ?? null, - $member['galleryLink'] ?? null, - $member['promoPic'] ?? null - ); - } + public static function fromDbArray($member) + { + return new shiai( + $member["lfdeNr"] ?? null, + $member["Datum"] ?? null, + $member["Veranstaltung"] ?? "", + $member["Altersklassen"] ?? null, + $member["Ort"] ?? "", + $member["Ausschreibung"] ?? null, + $member["Routenplaner"] ?? null, + $member["galleryLink"] ?? null, + $member["promoPic"] ?? null + ); + } - /** shiai event as html code for displaying - * - * @return html formatted string - */ - public function getHtml() - { - $retHtml = ''; - $retHtml = - '
' . - '

' . $this->getHtmlName() . '

' . - '
' . - '
Datum
' . $this->getHtmlDate() . '
' . - '
Altersklassen
' . $this->getHtmlDescriptiveAgeClasses() . '
' . - '
Ort
' . $this->getPlace() . '
' . - '
' . - '
'; - return $retHtml; - } + /** shiai event as html code for displaying + * + * @return html formatted string + */ + public function getHtml() + { + $retHtml = ""; + $retHtml = + "
" . + '

' . + $this->getHtmlName() . + "

" . + "
" . + "
Datum
" . + $this->getHtmlDate() . + "
" . + "
Altersklassen
" . + $this->getHtmlDescriptiveAgeClasses() . + "
" . + '
Ort
' . + $this->getPlace() . + "
" . + "
" . + "
"; + return $retHtml; + } - public function getHtmlDetails() - { - return - '
' - . '
Name
' . $this->getHtmlName() . '
' - . '
Datum
' . $this->getHtmlDate() . '
' - . '
Altersklassen
' . $this->getHtmlDescriptiveAgeClasses() . '
' - . '
Ort
' . $this->getPlace() . '
' . - '
' - ; - } + public function getHtmlDetails() + { + return "
" . + '
Name
' . + $this->getHtmlName() . + "
" . + "
Datum
" . + $this->getHtmlDate() . + "
" . + "
Altersklassen
" . + $this->getHtmlDescriptiveAgeClasses() . + "
" . + '
Ort
' . + $this->getPlace() . + "
" . + "
"; + } - public function getHtmlDescriptiveAgeClasses() - { - $retList = []; - foreach ($this->ageclasses as $ageclass => $years) { - $htmlFragment = $ageclass; - $years = $years[0]; + public function getHtmlDescriptiveAgeClasses() + { + return join(", ", $this->ageclasses); + } - if ($years[0] || $years[1]) { - $htmlFragment .= '('; - if ($years[1]) { - $htmlFragment .= strval($years[0]) . '-' . strval($years[1]); - } else { - $htmlFragment .= '<=' . strval($years[0]); - } - $htmlFragment .= ')'; - } - $retList[] = $htmlFragment; - } - return implode(', ', $retList); - } + /** convert a list of age class formatted strings into a list of intervals of years + * + * @param string $akListString + * @param int $year + * @return list[array(int,int)] list of tupels with lower/upper bound in date year of the age classes + */ + private static function akListString2jgArray( + string $akListString, + ?int $year = null + ) { + $year = + filterPosInt($year) ?? filterPosInt((new DateTime())->format("Y")); - /** convert a list of age class formatted strings into a list of intervals of years - * - * @param string $akListString - * @param int $year - * @return list[array(int,int)] list of tupels with lower/upper bound in date year of the age classes - */ - private static function akListString2jgArray(string $akListString, int $year = null) - { - $year = filterPosInt($year) ?? filterPosInt((new DateTime)->format('Y')); - $ret = []; - foreach (explode(' ', $akListString) as $ak) { - $ret[$ak] = self::akString2jgIntervall($ak, $year); - } - return $ret; - } + $ageGroups = []; + foreach (explode(" ", $akListString) as $label) { + $ageGroups[$label] = AgeGroup::create($label, $year); + } - /** convert age class from formatted string to interval of years - * - * @param [string] $akString - * @param [type] $year - * @return array(int,int) [x,y] with x the lower bound and y the upper bound of the age class in years. Both bounds are still included in the interval. - */ - private static function akString2jgIntervall(string $akString, int $year /*= null*/) - { - // input sanitation - $year = filterPosInt($year) ?? filterPosInt((new DateTime)->format('Y')); + return $ageGroups; + } - $ret = [null, null]; + /** convert age class from formatted string to interval of years + * + * @param [string] $akString + * @param [type] $year + * @return array(int,int) [x,y] with x the lower bound and y the upper bound of the age class in years. Both bounds are still included in the interval. + */ + private static function akString2jgIntervall(string $akString, int $year) + { + /*= null*/ // input sanitation + $year = + filterPosInt($year) ?? filterPosInt((new DateTime())->format("Y")); - // Matching against the different age class formats - // - ..Ux - // - Jg.x-y + $ret = [null, null]; - // Case Ux - $akUmatchString = '/(.*)U(.*)/'; + // Matching against the different age class formats + // - ..Ux + // - Jg.x-y - $matches = []; + // Case Ux + $akUmatchString = "/(.*)U(.*)/"; - preg_match($akUmatchString, $akString, $matches); - // The found match should cover the whole string. Otherwise it isn't applicable. - if ($matches[0] == $akString) { - // The x in Ux should be a positive integer. - $ageLimit = filterPosInt($matches[2]); - if ($ageLimit) { - $ret[0] = $year - $ageLimit + 1; - // lowering the lower bound according to the modifiers - if ($matches[1] == '') { - $ret[1] = $year - $ageLimit + 2; - } elseif ($matches[1] == '-') { - $ret[1] = $year - $ageLimit + 3; - } elseif ($matches[1] == '--') { - $ret[1] = $year - $ageLimit + 4; - } elseif (in_array($matches[1], ['<=', '≤', '≤', '≤', '≤'])) { - $ret[1] = $year; - } - return $ret; - } - } + $matches = []; - // Case Jg.x-y - $akUmatchString = "/Jg\.(.*)\-{1,2}(.*)/"; + preg_match($akUmatchString, $akString, $matches); + // The found match should cover the whole string. Otherwise it isn't applicable. + if ($matches[0] == $akString) { + // The x in Ux should be a positive integer. + $ageLimit = filterPosInt($matches[2]); + if ($ageLimit) { + $ret[0] = $year - $ageLimit + 1; + // lowering the lower bound according to the modifiers + if ($matches[1] == "") { + $ret[1] = $year - $ageLimit + 2; + } elseif ($matches[1] == "-") { + $ret[1] = $year - $ageLimit + 3; + } elseif ($matches[1] == "--") { + $ret[1] = $year - $ageLimit + 4; + } elseif ( + in_array($matches[1], [ + "<=", + "≤", + "≤", + "≤", + "≤", + ]) + ) { + $ret[1] = $year; + } + return $ret; + } + } - $matches = []; + // Case Jg.x-y + $akUmatchString = "/Jg\.(.*)\-{1,2}(.*)/"; - preg_match($akUmatchString, $akString, $matches); - // The found match should cover the whole string. Otherwise it isn't applicable. + $matches = []; - if ($matches[0] == $akString) { - $ret[0] = filterPosInt($matches[1]); - $ret[1] = filterPosInt($matches[2]); + preg_match($akUmatchString, $akString, $matches); + // The found match should cover the whole string. Otherwise it isn't applicable. - return $ret; - } + if ($matches[0] == $akString) { + $ret[0] = filterPosInt($matches[1]); + $ret[1] = filterPosInt($matches[2]); - return $ret; - } + return $ret; + } - /** grouping users kids by ageGroups - * - * @return array(ageGroup => list(users in ageGroup)) - */ - public function ageGroups() - { - $kids = participo::getKids(); - return self::ageClassGrouping($this->ageclasses, $kids); - } + return $ret; + } - /** grouping users by given age class - * - * @param array $ageClassList as array string representation of age class => [lower year bound, upper year bound] - * @param array $starterList list of starter (User) - * @return array of string representation of age class => array of userId=>user in this class - */ - private static function ageClassGrouping(array $ageClassList, array $starterList) - { - $grouping = []; - foreach ($ageClassList as $ageClass => $yearBoundaries) { - $grouping[$ageClass] = []; - } - $grouping[null] = []; + /** grouping users kids by ageGroups + * + * @return array(ageGroup => list(users in ageGroup)) + */ + public function ageGroups() + { + $kids = participo::getKids(); + return self::ageClassGrouping($this->ageclasses, $kids); + } - foreach ($starterList as $starter) { - $startersAgeClass = $starter->yearOfBirth() ? self::getAgeClassFromYear($starter->yearOfBirth(), $ageClassList) : null; - $grouping[$startersAgeClass][$starter->getId()] = $starter; - } - return $grouping; - } + /** grouping users by given age class + * + * @param array $ageClassList as array string representation of age class => [lower year bound, upper year bound] + * @param array $starterList list of starter (User) + * @return array of string representation of age class => array of userId=>user in this class + */ + private static function ageClassGrouping( + array $ageClassList, + array $starterList + ) { + $grouping = []; - private static function getAgeClassFromYear(int $year, array $ageClassList) - { - foreach ($ageClassList as $ageClass => $yearBoundaries) { - if (($yearBoundaries[0] <= $year) && ($year <= $yearBoundaries[1])) { - return $ageClass; - } - } - return null; - } + foreach ($ageClassList as $ageClass => $yearBoundaries) { + $grouping[$ageClass] = []; + } + $grouping[null] = []; + + foreach ($starterList as $starter) { + $startersAgeClass = $starter->yearOfBirth() + ? self::getAgeClassFromYear( + $starter->yearOfBirth(), + $ageClassList + ) + : null; + $grouping[$startersAgeClass][$starter->getId()] = $starter; + } + + return $grouping; + } + + private static function getAgeClassFromYear(int $year, array $ageClassList) + { + foreach ($ageClassList as $label => $ageGroup) { + if ($ageGroup->years()->contains($year)) { + return $label; + } + } + return null; + } } // end class shiai