From 1856a5bfb885ca6b4610dabf8e92926b86223181 Mon Sep 17 00:00:00 2001 From: marko Date: Mon, 1 Apr 2024 09:41:39 +0200 Subject: [PATCH 1/4] 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/4] 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 From 93946d1c8984b385dbb27c6d48054c3061e09c16 Mon Sep 17 00:00:00 2001 From: marko Date: Sun, 7 Apr 2024 09:03:17 +0200 Subject: [PATCH 3/4] registration form fkr --- .../2024-04-13-FKR/CWSV-Meldeliste-FKR-2024.xls | Bin 0 -> 10240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 shiai/shiai-2024/2024-04-13-FKR/CWSV-Meldeliste-FKR-2024.xls diff --git a/shiai/shiai-2024/2024-04-13-FKR/CWSV-Meldeliste-FKR-2024.xls b/shiai/shiai-2024/2024-04-13-FKR/CWSV-Meldeliste-FKR-2024.xls new file mode 100644 index 0000000000000000000000000000000000000000..40be1080049a13dcaae57c172e7413c69deb0da3 GIT binary patch literal 10240 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 Td;GtM*KGAa`TsBe-~9gz;M9yr literal 0 HcmV?d00001 From 181e6db950859df9e02706ffa42c37bdfa99db9b Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 10 Apr 2024 05:18:15 +0200 Subject: [PATCH 4/4] newsletter osterferien, fkr --- infoZettelOrg/2024-03-27-Osterferien.md | 26 ++++++++++++++++++++ infoZettelOrg/2024-04-04-Freitagstraining.md | 21 ++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 infoZettelOrg/2024-03-27-Osterferien.md create mode 100644 infoZettelOrg/2024-04-04-Freitagstraining.md diff --git a/infoZettelOrg/2024-03-27-Osterferien.md b/infoZettelOrg/2024-03-27-Osterferien.md new file mode 100644 index 0000000..c400eba --- /dev/null +++ b/infoZettelOrg/2024-03-27-Osterferien.md @@ -0,0 +1,26 @@ +--- +title: Training in den Osterferien +--- + +- [Training in den Osterferien](#training-in-den-osterferien) +- [Frühjahrskrümelrandori](#frühjahrskrümelrandori) + +## Training in den Osterferien + +Auch während der gesamten wird wieder trainiert werden können: + +- Karfreitag: 29.03.2024 + - 16:00--17:45 Uhr (Kinder/Anfänger) + - 17:30--19:15 Uhr (Jugend/Fortgeschrittene) +- Mittwoch: 03.04.2024 + - 16:00--17:45 Uhr (alle) + - Da das Dojo anderweitig benötigt wird, werden wir das Training nach draußen verlegen. Bitte an entsprechende Kleidung (insbesondere Schuhe). +- Freitag: 05.04.2024 + - 16:00--17:45 Uhr (Kinder/Anfänger) + - 17:30--19:15 Uhr (Jugend/Fortgeschrittene) + +## Frühjahrskrümelrandori + +Am 2023-04-13 wird das [27. Frühjahrskrümel­randori (U11--)][wk218] stattfinden. Bitte im [Wettkampfplaner][wk218] eintragen wer teilnehmen will und wer nicht. + +[wk218]: http://cwsvjudo.bplaced.net/participo/events#218 diff --git a/infoZettelOrg/2024-04-04-Freitagstraining.md b/infoZettelOrg/2024-04-04-Freitagstraining.md new file mode 100644 index 0000000..fc12bb0 --- /dev/null +++ b/infoZettelOrg/2024-04-04-Freitagstraining.md @@ -0,0 +1,21 @@ +--- +title: Training am Freitag, 2024-04-05 +--- + +- [Training am Freitag, 2024-04-05](#training-am-freitag-2024-04-05) +- [Frühjahrskrümelrandori](#frühjahrskrümelrandori) + +## Training am Freitag, 2024-04-05 + +Spontan haben die Karateka angefragt, für ihr Trainingslager am Freitag noch einmal in das Dojo zu können und ich habe zugesagt. Für das unser Training bedeutet das: + +- Das Training der Kinder/Anfänger wird noch wie gewohnt im Dojo stattfinden, aber überpünktlich bereits *17:30* enden: + - 16:00--*17:30* Uhr (Kinder/Anfänger) +- Bei den Großen wird es dann wie jeden ersten Freitag im Monat den Kraftkreis geben. Bei gutem Wetter draußen, bei schlechtem in einer Kabine: + - 17:30--19:15 Uhr (Kraftkreis) + +## Frühjahrskrümelrandori + +Am 2023-04-13 wird das [27. Frühjahrskrümel­randori (U11--)][wk218] stattfinden. Bitte im [Wettkampfplaner][wk218] eintragen wer teilnehmen will und wer nicht. + +[wk218]: http://cwsvjudo.bplaced.net/participo/events#218