From 983083d7614fd67d43c53b15d3025339044979e7 Mon Sep 17 00:00:00 2001 From: svennickel Date: Fri, 11 Sep 2026 07:14:05 +0200 Subject: [PATCH] Zeilenenden von tools.php wiederherstellen (CRLF) --- .../components/com_sportsmanager/tools.php | 1446 ++++++++--------- 1 file changed, 723 insertions(+), 723 deletions(-) diff --git a/src/structure/components/com_sportsmanager/tools.php b/src/structure/components/com_sportsmanager/tools.php index e951e7f..5126a71 100644 --- a/src/structure/components/com_sportsmanager/tools.php +++ b/src/structure/components/com_sportsmanager/tools.php @@ -1,723 +1,723 @@ -createFunc("ROUND", 'round', 1); - $this->createFunc("VERTEILUNG", 'mathParserVerteilung', 4); - $this->createFunc("VERTEILUNGR", 'mathParserVerteilungR', 4); - } catch (Exception $e) { - Log::add('an error occurred: ' . $e->getMessage(), Log::ERROR, 'com_sportsmanager'); - throw new RuntimeException('An error occurred.', 500); - } - } -} - -#[NoReturn] function keinZugriff($login = FALSE): void -{ - if (isJson()) { - abortWithError(401 . ' Unauthorized'); - } - if (!$login || Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id) { - Log::add('Unauthorized user with id ' . Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id, Log::WARNING, 'com_sportsmanager'); - throw new RuntimeException('Not authorized!', 401); - } - $version = new Version(); - $joomla = $version->getShortVersion(); - $u = Uri::getInstance(); - $redirectUrl = urlencode(base64_encode($u->toString())); - $redirectUrl = '&return=' . $redirectUrl; - $joomlaLoginUrl = 'index.php?option=' . (!str_starts_with($joomla, '1.5') ? 'com_users' : 'com_user') . '&view=login'; - $finalUrl = $joomlaLoginUrl . $redirectUrl; - $app = Factory::getContainer()->get(SiteApplication::class); - $app->redirect(Route::_($finalUrl)); - jexit(); -} - -function bereinigterDateiname($dateiname): array|string -{ - $_convertTable = array( - '&' => 'and', '@' => 'at', '©' => 'c', '®' => 'r', 'À' => 'a', - 'Á' => 'a', 'Â' => 'a', 'Ä' => 'a', 'Å' => 'a', 'Æ' => 'ae', 'Ç' => 'c', - 'È' => 'e', 'É' => 'e', 'Ë' => 'e', 'Ì' => 'i', 'Í' => 'i', 'Î' => 'i', - 'Ï' => 'i', 'Ò' => 'o', 'Ó' => 'o', 'Ô' => 'o', 'Õ' => 'o', 'Ö' => 'o', - 'Ø' => 'o', 'Ù' => 'u', 'Ú' => 'u', 'Û' => 'u', 'Ü' => 'u', 'Ý' => 'y', - 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ä' => 'a', 'å' => 'a', - 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', - 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ò' => 'o', 'ó' => 'o', - 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', - 'û' => 'u', 'ü' => 'u', 'ý' => 'y', 'þ' => 'p', 'ÿ' => 'y', 'Ā' => 'a', - 'ā' => 'a', 'Ă' => 'a', 'ă' => 'a', 'Ą' => 'a', 'ą' => 'a', 'Ć' => 'c', - 'ć' => 'c', 'Ĉ' => 'c', 'ĉ' => 'c', 'Ċ' => 'c', 'ċ' => 'c', 'Č' => 'c', - 'č' => 'c', 'Ď' => 'd', 'ď' => 'd', 'Đ' => 'd', 'đ' => 'd', 'Ē' => 'e', - 'ē' => 'e', 'Ĕ' => 'e', 'ĕ' => 'e', 'Ė' => 'e', 'ė' => 'e', 'Ę' => 'e', - 'ę' => 'e', 'Ě' => 'e', 'ě' => 'e', 'Ĝ' => 'g', 'ĝ' => 'g', 'Ğ' => 'g', - 'ğ' => 'g', 'Ġ' => 'g', 'ġ' => 'g', 'Ģ' => 'g', 'ģ' => 'g', 'Ĥ' => 'h', - 'ĥ' => 'h', 'Ħ' => 'h', 'ħ' => 'h', 'Ĩ' => 'i', 'ĩ' => 'i', 'Ī' => 'i', - 'ī' => 'i', 'Ĭ' => 'i', 'ĭ' => 'i', 'Į' => 'i', 'į' => 'i', 'İ' => 'i', - 'ı' => 'i', 'IJ' => 'ij', 'ij' => 'ij', 'Ĵ' => 'j', 'ĵ' => 'j', 'Ķ' => 'k', - 'ķ' => 'k', 'ĸ' => 'k', 'Ĺ' => 'l', 'ĺ' => 'l', 'Ļ' => 'l', 'ļ' => 'l', - 'Ľ' => 'l', 'ľ' => 'l', 'Ŀ' => 'l', 'ŀ' => 'l', 'Ł' => 'l', 'ł' => 'l', - 'Ń' => 'n', 'ń' => 'n', 'Ņ' => 'n', 'ņ' => 'n', 'Ň' => 'n', 'ň' => 'n', - 'ʼn' => 'n', 'Ŋ' => 'n', 'ŋ' => 'n', 'Ō' => 'o', 'ō' => 'o', 'Ŏ' => 'o', - 'ŏ' => 'o', 'Ő' => 'o', 'ő' => 'o', 'Œ' => 'oe', 'œ' => 'oe', 'Ŕ' => 'r', - 'ŕ' => 'r', 'Ŗ' => 'r', 'ŗ' => 'r', 'Ř' => 'r', 'ř' => 'r', 'Ś' => 's', - 'ś' => 's', 'Ŝ' => 's', 'ŝ' => 's', 'Ş' => 's', 'ş' => 's', 'Š' => 's', - 'š' => 's', 'Ţ' => 't', 'ţ' => 't', 'Ť' => 't', 'ť' => 't', 'Ŧ' => 't', - 'ŧ' => 't', 'Ũ' => 'u', 'ũ' => 'u', 'Ū' => 'u', 'ū' => 'u', 'Ŭ' => 'u', - 'ŭ' => 'u', 'Ů' => 'u', 'ů' => 'u', 'Ű' => 'u', 'ű' => 'u', 'Ų' => 'u', - 'ų' => 'u', 'Ŵ' => 'w', 'ŵ' => 'w', 'Ŷ' => 'y', 'ŷ' => 'y', 'Ÿ' => 'y', - 'Ź' => 'z', 'ź' => 'z', 'Ż' => 'z', 'ż' => 'z', 'Ž' => 'z', 'ž' => 'z', - 'ſ' => 'z', 'Ə' => 'e', 'ƒ' => 'f', 'Ơ' => 'o', 'ơ' => 'o', 'Ư' => 'u', - 'ư' => 'u', 'Ǎ' => 'a', 'ǎ' => 'a', 'Ǐ' => 'i', 'ǐ' => 'i', 'Ǒ' => 'o', - 'ǒ' => 'o', 'Ǔ' => 'u', 'ǔ' => 'u', 'Ǖ' => 'u', 'ǖ' => 'u', 'Ǘ' => 'u', - 'ǘ' => 'u', 'Ǚ' => 'u', 'ǚ' => 'u', 'Ǜ' => 'u', 'ǜ' => 'u', 'Ǻ' => 'a', - 'ǻ' => 'a', 'Ǽ' => 'ae', 'ǽ' => 'ae', 'Ǿ' => 'o', 'ǿ' => 'o', 'ə' => 'e', - 'Ё' => 'jo', 'Є' => 'e', 'І' => 'i', 'Ї' => 'i', 'А' => 'a', 'Б' => 'b', - 'В' => 'v', 'Г' => 'g', 'Д' => 'd', 'Е' => 'e', 'Ж' => 'zh', 'З' => 'z', - 'И' => 'i', 'Й' => 'j', 'К' => 'k', 'Л' => 'l', 'М' => 'm', 'Н' => 'n', - 'О' => 'o', 'П' => 'p', 'Р' => 'r', 'С' => 's', 'Т' => 't', 'У' => 'u', - 'Ф' => 'f', 'Х' => 'h', 'Ц' => 'c', 'Ч' => 'ch', 'Ш' => 'sh', 'Щ' => 'sch', - 'Ъ' => '-', 'Ы' => 'y', 'Ь' => '-', 'Э' => 'je', 'Ю' => 'ju', 'Я' => 'ja', - 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', - 'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'j', 'к' => 'k', 'л' => 'l', - 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', - 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', - 'ш' => 'sh', 'щ' => 'sch', 'ъ' => '-', 'ы' => 'y', 'ь' => '-', 'э' => 'je', - 'ю' => 'ju', 'я' => 'ja', 'ё' => 'jo', 'є' => 'e', 'і' => 'i', 'ї' => 'i', - 'Ґ' => 'g', 'ґ' => 'g', 'א' => 'a', 'ב' => 'b', 'ג' => 'g', 'ד' => 'd', - 'ה' => 'h', 'ו' => 'v', 'ז' => 'z', 'ח' => 'h', 'ט' => 't', 'י' => 'i', - 'ך' => 'k', 'כ' => 'k', 'ל' => 'l', 'ם' => 'm', 'מ' => 'm', 'ן' => 'n', - 'נ' => 'n', 'ס' => 's', 'ע' => 'e', 'ף' => 'p', 'פ' => 'p', 'ץ' => 'C', - 'צ' => 'c', 'ק' => 'q', 'ר' => 'r', 'ש' => 'w', 'ת' => 't', '™' => 'tm', - ); - $bad = array_merge( - array_map('chr', range(0, 31)), - array("<", ">", ":", '"', "/", "\\", "|", "?", "*")); - - return str_replace($bad, "", strtr($dateiname, $_convertTable)); -} - -function setMinMemoryLimit($memDestSize): void -{ - if (getBytes(ini_get('memory_limit')) < getBytes($memDestSize)) - ini_set('memory_limit', $memDestSize); -} - -function getBytes($val): int|string -{ - $val = trim($val); - $numeric = substr($val, 0, strlen($val) - 1); - $last = strtolower($val[strlen($val) - 1]); - switch ($last) { - // The 'G' modifier is available since PHP 5.1.0 - case 'm': - case 'g': - case 'k': - $numeric *= 1024; - break; - } - return $numeric; -} - -function encrypt($str, $key): string -{ - $result = ""; - for ($i = 0; $i < strlen($str); $i++) { - $char = substr($str, $i, 1); - $keychar = substr($key, ($i % strlen($key)) - 1, 1); - $char = chr(ord($char) + ord($keychar)); - $result .= $char; - } - return base64_encode($result); -} - -function decrypt($str, $key): string -{ - $str = base64_decode($str); - $result = ""; - for ($i = 0; $i < strlen($str); $i++) { - $char = substr($str, $i, 1); - $keychar = substr($key, ($i % strlen($key)) - 1, 1); - $char = chr(ord($char) - ord($keychar)); - $result .= $char; - } - return $result; -} - -function individualwettbewerbFilter($prefix): string -{ - $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_individualwettbewerb_id FROM #__sportsmanager_berechtigt_fuer_individualwettbewerb INNER JOIN #__sportsmanager_individualwettbewerb ON individualwettbewerb_id = berechtigt_individualwettbewerb_id WHERE berechtigt_user_id = $user_id) "; -} - -function kategorieFilter($prefix, $suffix = ""): string -{ - global $params; - - $kategorien = explode(",", $params->get('kategorien')); - $result = []; - - foreach ($kategorien as $item) { - $item = trim($item); - if ($item === '') continue; - - // Prüfen, ob es ein Bereich ist - if (strpos($item, '-') !== false) { - $rangeParts = explode('-', $item); - - // genau 2 Teile für einen gültigen Bereich - if (count($rangeParts) !== 2) continue; - - $start = intval(trim($rangeParts[0])); - $end = intval(trim($rangeParts[1])); - - if ($start <= 0 || $end <= 0 || $start > $end) continue; - - for ($i = $start; $i <= $end; $i++) { - $result[$i] = true; // Duplikate vermeiden - } - } else { - $num = intval($item); - if ($num > 0) { - $result[$num] = true; - } - } - } - - if (empty($result)) { - return ""; - } - - $filter = array_keys($result); - sort($filter, SORT_NUMERIC); - - return " $prefix (" . implode(", ", $filter) . ") $suffix"; -} - -function idListeParameterFilter(string $parameterName, string $prefix, string $suffix = ""): string -{ - $jInput = Factory::getContainer()->get(SiteApplication::class)->input; - $werte = $jInput->get($parameterName, '', 'STRING'); - - $result = []; - foreach (explode(",", $werte) as $item) { - $item = trim($item); - if ($item === '') continue; - - $num = intval($item); - if ($num > 0) { - $result[$num] = true; // Duplikate vermeiden - } - } - - if (empty($result)) { - return ""; - } - - $filter = array_keys($result); - sort($filter, SORT_NUMERIC); - - return " $prefix (" . implode(", ", $filter) . ") $suffix"; -} - -function halloffameIdFilter($prefix): string -{ - // Keine Bereichssuche bei der Halloffame-Id, nur einzelne Werte - return idListeParameterFilter('halloffame_id', $prefix); -} - -function halloffameJahrFilter($prefix): string -{ - $minJahr = 1900; - $maxJahr = (int) date('Y') + 5; - - $jInput = Factory::getContainer()->get(SiteApplication::class)->input; - $werte = $jInput->get('jahr', '', 'STRING'); - - $result = []; - foreach (explode(",", $werte) as $item) { - $item = trim($item); - if ($item === '') continue; - - // Prüfen, ob es ein Bereich ist - if (strpos($item, '-') !== false) { - $rangeParts = explode('-', $item); - - // genau 2 Teile für einen gültigen Bereich - if (count($rangeParts) !== 2) continue; - - $start = intval(trim($rangeParts[0])); - $end = intval(trim($rangeParts[1])); - - if ($start <= 0 || $end <= 0) continue; - - // Werte vertauschen, falls der 2. Wert kleiner als der 1. ist - if ($end < $start) { - [$start, $end] = [$end, $start]; - } - - // Bereich auf 1900 .. aktuelles Jahr+5 begrenzen - $start = max($start, $minJahr); - $end = min($end, $maxJahr); - - if ($start > $end) continue; - - for ($i = $start; $i <= $end; $i++) { - $result[$i] = true; // Duplikate vermeiden - } - } else { - $num = intval($item); - if ($num <= 0) continue; - - // Einzelwert auf 1900 .. aktuelles Jahr+5 begrenzen - $num = max($minJahr, min($maxJahr, $num)); - $result[$num] = true; - } - } - - if (empty($result)) { - return ""; - } - - $filter = array_keys($result); - sort($filter, SORT_NUMERIC); - - return " $prefix (" . implode(", ", $filter) . ")"; -} - -function halloffameAlleTeams($db): array -{ - return loadObjectList($db, "SELECT team_id, teamname FROM #__sportsmanager_team ORDER BY team_id DESC"); -} - -function halloffameTeamIdFuerTeamname(array $alleTeams, ?string $teamname) -{ - if (empty($teamname)) - return null; - foreach ($alleTeams as $team) { - if (str_starts_with($team->teamname, $teamname)) - return $team->team_id; - } - return null; -} - -function halloffameAlleSpielerInfo($db): array -{ - // "Aktiv" = hat einen aktuellen Verein; ohne aktuellen Verein liefert spieler_details ohnehin keine Daten - $rows = loadObjectList($db, "SELECT spieler_id, geschlecht, aktueller_verein_id FROM #__sportsmanager_spieler"); - $result = []; - foreach ($rows as $row) { - $result[$row->spieler_id] = (object) [ - 'geschlecht' => $row->geschlecht, - 'aktiv' => !empty($row->aktueller_verein_id), - ]; - } - return $result; -} - -function halloffameSpielerAktiv(array $alleSpielerInfo, $spieler_id): bool -{ - return empty($spieler_id) || !isset($alleSpielerInfo[$spieler_id]) || $alleSpielerInfo[$spieler_id]->aktiv; -} - -function halloffameSpielerBildId(array $alleSpielerInfo, $spieler_id) -{ - return halloffameSpielerAktiv($alleSpielerInfo, $spieler_id) ? $spieler_id : ''; -} - -function halloffameSpielerBildAlternativ(array $alleSpielerInfo, $spieler_id, string $geschaetztesGeschlecht = ''): string -{ - if (!empty($spieler_id) && isset($alleSpielerInfo[$spieler_id])) - return $alleSpielerInfo[$spieler_id]->geschlecht == 'M' ? 'm' : 'w'; - if ($geschaetztesGeschlecht === 'M') - return 'm'; - if ($geschaetztesGeschlecht === 'W') - return 'w'; - return 'n'; -} - -function halloffameGeschlechtZaehlen(object $ziel, array $alleSpielerInfo, $spieler1_id, $spieler2_id): void -{ - foreach ([$spieler1_id, $spieler2_id] as $id) { - if (empty($id) || !isset($alleSpielerInfo[$id])) - continue; - if ($alleSpielerInfo[$id]->geschlecht == 'M') - $ziel->anzahl_m++; - else - $ziel->anzahl_w++; - } -} - -function halloffameGeschaetztesGeschlecht($anzahl_m, $anzahl_w): string -{ - if ($anzahl_m > $anzahl_w) - return 'M'; - if ($anzahl_w > $anzahl_m) - return 'W'; - return ''; -} - -function halloffameAlleVereineInfo($db): array -{ - $rows = loadObjectList($db, "SELECT verein_id, ausgetreten FROM #__sportsmanager_verein"); - $result = []; - foreach ($rows as $row) { - $result[$row->verein_id] = (object) [ - 'aktiv' => empty($row->ausgetreten), - ]; - } - return $result; -} - -function halloffameVereinAktiv(array $alleVereineInfo, $verein_id): bool -{ - return empty($verein_id) || !isset($alleVereineInfo[$verein_id]) || $alleVereineInfo[$verein_id]->aktiv; -} - -function halloffameNameLink(string $bild_type, $id, array $alleSpielerInfo, array $alleVereineInfo, string $nameHtml): string -{ - if (empty($id)) - return $nameHtml; - if ($bild_type === 'spieler' && !halloffameSpielerAktiv($alleSpielerInfo, $id)) - return $nameHtml; - if ($bild_type === 'vereine' && !halloffameVereinAktiv($alleVereineInfo, $id)) - return $nameHtml; - - $tasks = ['spieler' => 'spieler_details', 'vereine' => 'verein_details', 'mannschaften' => 'team_details']; - if (!isset($tasks[$bild_type])) - return $nameHtml; - - return '' . $nameHtml . ''; -} - -function halloffameTitel(): string -{ - global $params; - - $titel = trim((string) $params->get('titel', '')); - if ($titel !== '') - return $titel; - - $menu = Factory::getContainer()->get(SiteApplication::class)->getMenu()->getActive(); - if ($menu !== null && trim((string) $menu->title) !== '') - return $menu->title; - - return ''; -} - -function turnierFilter($prefix): string -{ - $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_turnier_id FROM #__sportsmanager_berechtigt_fuer_turnier WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21) "; -} - -function vereinFilter($prefix): string -{ - $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_verein_id FROM #__sportsmanager_berechtigt_fuer_verein INNER JOIN #__sportsmanager_verein ON berechtigt_verein_id = verein_id WHERE berechtigt_user_id = $user_id AND NOT ausgetreten) "; -} - -function veranstalterFilter($prefix): string -{ - $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_veranstalter_id FROM #__sportsmanager_berechtigt_fuer_veranstalter WHERE berechtigt_user_id = $user_id) "; -} - -function veranstaltungFilter($prefix): string -{ - $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_veranstaltung_id FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21) "; -} - -// Berechnet Datum zum Montag der ersten Kalenderwoche eines Jahres -function firstkw($jahr): bool|int -{ - $erster = mktime(0, 0, 0, 1, 1, $jahr); - $wtag = date('w', $erster); - if ($wtag <= 4) { - /** - * Donnerstag oder kleiner: auf den Montag zurückrechnen. - */ - $montag = mktime(0, 0, 0, 1, 1 - ($wtag - 1), $jahr); - } else { - /** - * auf den Montag nach vorne rechnen. - */ - $montag = mktime(0, 0, 0, 1, 1 + (7 - $wtag + 1), $jahr); - } - return $montag; -} - -// Berechnet Wochentag über Kalenderwoche, Jahr und Wochentag (0 = Montag, ..., 6 = Sonntag) -function mondaykw($kw, $jahr, $weekday): bool|int -{ - $firstmonday = firstkw($jahr); - $mon_monat = date('m', $firstmonday); - $mon_jahr = date('Y', $firstmonday); - $mon_tage = (int)date('d', $firstmonday); - $tage = ($kw - 1) * 7; - return mktime(0, 0, 0, $mon_monat, $mon_tage + $tage + $weekday, $mon_jahr); -} - -// Berechnet Termin am Wochentag (0 = Montag, ..., 6 = Sonntag) in Kalenderwoche zum Datum -function geaenderterWochentag($datum, $wochentag): bool|int -{ - $wtag = date('w', $datum); - if ($wtag == 0) // Sonntag - $wtag = 7; - $mon_monat = date('m', $datum); - $mon_jahr = date('Y', $datum); - $mon_tage = (int)date('d', $datum); - return mktime(0, 0, 0, $mon_monat, $mon_tage + 1 - $wtag + $wochentag, $mon_jahr); -} - -function normalisiertesDatum($datum): ?string -{ - if ($datum == NULL) - return NULL; - - if (str_contains($datum, "-")) - $trennzeichen = "-"; - else - $trennzeichen = "."; - - $t = explode($trennzeichen, $datum); - $n = count($t); - if ($n == 1) { - $s = $t[0]; - if (strlen($s) < 8) - return NULL; - $jahr = intval(substr($s, 0, 4)); - $monat = intval(substr($s, 4, 2)); - $tag = intval(substr($s, 6, 2)); - } else if ($n == 3) { - if ($trennzeichen != ".") { - $jahr = intval($t[0]); - if (strlen($t[0]) <= 2) - $jahr += 1900; - $monat = intval($t[1]); - $tag = intval($t[2]); - } else { - $tag = intval($t[0]); - $monat = intval($t[1]); - $jahr = intval($t[2]); - if (strlen($t[2]) <= 2) - $jahr += 1900; - } - } else - return NULL; - - if (!checkdate($monat, $tag, $jahr)) - return NULL; - - return sprintf("%04d-%02d-%02d", $jahr, $monat, $tag); -} - -function normalisierteUhrzeit($uhrzeit): ?string -{ - if ($uhrzeit == NULL) - return NULL; - - if (str_contains($uhrzeit, "-")) - $trennzeichen = "-"; - else - $trennzeichen = ":"; - - $t = explode($trennzeichen, $uhrzeit); - $n = count($t); - if ($n == 1) { - $s = $t[0]; - $len = strlen($s); - if ($len != 4 && $len != 6) - return NULL; - $stunden = intval(substr($s, 0, 2)); - $minuten = intval(substr($s, 2, 2)); - $sekunden = $len != 6 ? 0 : intval(substr($s, 4, 2)); - } else if ($n == 2 || $n == 3) { - $stunden = intval($t[0]); - $minuten = intval($t[1]); - $sekunden = $n != 3 ? 0 : intval($t[2]); - } else - return NULL; - - if ($stunden < 0 || $stunden > 23 || $minuten < 0 || $minuten > 59 || $sekunden < 0 || $sekunden > 59) - return NULL; - - return sprintf("%02d:%02d:%02d", $stunden, $minuten, $sekunden); -} - -function runden_detailliert_invers($runden): ?string -{ - if ($runden == null) - return null; - $runden_invers = ""; - $saetze = explode(" ", $runden); - foreach ($saetze as $satz) { - $punkte = explode(":", $satz); - if (!empty($runden_invers)) - $runden_invers .= " "; - $runden_invers .= $punkte[1] . ":" . $punkte[0]; - } - return $runden_invers; -} - -function runden_detailliert_auswertung($runden): array -{ - $ergebnis = 0; - $heim_saetze = 0; - $unentschieden_saetze = 0; - $gast_saetze = 0; - $heim_punkte = 0; - $gast_punkte = 0; - if ($runden != null) { - $saetze = explode(" ", $runden); - foreach ($saetze as $satz) { - $punkte = explode(":", $satz); - $heim_punkte += (int)$punkte[0]; - $gast_punkte += (int)$punkte[1]; - if ($punkte[0] > $punkte[1]) - $heim_saetze++; - else if ($punkte[0] < $punkte[1]) - $gast_saetze++; - else - $unentschieden_saetze++; - } - if ($heim_saetze > $gast_saetze) - $ergebnis = 1; - else if ($heim_saetze < $gast_saetze) - $ergebnis = 2; - } - return array($ergebnis, $heim_saetze, $unentschieden_saetze, $gast_saetze, $heim_punkte, $gast_punkte); -} - -function spielpunkteFuerSpiel($wertung, $heim_punkte, $gast_punkte, $ergebnis_detailliert = null): array -{ - if ($wertung == 2) - return array($heim_punkte, $gast_punkte); - $je_satz = $wertung >= 10; - $grund = $wertung % 10; - $sieg = $grund == 0 ? 2 : ($grund == 1 ? 3 : 1); - $remis = $grund == 3 ? 0 : 1; - if ($je_satz) { - if (empty($ergebnis_detailliert)) - return array($sieg * (int)$heim_punkte, $sieg * (int)$gast_punkte); - $auswertung = runden_detailliert_auswertung($ergebnis_detailliert); - return array($sieg * $auswertung[1] + $remis * $auswertung[2], - $sieg * $auswertung[3] + $remis * $auswertung[2]); - } - if ($heim_punkte > $gast_punkte) - return array($sieg, 0); - if ($heim_punkte < $gast_punkte) - return array(0, $sieg); - if ($heim_punkte == 0 && $gast_punkte == 0) - return array(0, 0); - return array($remis, $remis); -} - -function toreFuerSpiel($punktetyp, $satzergebnisse, $heim_punkte, $gast_punkte, $ergebnis_detailliert): array -{ - if ($punktetyp == 0) - return array((int)$heim_punkte, (int)$gast_punkte); - if (!empty($satzergebnisse) && !empty($ergebnis_detailliert)) { - $auswertung = runden_detailliert_auswertung($ergebnis_detailliert); - return array($auswertung[4], $auswertung[5]); - } - return array(null, null); -} - -function jeSatzWertung($wertung_einzel, $wertung_doppel): bool -{ - return $wertung_einzel >= 10 || $wertung_doppel >= 10; -} - -function ausgetragenBedingung($je_satz, $alias): string -{ - return "($alias.heim_punkte != 0 OR $alias.gast_punkte != 0" - . ($je_satz ? " OR NOT ISNULL($alias.heim_tore)" : "") . ")"; -} - -function ergebnisVorhanden($je_satz, $heim_punkte, $gast_punkte, $heim_tore): bool -{ - return $heim_punkte != null || $gast_punkte != null || ($je_satz && $heim_tore !== null); -} - -function saetzeRemisFuerSpiel($punktetyp, $satzergebnisse, $ergebnis_detailliert): ?int -{ - if ($punktetyp == 0 || empty($satzergebnisse) || empty($ergebnis_detailliert)) - return null; - $auswertung = runden_detailliert_auswertung($ergebnis_detailliert); - return $auswertung[2]; -} - -// pass two file names -// returns TRUE if files are the same, FALSE otherwise -function files_identical($fn1, $fn2): bool -{ - if (!is_file($fn1) || !is_file($fn2)) - return FALSE; - - if (filesize($fn1) !== filesize($fn2)) - return FALSE; - - if (!$fp1 = fopen($fn1, 'rb')) - return FALSE; - - if (!$fp2 = fopen($fn2, 'rb')) { - fclose($fp1); - return FALSE; - } - - $same = TRUE; - while (!feof($fp1) and !feof($fp2)) - if (fread($fp1, 4096) !== fread($fp2, 4096)) { - $same = FALSE; - break; - } - - if (feof($fp1) !== feof($fp2)) - $same = FALSE; - - fclose($fp1); - fclose($fp2); - - return $same; -} - +createFunc("ROUND", 'round', 1); + $this->createFunc("VERTEILUNG", 'mathParserVerteilung', 4); + $this->createFunc("VERTEILUNGR", 'mathParserVerteilungR', 4); + } catch (Exception $e) { + Log::add('an error occurred: ' . $e->getMessage(), Log::ERROR, 'com_sportsmanager'); + throw new RuntimeException('An error occurred.', 500); + } + } +} + +#[NoReturn] function keinZugriff($login = FALSE): void +{ + if (isJson()) { + abortWithError(401 . ' Unauthorized'); + } + if (!$login || Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id) { + Log::add('Unauthorized user with id ' . Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id, Log::WARNING, 'com_sportsmanager'); + throw new RuntimeException('Not authorized!', 401); + } + $version = new Version(); + $joomla = $version->getShortVersion(); + $u = Uri::getInstance(); + $redirectUrl = urlencode(base64_encode($u->toString())); + $redirectUrl = '&return=' . $redirectUrl; + $joomlaLoginUrl = 'index.php?option=' . (!str_starts_with($joomla, '1.5') ? 'com_users' : 'com_user') . '&view=login'; + $finalUrl = $joomlaLoginUrl . $redirectUrl; + $app = Factory::getContainer()->get(SiteApplication::class); + $app->redirect(Route::_($finalUrl)); + jexit(); +} + +function bereinigterDateiname($dateiname): array|string +{ + $_convertTable = array( + '&' => 'and', '@' => 'at', '©' => 'c', '®' => 'r', 'À' => 'a', + 'Á' => 'a', 'Â' => 'a', 'Ä' => 'a', 'Å' => 'a', 'Æ' => 'ae', 'Ç' => 'c', + 'È' => 'e', 'É' => 'e', 'Ë' => 'e', 'Ì' => 'i', 'Í' => 'i', 'Î' => 'i', + 'Ï' => 'i', 'Ò' => 'o', 'Ó' => 'o', 'Ô' => 'o', 'Õ' => 'o', 'Ö' => 'o', + 'Ø' => 'o', 'Ù' => 'u', 'Ú' => 'u', 'Û' => 'u', 'Ü' => 'u', 'Ý' => 'y', + 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ä' => 'a', 'å' => 'a', + 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', + 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ò' => 'o', 'ó' => 'o', + 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', + 'û' => 'u', 'ü' => 'u', 'ý' => 'y', 'þ' => 'p', 'ÿ' => 'y', 'Ā' => 'a', + 'ā' => 'a', 'Ă' => 'a', 'ă' => 'a', 'Ą' => 'a', 'ą' => 'a', 'Ć' => 'c', + 'ć' => 'c', 'Ĉ' => 'c', 'ĉ' => 'c', 'Ċ' => 'c', 'ċ' => 'c', 'Č' => 'c', + 'č' => 'c', 'Ď' => 'd', 'ď' => 'd', 'Đ' => 'd', 'đ' => 'd', 'Ē' => 'e', + 'ē' => 'e', 'Ĕ' => 'e', 'ĕ' => 'e', 'Ė' => 'e', 'ė' => 'e', 'Ę' => 'e', + 'ę' => 'e', 'Ě' => 'e', 'ě' => 'e', 'Ĝ' => 'g', 'ĝ' => 'g', 'Ğ' => 'g', + 'ğ' => 'g', 'Ġ' => 'g', 'ġ' => 'g', 'Ģ' => 'g', 'ģ' => 'g', 'Ĥ' => 'h', + 'ĥ' => 'h', 'Ħ' => 'h', 'ħ' => 'h', 'Ĩ' => 'i', 'ĩ' => 'i', 'Ī' => 'i', + 'ī' => 'i', 'Ĭ' => 'i', 'ĭ' => 'i', 'Į' => 'i', 'į' => 'i', 'İ' => 'i', + 'ı' => 'i', 'IJ' => 'ij', 'ij' => 'ij', 'Ĵ' => 'j', 'ĵ' => 'j', 'Ķ' => 'k', + 'ķ' => 'k', 'ĸ' => 'k', 'Ĺ' => 'l', 'ĺ' => 'l', 'Ļ' => 'l', 'ļ' => 'l', + 'Ľ' => 'l', 'ľ' => 'l', 'Ŀ' => 'l', 'ŀ' => 'l', 'Ł' => 'l', 'ł' => 'l', + 'Ń' => 'n', 'ń' => 'n', 'Ņ' => 'n', 'ņ' => 'n', 'Ň' => 'n', 'ň' => 'n', + 'ʼn' => 'n', 'Ŋ' => 'n', 'ŋ' => 'n', 'Ō' => 'o', 'ō' => 'o', 'Ŏ' => 'o', + 'ŏ' => 'o', 'Ő' => 'o', 'ő' => 'o', 'Œ' => 'oe', 'œ' => 'oe', 'Ŕ' => 'r', + 'ŕ' => 'r', 'Ŗ' => 'r', 'ŗ' => 'r', 'Ř' => 'r', 'ř' => 'r', 'Ś' => 's', + 'ś' => 's', 'Ŝ' => 's', 'ŝ' => 's', 'Ş' => 's', 'ş' => 's', 'Š' => 's', + 'š' => 's', 'Ţ' => 't', 'ţ' => 't', 'Ť' => 't', 'ť' => 't', 'Ŧ' => 't', + 'ŧ' => 't', 'Ũ' => 'u', 'ũ' => 'u', 'Ū' => 'u', 'ū' => 'u', 'Ŭ' => 'u', + 'ŭ' => 'u', 'Ů' => 'u', 'ů' => 'u', 'Ű' => 'u', 'ű' => 'u', 'Ų' => 'u', + 'ų' => 'u', 'Ŵ' => 'w', 'ŵ' => 'w', 'Ŷ' => 'y', 'ŷ' => 'y', 'Ÿ' => 'y', + 'Ź' => 'z', 'ź' => 'z', 'Ż' => 'z', 'ż' => 'z', 'Ž' => 'z', 'ž' => 'z', + 'ſ' => 'z', 'Ə' => 'e', 'ƒ' => 'f', 'Ơ' => 'o', 'ơ' => 'o', 'Ư' => 'u', + 'ư' => 'u', 'Ǎ' => 'a', 'ǎ' => 'a', 'Ǐ' => 'i', 'ǐ' => 'i', 'Ǒ' => 'o', + 'ǒ' => 'o', 'Ǔ' => 'u', 'ǔ' => 'u', 'Ǖ' => 'u', 'ǖ' => 'u', 'Ǘ' => 'u', + 'ǘ' => 'u', 'Ǚ' => 'u', 'ǚ' => 'u', 'Ǜ' => 'u', 'ǜ' => 'u', 'Ǻ' => 'a', + 'ǻ' => 'a', 'Ǽ' => 'ae', 'ǽ' => 'ae', 'Ǿ' => 'o', 'ǿ' => 'o', 'ə' => 'e', + 'Ё' => 'jo', 'Є' => 'e', 'І' => 'i', 'Ї' => 'i', 'А' => 'a', 'Б' => 'b', + 'В' => 'v', 'Г' => 'g', 'Д' => 'd', 'Е' => 'e', 'Ж' => 'zh', 'З' => 'z', + 'И' => 'i', 'Й' => 'j', 'К' => 'k', 'Л' => 'l', 'М' => 'm', 'Н' => 'n', + 'О' => 'o', 'П' => 'p', 'Р' => 'r', 'С' => 's', 'Т' => 't', 'У' => 'u', + 'Ф' => 'f', 'Х' => 'h', 'Ц' => 'c', 'Ч' => 'ch', 'Ш' => 'sh', 'Щ' => 'sch', + 'Ъ' => '-', 'Ы' => 'y', 'Ь' => '-', 'Э' => 'je', 'Ю' => 'ju', 'Я' => 'ja', + 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', + 'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'j', 'к' => 'k', 'л' => 'l', + 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', + 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', + 'ш' => 'sh', 'щ' => 'sch', 'ъ' => '-', 'ы' => 'y', 'ь' => '-', 'э' => 'je', + 'ю' => 'ju', 'я' => 'ja', 'ё' => 'jo', 'є' => 'e', 'і' => 'i', 'ї' => 'i', + 'Ґ' => 'g', 'ґ' => 'g', 'א' => 'a', 'ב' => 'b', 'ג' => 'g', 'ד' => 'd', + 'ה' => 'h', 'ו' => 'v', 'ז' => 'z', 'ח' => 'h', 'ט' => 't', 'י' => 'i', + 'ך' => 'k', 'כ' => 'k', 'ל' => 'l', 'ם' => 'm', 'מ' => 'm', 'ן' => 'n', + 'נ' => 'n', 'ס' => 's', 'ע' => 'e', 'ף' => 'p', 'פ' => 'p', 'ץ' => 'C', + 'צ' => 'c', 'ק' => 'q', 'ר' => 'r', 'ש' => 'w', 'ת' => 't', '™' => 'tm', + ); + $bad = array_merge( + array_map('chr', range(0, 31)), + array("<", ">", ":", '"', "/", "\\", "|", "?", "*")); + + return str_replace($bad, "", strtr($dateiname, $_convertTable)); +} + +function setMinMemoryLimit($memDestSize): void +{ + if (getBytes(ini_get('memory_limit')) < getBytes($memDestSize)) + ini_set('memory_limit', $memDestSize); +} + +function getBytes($val): int|string +{ + $val = trim($val); + $numeric = substr($val, 0, strlen($val) - 1); + $last = strtolower($val[strlen($val) - 1]); + switch ($last) { + // The 'G' modifier is available since PHP 5.1.0 + case 'm': + case 'g': + case 'k': + $numeric *= 1024; + break; + } + return $numeric; +} + +function encrypt($str, $key): string +{ + $result = ""; + for ($i = 0; $i < strlen($str); $i++) { + $char = substr($str, $i, 1); + $keychar = substr($key, ($i % strlen($key)) - 1, 1); + $char = chr(ord($char) + ord($keychar)); + $result .= $char; + } + return base64_encode($result); +} + +function decrypt($str, $key): string +{ + $str = base64_decode($str); + $result = ""; + for ($i = 0; $i < strlen($str); $i++) { + $char = substr($str, $i, 1); + $keychar = substr($key, ($i % strlen($key)) - 1, 1); + $char = chr(ord($char) - ord($keychar)); + $result .= $char; + } + return $result; +} + +function individualwettbewerbFilter($prefix): string +{ + $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; + return " " . $prefix . " (SELECT berechtigt_individualwettbewerb_id FROM #__sportsmanager_berechtigt_fuer_individualwettbewerb INNER JOIN #__sportsmanager_individualwettbewerb ON individualwettbewerb_id = berechtigt_individualwettbewerb_id WHERE berechtigt_user_id = $user_id) "; +} + +function kategorieFilter($prefix, $suffix = ""): string +{ + global $params; + + $kategorien = explode(",", $params->get('kategorien')); + $result = []; + + foreach ($kategorien as $item) { + $item = trim($item); + if ($item === '') continue; + + // Prüfen, ob es ein Bereich ist + if (strpos($item, '-') !== false) { + $rangeParts = explode('-', $item); + + // genau 2 Teile für einen gültigen Bereich + if (count($rangeParts) !== 2) continue; + + $start = intval(trim($rangeParts[0])); + $end = intval(trim($rangeParts[1])); + + if ($start <= 0 || $end <= 0 || $start > $end) continue; + + for ($i = $start; $i <= $end; $i++) { + $result[$i] = true; // Duplikate vermeiden + } + } else { + $num = intval($item); + if ($num > 0) { + $result[$num] = true; + } + } + } + + if (empty($result)) { + return ""; + } + + $filter = array_keys($result); + sort($filter, SORT_NUMERIC); + + return " $prefix (" . implode(", ", $filter) . ") $suffix"; +} + +function idListeParameterFilter(string $parameterName, string $prefix, string $suffix = ""): string +{ + $jInput = Factory::getContainer()->get(SiteApplication::class)->input; + $werte = $jInput->get($parameterName, '', 'STRING'); + + $result = []; + foreach (explode(",", $werte) as $item) { + $item = trim($item); + if ($item === '') continue; + + $num = intval($item); + if ($num > 0) { + $result[$num] = true; // Duplikate vermeiden + } + } + + if (empty($result)) { + return ""; + } + + $filter = array_keys($result); + sort($filter, SORT_NUMERIC); + + return " $prefix (" . implode(", ", $filter) . ") $suffix"; +} + +function halloffameIdFilter($prefix): string +{ + // Keine Bereichssuche bei der Halloffame-Id, nur einzelne Werte + return idListeParameterFilter('halloffame_id', $prefix); +} + +function halloffameJahrFilter($prefix): string +{ + $minJahr = 1900; + $maxJahr = (int) date('Y') + 5; + + $jInput = Factory::getContainer()->get(SiteApplication::class)->input; + $werte = $jInput->get('jahr', '', 'STRING'); + + $result = []; + foreach (explode(",", $werte) as $item) { + $item = trim($item); + if ($item === '') continue; + + // Prüfen, ob es ein Bereich ist + if (strpos($item, '-') !== false) { + $rangeParts = explode('-', $item); + + // genau 2 Teile für einen gültigen Bereich + if (count($rangeParts) !== 2) continue; + + $start = intval(trim($rangeParts[0])); + $end = intval(trim($rangeParts[1])); + + if ($start <= 0 || $end <= 0) continue; + + // Werte vertauschen, falls der 2. Wert kleiner als der 1. ist + if ($end < $start) { + [$start, $end] = [$end, $start]; + } + + // Bereich auf 1900 .. aktuelles Jahr+5 begrenzen + $start = max($start, $minJahr); + $end = min($end, $maxJahr); + + if ($start > $end) continue; + + for ($i = $start; $i <= $end; $i++) { + $result[$i] = true; // Duplikate vermeiden + } + } else { + $num = intval($item); + if ($num <= 0) continue; + + // Einzelwert auf 1900 .. aktuelles Jahr+5 begrenzen + $num = max($minJahr, min($maxJahr, $num)); + $result[$num] = true; + } + } + + if (empty($result)) { + return ""; + } + + $filter = array_keys($result); + sort($filter, SORT_NUMERIC); + + return " $prefix (" . implode(", ", $filter) . ")"; +} + +function halloffameAlleTeams($db): array +{ + return loadObjectList($db, "SELECT team_id, teamname FROM #__sportsmanager_team ORDER BY team_id DESC"); +} + +function halloffameTeamIdFuerTeamname(array $alleTeams, ?string $teamname) +{ + if (empty($teamname)) + return null; + foreach ($alleTeams as $team) { + if (str_starts_with($team->teamname, $teamname)) + return $team->team_id; + } + return null; +} + +function halloffameAlleSpielerInfo($db): array +{ + // "Aktiv" = hat einen aktuellen Verein; ohne aktuellen Verein liefert spieler_details ohnehin keine Daten + $rows = loadObjectList($db, "SELECT spieler_id, geschlecht, aktueller_verein_id FROM #__sportsmanager_spieler"); + $result = []; + foreach ($rows as $row) { + $result[$row->spieler_id] = (object) [ + 'geschlecht' => $row->geschlecht, + 'aktiv' => !empty($row->aktueller_verein_id), + ]; + } + return $result; +} + +function halloffameSpielerAktiv(array $alleSpielerInfo, $spieler_id): bool +{ + return empty($spieler_id) || !isset($alleSpielerInfo[$spieler_id]) || $alleSpielerInfo[$spieler_id]->aktiv; +} + +function halloffameSpielerBildId(array $alleSpielerInfo, $spieler_id) +{ + return halloffameSpielerAktiv($alleSpielerInfo, $spieler_id) ? $spieler_id : ''; +} + +function halloffameSpielerBildAlternativ(array $alleSpielerInfo, $spieler_id, string $geschaetztesGeschlecht = ''): string +{ + if (!empty($spieler_id) && isset($alleSpielerInfo[$spieler_id])) + return $alleSpielerInfo[$spieler_id]->geschlecht == 'M' ? 'm' : 'w'; + if ($geschaetztesGeschlecht === 'M') + return 'm'; + if ($geschaetztesGeschlecht === 'W') + return 'w'; + return 'n'; +} + +function halloffameGeschlechtZaehlen(object $ziel, array $alleSpielerInfo, $spieler1_id, $spieler2_id): void +{ + foreach ([$spieler1_id, $spieler2_id] as $id) { + if (empty($id) || !isset($alleSpielerInfo[$id])) + continue; + if ($alleSpielerInfo[$id]->geschlecht == 'M') + $ziel->anzahl_m++; + else + $ziel->anzahl_w++; + } +} + +function halloffameGeschaetztesGeschlecht($anzahl_m, $anzahl_w): string +{ + if ($anzahl_m > $anzahl_w) + return 'M'; + if ($anzahl_w > $anzahl_m) + return 'W'; + return ''; +} + +function halloffameAlleVereineInfo($db): array +{ + $rows = loadObjectList($db, "SELECT verein_id, ausgetreten FROM #__sportsmanager_verein"); + $result = []; + foreach ($rows as $row) { + $result[$row->verein_id] = (object) [ + 'aktiv' => empty($row->ausgetreten), + ]; + } + return $result; +} + +function halloffameVereinAktiv(array $alleVereineInfo, $verein_id): bool +{ + return empty($verein_id) || !isset($alleVereineInfo[$verein_id]) || $alleVereineInfo[$verein_id]->aktiv; +} + +function halloffameNameLink(string $bild_type, $id, array $alleSpielerInfo, array $alleVereineInfo, string $nameHtml): string +{ + if (empty($id)) + return $nameHtml; + if ($bild_type === 'spieler' && !halloffameSpielerAktiv($alleSpielerInfo, $id)) + return $nameHtml; + if ($bild_type === 'vereine' && !halloffameVereinAktiv($alleVereineInfo, $id)) + return $nameHtml; + + $tasks = ['spieler' => 'spieler_details', 'vereine' => 'verein_details', 'mannschaften' => 'team_details']; + if (!isset($tasks[$bild_type])) + return $nameHtml; + + return '' . $nameHtml . ''; +} + +function halloffameTitel(): string +{ + global $params; + + $titel = trim((string) $params->get('titel', '')); + if ($titel !== '') + return $titel; + + $menu = Factory::getContainer()->get(SiteApplication::class)->getMenu()->getActive(); + if ($menu !== null && trim((string) $menu->title) !== '') + return $menu->title; + + return ''; +} + +function turnierFilter($prefix): string +{ + $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; + return " " . $prefix . " (SELECT berechtigt_turnier_id FROM #__sportsmanager_berechtigt_fuer_turnier WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21) "; +} + +function vereinFilter($prefix): string +{ + $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; + return " " . $prefix . " (SELECT berechtigt_verein_id FROM #__sportsmanager_berechtigt_fuer_verein INNER JOIN #__sportsmanager_verein ON berechtigt_verein_id = verein_id WHERE berechtigt_user_id = $user_id AND NOT ausgetreten) "; +} + +function veranstalterFilter($prefix): string +{ + $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; + return " " . $prefix . " (SELECT berechtigt_veranstalter_id FROM #__sportsmanager_berechtigt_fuer_veranstalter WHERE berechtigt_user_id = $user_id) "; +} + +function veranstaltungFilter($prefix): string +{ + $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; + return " " . $prefix . " (SELECT berechtigt_veranstaltung_id FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21) "; +} + +// Berechnet Datum zum Montag der ersten Kalenderwoche eines Jahres +function firstkw($jahr): bool|int +{ + $erster = mktime(0, 0, 0, 1, 1, $jahr); + $wtag = date('w', $erster); + if ($wtag <= 4) { + /** + * Donnerstag oder kleiner: auf den Montag zurückrechnen. + */ + $montag = mktime(0, 0, 0, 1, 1 - ($wtag - 1), $jahr); + } else { + /** + * auf den Montag nach vorne rechnen. + */ + $montag = mktime(0, 0, 0, 1, 1 + (7 - $wtag + 1), $jahr); + } + return $montag; +} + +// Berechnet Wochentag über Kalenderwoche, Jahr und Wochentag (0 = Montag, ..., 6 = Sonntag) +function mondaykw($kw, $jahr, $weekday): bool|int +{ + $firstmonday = firstkw($jahr); + $mon_monat = date('m', $firstmonday); + $mon_jahr = date('Y', $firstmonday); + $mon_tage = (int)date('d', $firstmonday); + $tage = ($kw - 1) * 7; + return mktime(0, 0, 0, $mon_monat, $mon_tage + $tage + $weekday, $mon_jahr); +} + +// Berechnet Termin am Wochentag (0 = Montag, ..., 6 = Sonntag) in Kalenderwoche zum Datum +function geaenderterWochentag($datum, $wochentag): bool|int +{ + $wtag = date('w', $datum); + if ($wtag == 0) // Sonntag + $wtag = 7; + $mon_monat = date('m', $datum); + $mon_jahr = date('Y', $datum); + $mon_tage = (int)date('d', $datum); + return mktime(0, 0, 0, $mon_monat, $mon_tage + 1 - $wtag + $wochentag, $mon_jahr); +} + +function normalisiertesDatum($datum): ?string +{ + if ($datum == NULL) + return NULL; + + if (str_contains($datum, "-")) + $trennzeichen = "-"; + else + $trennzeichen = "."; + + $t = explode($trennzeichen, $datum); + $n = count($t); + if ($n == 1) { + $s = $t[0]; + if (strlen($s) < 8) + return NULL; + $jahr = intval(substr($s, 0, 4)); + $monat = intval(substr($s, 4, 2)); + $tag = intval(substr($s, 6, 2)); + } else if ($n == 3) { + if ($trennzeichen != ".") { + $jahr = intval($t[0]); + if (strlen($t[0]) <= 2) + $jahr += 1900; + $monat = intval($t[1]); + $tag = intval($t[2]); + } else { + $tag = intval($t[0]); + $monat = intval($t[1]); + $jahr = intval($t[2]); + if (strlen($t[2]) <= 2) + $jahr += 1900; + } + } else + return NULL; + + if (!checkdate($monat, $tag, $jahr)) + return NULL; + + return sprintf("%04d-%02d-%02d", $jahr, $monat, $tag); +} + +function normalisierteUhrzeit($uhrzeit): ?string +{ + if ($uhrzeit == NULL) + return NULL; + + if (str_contains($uhrzeit, "-")) + $trennzeichen = "-"; + else + $trennzeichen = ":"; + + $t = explode($trennzeichen, $uhrzeit); + $n = count($t); + if ($n == 1) { + $s = $t[0]; + $len = strlen($s); + if ($len != 4 && $len != 6) + return NULL; + $stunden = intval(substr($s, 0, 2)); + $minuten = intval(substr($s, 2, 2)); + $sekunden = $len != 6 ? 0 : intval(substr($s, 4, 2)); + } else if ($n == 2 || $n == 3) { + $stunden = intval($t[0]); + $minuten = intval($t[1]); + $sekunden = $n != 3 ? 0 : intval($t[2]); + } else + return NULL; + + if ($stunden < 0 || $stunden > 23 || $minuten < 0 || $minuten > 59 || $sekunden < 0 || $sekunden > 59) + return NULL; + + return sprintf("%02d:%02d:%02d", $stunden, $minuten, $sekunden); +} + +function runden_detailliert_invers($runden): ?string +{ + if ($runden == null) + return null; + $runden_invers = ""; + $saetze = explode(" ", $runden); + foreach ($saetze as $satz) { + $punkte = explode(":", $satz); + if (!empty($runden_invers)) + $runden_invers .= " "; + $runden_invers .= $punkte[1] . ":" . $punkte[0]; + } + return $runden_invers; +} + +function runden_detailliert_auswertung($runden): array +{ + $ergebnis = 0; + $heim_saetze = 0; + $unentschieden_saetze = 0; + $gast_saetze = 0; + $heim_punkte = 0; + $gast_punkte = 0; + if ($runden != null) { + $saetze = explode(" ", $runden); + foreach ($saetze as $satz) { + $punkte = explode(":", $satz); + $heim_punkte += (int)$punkte[0]; + $gast_punkte += (int)$punkte[1]; + if ($punkte[0] > $punkte[1]) + $heim_saetze++; + else if ($punkte[0] < $punkte[1]) + $gast_saetze++; + else + $unentschieden_saetze++; + } + if ($heim_saetze > $gast_saetze) + $ergebnis = 1; + else if ($heim_saetze < $gast_saetze) + $ergebnis = 2; + } + return array($ergebnis, $heim_saetze, $unentschieden_saetze, $gast_saetze, $heim_punkte, $gast_punkte); +} + +function spielpunkteFuerSpiel($wertung, $heim_punkte, $gast_punkte, $ergebnis_detailliert = null): array +{ + if ($wertung == 2) + return array($heim_punkte, $gast_punkte); + $je_satz = $wertung >= 10; + $grund = $wertung % 10; + $sieg = $grund == 0 ? 2 : ($grund == 1 ? 3 : 1); + $remis = $grund == 3 ? 0 : 1; + if ($je_satz) { + if (empty($ergebnis_detailliert)) + return array($sieg * (int)$heim_punkte, $sieg * (int)$gast_punkte); + $auswertung = runden_detailliert_auswertung($ergebnis_detailliert); + return array($sieg * $auswertung[1] + $remis * $auswertung[2], + $sieg * $auswertung[3] + $remis * $auswertung[2]); + } + if ($heim_punkte > $gast_punkte) + return array($sieg, 0); + if ($heim_punkte < $gast_punkte) + return array(0, $sieg); + if ($heim_punkte == 0 && $gast_punkte == 0) + return array(0, 0); + return array($remis, $remis); +} + +function toreFuerSpiel($punktetyp, $satzergebnisse, $heim_punkte, $gast_punkte, $ergebnis_detailliert): array +{ + if ($punktetyp == 0) + return array((int)$heim_punkte, (int)$gast_punkte); + if (!empty($satzergebnisse) && !empty($ergebnis_detailliert)) { + $auswertung = runden_detailliert_auswertung($ergebnis_detailliert); + return array($auswertung[4], $auswertung[5]); + } + return array(null, null); +} + +function jeSatzWertung($wertung_einzel, $wertung_doppel): bool +{ + return $wertung_einzel >= 10 || $wertung_doppel >= 10; +} + +function ausgetragenBedingung($je_satz, $alias): string +{ + return "($alias.heim_punkte != 0 OR $alias.gast_punkte != 0" + . ($je_satz ? " OR NOT ISNULL($alias.heim_tore)" : "") . ")"; +} + +function ergebnisVorhanden($je_satz, $heim_punkte, $gast_punkte, $heim_tore): bool +{ + return $heim_punkte != null || $gast_punkte != null || ($je_satz && $heim_tore !== null); +} + +function saetzeRemisFuerSpiel($punktetyp, $satzergebnisse, $ergebnis_detailliert): ?int +{ + if ($punktetyp == 0 || empty($satzergebnisse) || empty($ergebnis_detailliert)) + return null; + $auswertung = runden_detailliert_auswertung($ergebnis_detailliert); + return $auswertung[2]; +} + +// pass two file names +// returns TRUE if files are the same, FALSE otherwise +function files_identical($fn1, $fn2): bool +{ + if (!is_file($fn1) || !is_file($fn2)) + return FALSE; + + if (filesize($fn1) !== filesize($fn2)) + return FALSE; + + if (!$fp1 = fopen($fn1, 'rb')) + return FALSE; + + if (!$fp2 = fopen($fn2, 'rb')) { + fclose($fp1); + return FALSE; + } + + $same = TRUE; + while (!feof($fp1) and !feof($fp2)) + if (fread($fp1, 4096) !== fread($fp2, 4096)) { + $same = FALSE; + break; + } + + if (feof($fp1) !== feof($fp2)) + $same = FALSE; + + fclose($fp1); + fclose($fp2); + + return $same; +} +