Merge branch 'sportsmanager2-dev' into feature/auto-email-missing-results

# Conflicts:
#	src/structure/components/com_sportsmanager/database/update.php
#	src/structure/components/com_sportsmanager/views/sportsmanager/view_admin.php
This commit is contained in:
Marvin Flock
2025-09-25 18:16:42 +02:00
5 changed files with 164 additions and 113 deletions
@@ -18,18 +18,25 @@ defined('_JEXEC') or die('Restricted access');
require_once JPATH_SITE . '/components/com_sportsmanager/util/image.php';
require_once JPATH_SITE . '/components/com_sportsmanager/database/init.php';
function UhrzeitWandlerDE($Zeitstempel): mixed
{
$Temp = explode(' ', $Zeitstempel);
$Datum = $Temp[0];
$Uhrzeit = $Temp[1];
if (preg_match("/\d{2}\.\d{2}\.\d{4}/", $Datum)) {
$Datum = substr($Datum, 6, 4) . "-" . substr($Datum, 3, 2) . "-" . substr($Datum, 0, 2);
} else if (preg_match("/\d{4}-\d{2}-\d{2}/", $Datum)) {
return $Zeitstempel;
}
return $Datum . " " . $Uhrzeit;
function UhrzeitWandlerDE(string $input): string {
// mögliche Datumsformate
$formats = [
'Y-m-d H:i',
'd.m.Y H:i',
'd.m.Y H:i:s',
];
foreach ($formats as $format) {
$dt = DateTime::createFromFormat($format, $input);
// prüfen, ob Parsing erfolgreich war UND das Datum exakt passt
if ($dt && $dt->format($format) === $input) {
return $dt->format('Y-m-d H:i:s');
}
}
// falls kein bekanntes Format -> Original zurückgeben
return $input;
}
function validateDate($date, $format = 'Y-m-d H:i:s'): bool
@@ -38,6 +45,22 @@ function validateDate($date, $format = 'Y-m-d H:i:s'): bool
return $d && $d->format($format) == $date;
}
function detectFileEncoding(string $filename): string {
$handle = fopen($filename, "r");
if (!$handle) {
throw new Exception("Datei konnte nicht geöffnet werden: $filename");
}
// Erstes Stück der Datei lesen (nicht alles, reicht für Erkennung)
$sample = fread($handle, 1000);
fclose($handle);
// Encoding bestimmen
$encoding = mb_detect_encoding($sample, ['UTF-8', 'ISO-8859-1', 'Windows-1252'], true);
return $encoding ?: 'UTF-8'; // Fallback auf UTF-8
}
function adminUebersicht(): void
{
$db = getDatabase();
@@ -8330,7 +8353,7 @@ function adminSaveBegegnungSpielplan(): void
}
if ($zwischenergebnis) {
$query = "INSERT INTO #__sportsmanager_unbestaetigtes_ergebnis (begegnung_id, vorschlagendes_team_id, zwischenergebnis, kommentar, vorgeschlagen)"
$query = "INSERT IGNORE INTO #__sportsmanager_unbestaetigtes_ergebnis (begegnung_id, vorschlagendes_team_id, zwischenergebnis, kommentar, vorgeschlagen)"
. "\n VALUES ('$id', " . ($bestaetigen != 0 ? "'$vorschlagendes_team_id'" : "'0'") . ", '1', '$kommentar', now());";
$db->setQuery($query);
if (!$db->execute()) {
@@ -8344,7 +8367,7 @@ function adminSaveBegegnungSpielplan(): void
abortWithError($db->stderr(true));
}
} else if ($bestaetigen != 0) {
$query = "INSERT INTO #__sportsmanager_unbestaetigtes_ergebnis (begegnung_id, vorschlagendes_team_id, kommentar, vorgeschlagen)"
$query = "INSERT IGNORE INTO #__sportsmanager_unbestaetigtes_ergebnis (begegnung_id, vorschlagendes_team_id, kommentar, vorgeschlagen)"
. "\n VALUES ('$id', '$vorschlagendes_team_id', '$kommentar', now());";
$db->setQuery($query);
if (!$db->execute()) {
@@ -9502,6 +9525,8 @@ function adminBegegnungenImportieren(): void
redirectSportsManagerURL('&task=admin_spieler', Text::_('COM_SPORTSMANAGER_NO_FILE_SPECIFIED'));
}
$encoding = detectFileEncoding($_FILES["daten"]["tmp_name"]);
$handle = fopen($_FILES["daten"]["tmp_name"], "r");
if (!$handle) {
redirectSportsManagerURL('&task=admin_spieler', Text::_('COM_SPORTSMANAGER_COULD_NOT_OPEN_FILE'));
@@ -9523,6 +9548,7 @@ function adminBegegnungenImportieren(): void
$Titelzeile = null;
$import_zeile = false;
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
if (empty($data[0])){continue;}
if ($Zeile == 1) {
foreach($data as $spalte_nr => $spalte)
{
@@ -9531,7 +9557,7 @@ function adminBegegnungenImportieren(): void
if (vergleich($spalte,"heim,heimteam,heimmannschaft")) $Titelzeile['Heim'] = $spalte_nr;
if (vergleich($spalte,"gast,gastteam,gastmannschaft")) $Titelzeile['Gast'] = $spalte_nr;
if (vergleich($spalte,"spielnr,spielnummer")) $Titelzeile['Spiel_Nr'] = $spalte_nr;
if (vergleich($spalte,"spieltagtitel")) $Titelzeile['Spieltag_Titel'] = $spalte_nr;
if (vergleich($spalte,"spieltagtitel,spieltitel")) $Titelzeile['Spieltag_Titel'] = $spalte_nr;
if (vergleich($spalte,"jahr,spieljahr")) $Titelzeile['Spieljahr'] = $spalte_nr;
if (vergleich($spalte,"kalenderwoche,woche,kw")) $Titelzeile['Kalenderwoche'] = $spalte_nr;
}
@@ -9540,10 +9566,16 @@ function adminBegegnungenImportieren(): void
$bgcolor = "green";
$Begegnung[$Zeile]['spieltag'] = $data[$Titelzeile['Spieltag_Nr']];
$Begegnung[$Zeile]['zeitpunkt'] = UhrzeitWandlerDE($data[$Titelzeile['Spielstart']]);
if ($encoding == "UTF-8"){
$Begegnung[$Zeile]['heim_team_id'] = $Mannschaften[$data[$Titelzeile['Heim']]]['team_id'];
$Begegnung[$Zeile]['gast_team_id'] = $Mannschaften[$data[$Titelzeile['Gast']]]['team_id'];
if (isset($data[$Titelzeile['Spiel_Nr']])) $Begegnung[$Zeile]['spiel_nr'] = $data[$Titelzeile['Spiel_Nr']];
if (isset($data[$Titelzeile['Spieltag_Titel']])) $Begegnung[$Zeile]['spieltag_titel'] = $data[$Titelzeile['Spieltag_Titel']];
} else {
$Begegnung[$Zeile]['heim_team_id'] = $Mannschaften[utf8_encode($data[$Titelzeile['Heim']])]['team_id'];
$Begegnung[$Zeile]['gast_team_id'] = $Mannschaften[utf8_encode($data[$Titelzeile['Gast']])]['team_id'];
if (isset($data[$Titelzeile['Spieltag_Titel']])) $Begegnung[$Zeile]['spieltag_titel'] = utf8_encode($data[$Titelzeile['Spieltag_Titel']]);
}
if (isset($data[$Titelzeile['Spiel_Nr']])) $Begegnung[$Zeile]['spiel_nr'] = $data[$Titelzeile['Spiel_Nr']];
echo "<tr style='color: white;'>";
if ($Begegnung[$Zeile]['spieltag'] > 99 or $Begegnung[$Zeile]['spieltag'] < 1) {
$bgcolor = "red";
@@ -9563,7 +9595,6 @@ function adminBegegnungenImportieren(): void
$Mannschaften[$data[$Titelzeile['Heim']]]['heimspiel_uhrzeit']);
}
$Begegnung[$Zeile]['zeitpunkt'] = $data[$Titelzeile['Spielstart']];
if (!validateDate($Begegnung[$Zeile]['zeitpunkt'])) {
$bgcolor = "red";
$import = false;
@@ -9583,7 +9614,12 @@ function adminBegegnungenImportieren(): void
} else {
$bgcolor = "green";
}
echo "<td style='text-align: center; background-color:" . $bgcolor . "'>" . $data[$Titelzeile['Heim']] . "</td>";
echo "<td style='text-align: center; background-color:" . $bgcolor . "'>";
if ($encoding == "UTF-8")
echo $data[$Titelzeile['Heim']];
else
echo utf8_encode($data[$Titelzeile['Heim']]);
echo "</td>";
if ($Begegnung[$Zeile]['gast_team_id'] == "") {
if ($data[$Titelzeile['Gast']] == "spielfrei") {
$bgcolor = "orange";
@@ -9595,7 +9631,12 @@ function adminBegegnungenImportieren(): void
} else {
$bgcolor = "green";
}
echo "<td style='text-align: center; background-color:" . $bgcolor . "'>" . $data[$Titelzeile['Gast']] . "</td>";
echo "<td style='text-align: center; background-color:" . $bgcolor . "'>";
if ($encoding == "UTF-8")
echo $data[$Titelzeile['Gast']];
else
echo utf8_encode($data[$Titelzeile['Gast']]);
echo "</td>";
echo "</tr>";
}
if (!$import_zeile) {
@@ -9603,6 +9644,7 @@ function adminBegegnungenImportieren(): void
}
$Zeile++;
}
echo "<tr><td colspan=4 style='text-align: center;'>Dateiformat: $encoding</td></tr>";
echo "</table>";
fclose($handle);
@@ -5319,6 +5319,29 @@ function updateDatabase(): void
}
if ($datenbank_version < 108) {
$query = "DELETE t1 FROM #__sportsmanager_unbestaetigtes_ergebnis t1"
. "\n INNER JOIN #__sportsmanager_unbestaetigtes_ergebnis t2"
. "\n ON t1.begegnung_id = t2.begegnung_id"
. "\n AND t1.unbestaetigtes_ergebnis_id < t2.unbestaetigtes_ergebnis_id;";
$db->setQuery( $query );
if (!$db->execute()) { die($db->stderr(true)); }
$query = " ALTER TABLE `#__sportsmanager_unbestaetigtes_ergebnis`"
. "\n DROP INDEX `begegnung_id`, ADD UNIQUE `begegnung_id` (`begegnung_id`) USING BTREE;";
$db->setQuery( $query );
if (!$db->execute()) { die($db->stderr(true)); }
$query = "UPDATE #__sportsmanager_einstellungen"
. "\n SET wert = '108'"
. "\n WHERE name = 'datenbank_version'";
$db->setQuery($query);
if (!$db->execute()) {
die($db->stderr(true));
}
}
if ($datenbank_version < 109) {
$query = "ALTER TABLE #__sportsmanager_turnier ADD COLUMN `reminder_count` TINYINT DEFAULT '0'";
$db->setQuery($query);
if (!$db->execute()) { die($db->stderr(true)); }
@@ -5334,7 +5357,7 @@ function updateDatabase(): void
if (!$db->execute()) { die($db->stderr(true)); }
$query = "UPDATE #__sportsmanager_einstellungen"
. "\n SET wert = '108'"
. "\n SET wert = '109'"
. "\n WHERE name = 'datenbank_version'";
$db->setQuery($query);
if (!$db->execute()) {
@@ -444,7 +444,14 @@ static function turniere($turniere): void
if (!empty($turnier->disziplinen)) {
?>
<br/>
<small><?php echo $turnier->disziplinen; ?></small>
<small>
<?php
$parts = preg_split('/,(?![^()]*\))/m', $turnier->disziplinen);
$parts = array_map('trim', $parts); // remove extra spaces
foreach ($parts as $discipline) {
echo $discipline . "<br>";
} ?>
</small>
<?php
}
?>
@@ -1731,8 +1738,8 @@ static function tabelleAnzeigen($veranstaltung, $modus, $teams, $spieltag, $spie
<table style='width: 100%; border-collapse: collapse;'
class="uk-table-hover uk-table-divider uk-table-middle dtfl-table-medium contentpaneopen<?php echo $params->get('pageclass_sfx'); ?>">
<tr class="sectiontableheader<?php echo $params->get('pageclass_sfx'); ?>">
<th><strong><?php echo Text::_('COM_SPORTSMANAGER_PLACE'); ?></strong></th>
<th style="text-align: left; width: 280px;">
<th style="text-align: center; width: 80px;"><strong><?php echo Text::_('COM_SPORTSMANAGER_PLACE'); ?></strong></th>
<th style="text-align: left; width: 320px;">
<strong><?php echo Text::_('COM_SPORTSMANAGER_TEAM'); ?></strong></th>
<?php
if ($bilder_anzeigen) {
@@ -1998,21 +2005,22 @@ static function tabelleAnzeigen($veranstaltung, $modus, $teams, $spieltag, $spie
?>
<!-- Gruppentabelle Hauptrunde -->
<div class="uk-overflow-auto">
<table
class="uk-table uk-table-hover uk-table-divider uk-table-middle dtfl-table-small contentpaneopen<?php echo $params->get('pageclass_sfx'); ?>">
<table style='width: 450px; border-collapse: collapse;'
class="uk-table-hover uk-table-divider uk-table-middle dtfl-table-small contentpaneopen<?php echo $params->get('pageclass_sfx'); ?>">
<tr class="sectiontableheader<?php echo $params->get('pageclass_sfx'); ?>">
<th><strong><?php echo Text::_('COM_SPORTSMANAGER_PLACE'); ?></strong></th>
<th style="text-align: left">
<th style="text-align: center; width: 80px;"><strong><?php echo Text::_('COM_SPORTSMANAGER_PLACE'); ?></strong></th>
<th style="text-align: left; width: 320px;">
<strong><?php echo Text::_('COM_SPORTSMANAGER_TEAM'); ?></strong></th>
<?php if ($bilder_anzeigen) { ?>
<th style="text-align: center; width: 70px;"></th>
<?php } ?>
</tr>
<?php
$laufende_veranstaltung = $teams[count($teams) - 1]->platz == null;
$platz = -1;
$k = 0;
foreach ($teams
as $team) {
foreach ($teams as $team) {
if ($laufende_veranstaltung && $team->platz != $platz && $team->platz == null) {
?>
<tr>
@@ -2040,10 +2048,6 @@ static function tabelleAnzeigen($veranstaltung, $modus, $teams, $spieltag, $spie
?>
</td>
<td nowrap>
<table style="width: 100%; border: none; border-spacing: 0; padding: 0">
<tr>
<td>
<?php
echo "<a href=\"" . SportsManagerURL('&task=team_details&id=' . $team->team_id) . "\">" . htmlentities_utf8(NichtLeererString($team->teamname)) . "</a>";
?>
@@ -2051,7 +2055,7 @@ static function tabelleAnzeigen($veranstaltung, $modus, $teams, $spieltag, $spie
<?php
if ($bilder_anzeigen) {
?>
<td style="width: 50px" height="50" style="text-align: right">
<td style="text-align: center;">
<?php
$bild = bildHTML("mannschaften", $team->team_id, 50, 50, 0, 0, 'border="0"');
if ($bild != null) {
@@ -2067,34 +2071,7 @@ static function tabelleAnzeigen($veranstaltung, $modus, $teams, $spieltag, $spie
}
?>
</tr>
</table>
</td>
<?php
/*
<td nowrap style="text-align: center">
<?php
echo Rundenbezeichnung($team->letzter_spieltag);
?>
</td>
<td nowrap style="text-align: center">
<?php
echo $team->letzter_spieltag;
?>
</td>
<td nowrap style="text-align: center">
<?php
echo $team->zuletzt_gewonnen;
?>
</td>
<td nowrap style="text-align: center">
<?php
echo $spieltag_verlorene_begegnungen . " | " . $spieltag_einmal_vollstaendig . " = ". $spieltag_mannschaften;
?>
</td>
</tr>
<?php
*/
}
?>
</table>
@@ -374,7 +374,16 @@ class HTML_sportsmanager_admin
echo htmlentities_utf8($row->turnierbezeichnung);
if (!empty($row->disziplinen)) {
?>
<br/><small><?php echo $row->disziplinen; ?></small>
<br/>
<small>
<?php
$parts = preg_split('/,(?![^()]*\))/m', $row->disziplinen);
$parts = array_map('trim', $parts); // remove extra spaces
foreach ($parts as $discipline) {
echo $discipline . "<br>";
}
?>
</small>
<?php
}
?>
+1 -1
View File
@@ -1014,7 +1014,7 @@ return new class () implements InstallerScriptInterface
. "\n `kommentar` varchar(255) DEFAULT NULL,"
. "\n `vorgeschlagen` datetime DEFAULT NULL,"
. "\n PRIMARY KEY (`unbestaetigtes_ergebnis_id`),"
. "\n KEY `begegnung_id` (`begegnung_id`),"
. "\n UNIQUE KEY `begegnung_id` (`begegnung_id`),"
. "\n KEY `vorschlagendes_team_id` (`vorschlagendes_team_id`)"
. "\n) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;";
$db->setQuery( $query );