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 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 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 getHtmlDate() { return $this->date != null ? $this->date->format("Y-m-d") : "fehlendes Datum"; } public function getAgeClasses() { return $this->ageclasses != null ? $this->ageclasses : "-"; } public function getPlace() { return $this->place != null ? $this->place : "-"; } public function getAnnouncementUrl() { return $this->announcementUrl; } public function getRouteUrl() { return $this->routeUrl; } 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); // 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); 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 ); } /** 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 getHtmlDescriptiveAgeClasses() { return join(", ", $this->ageclasses); } /** 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")); $ageGroups = []; foreach (explode(" ", $akListString) as $label) { $ageGroups[$label] = AgeGroup::create($label, $year); } return $ageGroups; } /** 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")); $ret = [null, null]; // Matching against the different age class formats // - ..Ux // - Jg.x-y // Case Ux $akUmatchString = "/(.*)U(.*)/"; $matches = []; 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; } } // Case Jg.x-y $akUmatchString = "/Jg\.(.*)\-{1,2}(.*)/"; $matches = []; preg_match($akUmatchString, $akString, $matches); // The found match should cover the whole string. Otherwise it isn't applicable. 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); } /** 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] = []; 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