Compare commits

..

1 Commits

Author SHA1 Message Date
MarvinF 7d47b3ed24 Merge pull request #281 from Deutscher-Tischfussballbund/sportsmanager2-stage
stage to prod
2026-04-14 19:10:16 +02:00
4 changed files with 213 additions and 1102 deletions
@@ -953,14 +953,6 @@ function adminEinstellungen(): void
redirectSportsManagerURL('&task=admin_uebersicht'); redirectSportsManagerURL('&task=admin_uebersicht');
} }
function adminSportshub(): void
{
ini_set('memory_limit', '1024M');
$db = getDatabase(true);
$exporter = new SMExporter($db);
$exporter->run();
}
function adminDatenbank(): void function adminDatenbank(): void
{ {
$db = getDatabase(true); $db = getDatabase(true);
@@ -3482,8 +3474,6 @@ function adminVereine(): void
if (!benutzerZugriff("vereine_aendern")) if (!benutzerZugriff("vereine_aendern"))
keinZugriff(true); keinZugriff(true);
$ansprechpartner = [];
$query = "SELECT COUNT(DISTINCT veranstalter_id) FROM #__sportsmanager_verein WHERE NOT ausgetreten"; $query = "SELECT COUNT(DISTINCT veranstalter_id) FROM #__sportsmanager_verein WHERE NOT ausgetreten";
$organisationAnzeigen = loadResult($db, $query) > 1; $organisationAnzeigen = loadResult($db, $query) > 1;
@@ -3493,21 +3483,7 @@ function adminVereine(): void
. "\n LEFT JOIN #__sportsmanager_veranstalter USING (veranstalter_id)" . "\n LEFT JOIN #__sportsmanager_veranstalter USING (veranstalter_id)"
. "\n ORDER BY IF(ISNULL(#__sportsmanager_veranstalter.veranstalter_id), 1, 0), veranstalterbezeichnung, ausgetreten, vereinsname"; . "\n ORDER BY IF(ISNULL(#__sportsmanager_veranstalter.veranstalter_id), 1, 0), veranstalterbezeichnung, ausgetreten, vereinsname";
$vereine = loadObjectList($db, $query); $vereine = loadObjectList($db, $query);
HTML_sportsmanager_admin::adminVereine($vereine, $organisationAnzeigen);
$query = "SELECT #__sportsmanager_verein.verein_id, email FROM #__sportsmanager_vereinsansprechpartner"
. "\n LEFT join #__sportsmanager_verein ON #__sportsmanager_vereinsansprechpartner.verein_id = #__sportsmanager_verein.verein_id"
. "\n WHERE #__sportsmanager_verein.ausgetreten = 0"
. "\n AND email IS NOT NULL AND email <> '';";
$ergebnisse = loadObjectList($db, $query);
if (!empty($ergebnisse)){
foreach($ergebnisse as $value){
if (empty($ansprechpartner[$value->verein_id]) OR !in_array($value->email, $ansprechpartner[$value->verein_id]))
$ansprechpartner[$value->verein_id][] = $value->email;
}
}
HTML_sportsmanager_admin::adminVereine($vereine, $organisationAnzeigen, $ansprechpartner);
} }
function adminEditVerein(): void function adminEditVerein(): void
@@ -8598,8 +8574,6 @@ function adminMannschaften(): void
if (!benutzerZugriff("mannschaftswettbewerb_aendern") && !benutzerVeranstaltungModerator($veranstaltungId)) if (!benutzerZugriff("mannschaftswettbewerb_aendern") && !benutzerVeranstaltungModerator($veranstaltungId))
keinZugriff(true); keinZugriff(true);
$ansprechpartner = [];
$query = "SELECT * FROM #__sportsmanager_veranstaltung WHERE veranstaltung_id = $veranstaltungId"; $query = "SELECT * FROM #__sportsmanager_veranstaltung WHERE veranstaltung_id = $veranstaltungId";
$rows = loadObjectList($db, $query); $rows = loadObjectList($db, $query);
if (count($rows) < 1) die("Wrong id!"); if (count($rows) < 1) die("Wrong id!");
@@ -8624,36 +8598,7 @@ function adminMannschaften(): void
. "\n WHERE #__sportsmanager_team.veranstaltung_id = $veranstaltungId" . "\n WHERE #__sportsmanager_team.veranstaltung_id = $veranstaltungId"
. "\n ORDER BY teamname"; . "\n ORDER BY teamname";
$rows = loadObjectList($db, $query); $rows = loadObjectList($db, $query);
HTML_sportsmanager_admin::adminMannschaften($veranstaltung, $rows);
//Ansprechpartner Teams
$query = "SELECT #__sportsmanager_team.team_id, email FROM #__sportsmanager_teamansprechpartner"
. "\n LEFT JOIN #__sportsmanager_team ON #__sportsmanager_teamansprechpartner.team_id = #__sportsmanager_team.team_id"
. "\n WHERE #__sportsmanager_team.veranstaltung_id = $veranstaltungId"
. "\n AND email IS NOT NULL AND email <> '';";
$ergebnisse = loadObjectList($db, $query);
if (!empty($ergebnisse)){
foreach($ergebnisse as $value){
if (empty($ansprechpartner[$value->team_id]) OR !in_array($value->email, $ansprechpartner[$value->team_id]))
$ansprechpartner[$value->team_id][] = $value->email;
}
}
//Ansprechpartner Vereine
$query = "SELECT #__sportsmanager_team.team_id, #__sportsmanager_vereinsansprechpartner.email"
. "\n FROM #__sportsmanager_team"
. "\n LEFT JOIN #__sportsmanager_verein ON #__sportsmanager_team.verein_id = #__sportsmanager_verein.verein_id"
. "\n LEFT JOIN #__sportsmanager_vereinsansprechpartner ON #__sportsmanager_verein.verein_id = #__sportsmanager_vereinsansprechpartner.verein_id"
. "\n WHERE #__sportsmanager_team.veranstaltung_id = $veranstaltungId"
. "\n AND #__sportsmanager_vereinsansprechpartner.email IS NOT NULL AND #__sportsmanager_vereinsansprechpartner.email <> '';";
$ergebnisse = loadObjectList($db, $query);
if (!empty($ergebnisse)){
foreach($ergebnisse as $value){
if (empty($ansprechpartner[$value->team_id]) OR !in_array($value->email, $ansprechpartner[$value->team_id]))
$ansprechpartner[$value->team_id][] = $value->email;
}
}
HTML_sportsmanager_admin::adminMannschaften($veranstaltung, $rows, $ansprechpartner);
} }
function adminEditMannschaft(): void function adminEditMannschaft(): void
@@ -14260,7 +14205,7 @@ function adminImportTurnierdisziplinMeldungenSpieleForm(): void
HTML_sportsmanager_admin::adminImportTurnierdisziplinMeldungenSpieleForm($row, $veranstalter); HTML_sportsmanager_admin::adminImportTurnierdisziplinMeldungenSpieleForm($row, $veranstalter);
} }
function adminLoeschenTurnierdisziplinMeldungenSpiele($id): void #[NoReturn] function adminLoeschenTurnierdisziplinMeldungenSpiele($id): void
{ {
$db = getDatabase(); $db = getDatabase();
global $_FILES; global $_FILES;
@@ -43,7 +43,6 @@ require_once JPATH_SITE . '/components/com_sportsmanager/views/sportsmanager/vie
require_once JPATH_SITE . '/components/com_sportsmanager/views/sportsmanager/view_ticker.php'; require_once JPATH_SITE . '/components/com_sportsmanager/views/sportsmanager/view_ticker.php';
require_once JPATH_SITE . '/components/com_sportsmanager/util/image.php'; require_once JPATH_SITE . '/components/com_sportsmanager/util/image.php';
require_once JPATH_SITE . '/components/com_sportsmanager/util/email.php'; require_once JPATH_SITE . '/components/com_sportsmanager/util/email.php';
require_once JPATH_SITE . '/components/com_sportsmanager/util/export.php';
require_once JPATH_SITE . '/components/com_sportsmanager/database/update.php'; // will also include init.php and util.php require_once JPATH_SITE . '/components/com_sportsmanager/database/update.php'; // will also include init.php and util.php
initDatabase(); initDatabase();
@@ -84,9 +83,6 @@ if ($task == "spielerbild") {
case 'admin_einstellungen_save': case 'admin_einstellungen_save':
adminSaveEinstellungen(); adminSaveEinstellungen();
break; break;
case 'admin_sportshub':
adminSportshub();
break;
case 'admin_datenbank': case 'admin_datenbank':
adminDatenbank(); adminDatenbank();
break; break;
@@ -1,804 +0,0 @@
<?php
/**
* Joomla/PHP export to importFormat.json structure.
*
* Assumptions:
* - Joomla table prefix is used via #__.
* - Source timezone is Europe/Berlin; output is UTC ISO-8601 "Z".
* - For turnier:
* - rundenstufe = 10 => Vorrunde
* - rundenstufe = 1,2,3 => Hauptrunde with groups:
* 1 => Profifeld, 2 => Amateurfeld, 3 => Hobbyfeld
* - For team-based exports:
* - stage/group are synthesized as defaults.
*
* Place this in a Joomla context (CLI script, controller, or a small admin entry point).
*/
defined('_JEXEC') or die;
use Joomla\Database\DatabaseDriver;
final class SMExporter
{
private DatabaseDriver $db;
private DateTimeZone $sourceTz;
private DateTimeZone $outputTz;
// Optional filter; set to null for all seasons
private $exportSeasonId = null;
// Optional file output; set to null to echo JSON only
private string $outputFile = JPATH_ROOT . '/tsm.json';
private array $playerCache = [];
private array $meldungsPlayersCache = [];
private array $teamCache = [];
private array $disciplineShortNames = ['Offenes Doppel' => 'OD',
'Offenes Einzel' => 'OE',
'Damen Doppel' => 'DD',
'Damen Einzel' => 'DE',
'Herren Doppel' => 'HD',
'Herren Einzel' => 'HE',
'Junioren Doppel' => 'JD',
'Junioren Einzel' => 'JE',
'Senioren Doppel' => 'SD',
'Senioren Einzel' => 'SE',];
public function __construct(DatabaseDriver $db)
{
$this->db = $db;
$this->sourceTz = new DateTimeZone('Europe/Berlin');
$this->outputTz = new DateTimeZone('UTC');
}
/**
* Format a DB date/datetime into UTC ISO-8601.
*/
function isoUtc(?string $value, DateTimeZone $sourceTz, DateTimeZone $outputTz): ?string
{
if (!$value || $value === '0000-00-00' || $value === '0000-00-00 00:00:00') {
return null;
}
try {
$dt = new DateTimeImmutable($value, $sourceTz);
return $dt->setTimezone($outputTz)->format('Y-m-d\TH:i:s\Z');
} catch (Throwable $e) {
return null;
}
}
/**
* Build shortName from kuerzel or disziplin text.
*/
function disciplineShortName(?string $kuerzel, ?string $disziplin): string
{
$kuerzel = trim((string)$kuerzel);
if ($kuerzel !== '') {
return $kuerzel;
}
$disziplin = (string)$disziplin;
foreach ($this->disciplineShortNames as $needle => $short) {
if (mb_stripos($disziplin, $needle) !== false) {
return $short;
}
}
// Last-resort fallback: initials of the words
$words = preg_split('/\s+/', trim($disziplin));
$initials = '';
foreach ($words as $w) {
if ($w !== '') {
$initials .= mb_substr($w, 0, 1);
}
}
return $initials !== '' ? mb_strtoupper($initials) : 'X';
}
/**
* Build a person object from spieler_id or from turniermeldung_spieler_name.
*/
function getPersonForSpieler(
Joomla\Database\DatabaseInterface $db,
?int $spielerId,
?int $turniermeldungSpielerId,
array &$playerCache
): array
{
if ($spielerId && isset($playerCache[$spielerId])) {
return $playerCache[$spielerId];
}
if ($spielerId) {
$query = $db->getQuery(true)
->select(['spieler_id', 'vorname', 'nachname', 'spielernr'])
->from($db->quoteName('#__sportsmanager_spieler'))
->where($db->quoteName('spieler_id') . ' = ' . (int)$spielerId);
$db->setQuery($query);
$row = $db->loadObject();
$person = [
'name' => $row ? trim(($row->vorname ?? '') . ' ' . ($row->nachname ?? '')) : ('Spieler ' . $spielerId),
'playerNr' => $row && !empty($row->spielernr) ? (string)$row->spielernr : null,
];
$playerCache[$spielerId] = $person;
return $person;
}
if ($turniermeldungSpielerId) {
$query = $db->getQuery(true)
->select(['vorname', 'nachname', 'vereinsname'])
->from($db->quoteName('#__sportsmanager_turniermeldung_spieler_name'))
->where($db->quoteName('turniermeldung_spieler_id') . ' = ' . (int)$turniermeldungSpielerId)
->order('turniermeldung_spieler_name_id ASC');
$db->setQuery($query);
$row = $db->loadObject();
if ($row) {
return [
'name' => trim(($row->vorname ?? '') . ' ' . ($row->nachname ?? '')),
'playerNr' => null,
];
}
}
return [
'name' => 'Unknown',
'playerNr' => null,
];
}
/**
* Get all players assigned to a turniermeldung.
*/
function getMeldungPlayers(
Joomla\Database\DatabaseInterface $db,
int $turniermeldungId,
array &$meldungsPlayersCache,
array &$playerCache
): array
{
if (isset($meldungsPlayersCache[$turniermeldungId])) {
return $meldungsPlayersCache[$turniermeldungId];
}
$query = $db->getQuery(true)
->select(['tms.turniermeldung_spieler_id', 'tms.spieler_id'])
->from($db->quoteName('#__sportsmanager_turniermeldung_spieler', 'tms'))
->where('tms.turniermeldung_id = ' . $turniermeldungId)
->order('tms.turniermeldung_spieler_id ASC');
$db->setQuery($query);
$rows = $db->loadObjectList();
$players = [];
foreach ($rows as $row) {
$players[] = $this->getPersonForSpieler($db, $row->spieler_id ? (int)$row->spieler_id : null, (int)$row->turniermeldung_spieler_id, $playerCache);
}
$meldungsPlayersCache[$turniermeldungId] = $players;
return $players;
}
/**
* Build display name for a side.
*/
function buildSideName(array $players): string
{
if (count($players) === 0) {
return 'Unknown';
}
if (count($players) === 1) {
return $players[0]['name'];
}
$names = [];
foreach ($players as $p) {
$names[] = $p['name'];
}
return implode(' / ', $names);
}
/**
* Parse set scores from a result string.
* Supports patterns like "11:7;11:9", "11-7 11-9", etc.
*/
function parseSets(array $detail): array
{
$sets = [];
$n = 1;
foreach ($detail as $set) {
$set = trim((string)$set);
if ($set === '') {
continue;
}
preg_match_all('/(\d{1,2})\s*[:\-]\s*(\d{1,2})/', $set, $m, PREG_SET_ORDER);
foreach ($m as $match) {
$sets[] = [
'number' => $n++,
'scoreHome' => (int)$match[1],
'scoreAway' => (int)$match[2],
];
}
}
return $sets;
}
/**
* Determine match state.
*/
function determineMatchState($result, array $detail): string
{
if ($result !== null || ( !empty($detail) && !array_filter($detail, fn($v) => $v === null || trim((string)$v) === ''))) {
return 'PLAYED';
}
return 'SCHEDULED';
}
/**
* Determine match state.
*/
function determineWinner(array $detail, string $sourceType): string
{
if ($sourceType === 'TEAM') {
$sets = $this->parseSets($detail);
$homeSetsWon = 0;
$awaySetsWon = 0;
foreach ($sets as $set) {
if ($set['scoreHome'] > $set['scoreAway']) {
$homeSetsWon++;
} elseif ($set['scoreHome'] < $set['scoreAway']) {
$awaySetsWon++;
}
}
if ($homeSetsWon > $awaySetsWon) {
return 'HOME';
} elseif ($homeSetsWon < $awaySetsWon) {
return 'AWAY';
}
return 'DRAW';
} else {
if (count($detail) >0) {
if ($detail[0] == 1) {
return 'HOME';
} elseif ($detail[0] == 2) {
return 'AWAY';
} else {
return 'DRAW';
}
}
return 'UNKNOWN';
}
}
/**
* Determine group state based on a cutoff date.
*/
function determineFinishedState(?string $cutoffDate): string
{
if (!$cutoffDate || $cutoffDate === '0000-00-00') {
return 'PLANNED';
}
$today = new DateTimeImmutable('today');
$cutoff = new DateTimeImmutable($cutoffDate);
return ($cutoff < $today) ? 'FINISHED' : 'RUNNING';
}
/**
* Build one match object.
*/
function buildMatch(
array $homePlayers,
array $awayPlayers,
?string $startDate,
?string $endDate,
?int $result,
array $detail,
string $sourceType
): array
{
$type = (count($homePlayers) > 1 || count($awayPlayers) > 1) ? 'DOUBLE' : 'SINGLE';
$match = [
'startDate' => $startDate,
'endDate' => $endDate,
'type' => $type,
'state' => $this->determineMatchState($result, $detail),
'players' => [],
'sets' => $sourceType === 'TEAM' ? $this->parseSets($detail) : [],
'winner' => $this->determineWinner($detail, $sourceType),
];
foreach ($homePlayers as $p) {
$match['players'][] = [
'name' => $p['name'],
'playerNr' => $p['playerNr'],
'side' => 'HOME',
];
}
foreach ($awayPlayers as $p) {
$match['players'][] = [
'name' => $p['name'],
'playerNr' => $p['playerNr'],
'side' => 'AWAY',
];
}
// If detail parsing produced no sets, keep the structure valid by leaving it empty.
if ($sourceType === 'TEAM' && empty($match['sets']) && $result !== null) {
$match['sets'] = [];
}
return $match;
}
/**
* group matches. Based on String (e.g. E1E1, D1D1, D1D1, E2E2, D2D2 etc.)
*/
function groupMatches(array $pattern, array $games): array {
$grouped = [];
$order = []; // to preserve first appearance order
foreach ($pattern as $i => $slot) {
if (!array_key_exists($i, $games)) {
continue;
}
if (!isset($grouped[$slot])) {
$grouped[$slot] = [
'type' => $slot,
'sets' => []
];
$order[] = $slot; // remember order of first occurrence
}
$grouped[$slot]['sets'][] = $games[$i];
}
// rebuild ordered result
$result = [];
foreach ($order as $slot) {
$result[] = $grouped[$slot];
}
return $result;
}
function run(): void
{
set_time_limit(0);
$db = $this->db;
$export = [
'meta' => [
// Keep the organization value explicit, or replace it from settings if available.
'organisation' => 'TFVSH',
],
'seasons' => [],
];
// Seasons
$seasonSql = $db->getQuery(true)
->select(['saison_id', 'saisonbezeichnung'])
->from($db->quoteName('#__sportsmanager_saison'))
->order('saisonbezeichnung ASC, saison_id ASC');
if ($this->exportSeasonId !== null) {
$seasonSql->where('saison_id = ' . (int)$this->exportSeasonId);
}
$db->setQuery($seasonSql);
$seasons = $db->loadObjectList();
foreach ($seasons as $season) {
$seasonNode = [
'name' => (string)$season->saisonbezeichnung,
'events' => [],
];
/**
* Event type 1: turniere
*/
$turnierSql = $db->getQuery(true)
->select([
't.turnier_id',
't.turnierbezeichnung',
't.erster_tag',
't.letzter_tag',
])
->from($db->quoteName('#__sportsmanager_turnier', 't'))
->where('t.saison_id = ' . (int)$season->saison_id)
->order('t.erster_tag ASC, t.turnier_id ASC');
$db->setQuery($turnierSql);
$turniere = $db->loadObjectList();
foreach ($turniere as $turnier) {
$eventNode = [
'name' => (string)$turnier->turnierbezeichnung,
'disciplines' => [],
];
$discSql = $db->getQuery(true)
->select([
'd.turnierdisziplin_id',
'd.disziplin',
'd.kuerzel',
'd.beginn',
])
->from($db->quoteName('#__sportsmanager_turnierdisziplin', 'd'))
->where('d.turnier_id = ' . (int)$turnier->turnier_id)
->order('d.reihenfolge ASC, d.turnierdisziplin_id ASC');
$db->setQuery($discSql);
$disciplines = $db->loadObjectList();
foreach ($disciplines as $disc) {
$disciplineNode = [
'name' => (string)$disc->disziplin,
'shortName' => $this->disciplineShortName($disc->kuerzel, $disc->disziplin),
'stages' => [],
];
$spielSql = $db->getQuery(true)
->select([
'ts.turnierspiel_id',
'ts.turnierdisziplin_id',
'ts.spiel_nummer',
'ts.runde',
'ts.rundenstufe',
'ts.heim_meldung_id',
'ts.gast_meldung_id',
'ts.ergebnis',
'ts.ergebnis_detailliert',
'hm.meldungsgruppe_id AS heim_meldungsgruppe_id',
'gm.meldungsgruppe_id AS gast_meldungsgruppe_id',
])
->from($db->quoteName('#__sportsmanager_turnierspiel', 'ts'))
->leftJoin($db->quoteName('#__sportsmanager_turniermeldung', 'hm') . ' ON hm.turniermeldung_id = ts.heim_meldung_id')
->leftJoin($db->quoteName('#__sportsmanager_turniermeldung', 'gm') . ' ON gm.turniermeldung_id = ts.gast_meldung_id')
->where('ts.turnierdisziplin_id = ' . (int)$disc->turnierdisziplin_id)
->order('COALESCE(ts.rundenstufe, 99) ASC, COALESCE(ts.runde, 99) ASC, COALESCE(ts.spiel_nummer, 99) ASC, ts.turnierspiel_id ASC');
$db->setQuery($spielSql);
$spiele = $db->loadObjectList();
$stages = [];
foreach ($spiele as $spiel) {
$rundenstufe = (int)($spiel->rundenstufe ?? 0);
if ($rundenstufe === 10) {
$stageName = 'Vorrunde';
$groupName = 'Vorrunde';
} elseif (in_array($rundenstufe, [1, 2, 3], true)) {
$stageName = 'Hauptrunde';
$groupName = match ($rundenstufe) {
1 => 'Profifeld',
2 => 'Amateurfeld',
3 => 'Hobbyfeld',
};
} else {
$stageName = 'Stage A';
$groupName = 'Group A';
}
$groupKey = $stageName . '|' . $groupName;
if (!isset($stages[$stageName])) {
$stages[$stageName] = [];
}
if (!isset($stages[$stageName][$groupKey])) {
$stages[$stageName][$groupKey] = [
'name' => $groupName,
'rounds' => [],
'_dates' => [],
];
}
$homePlayers = $this->getMeldungPlayers($db, (int)$spiel->heim_meldung_id, $this->meldungsPlayersCache, $this->playerCache);
$awayPlayers = $this->getMeldungPlayers($db, (int)$spiel->gast_meldung_id, $this->meldungsPlayersCache, $this->playerCache);
$homeName = $this->buildSideName($homePlayers);
$awayName = $this->buildSideName($awayPlayers);
$startDate = $this->isoUtc((string)$disc->beginn, $this->sourceTz, $this->outputTz) ?: $this->isoUtc($turnier->erster_tag . ' 00:00:00', $this->sourceTz, $this->outputTz);
$endDate = $this->isoUtc((string)$disc->beginn, $this->sourceTz, $this->outputTz) ?: $this->isoUtc($turnier->letzter_tag . ' 23:59:59', $this->sourceTz, $this->outputTz);
$match = $this->buildMatch(
$homePlayers,
$awayPlayers,
$startDate,
$endDate,
$spiel->ergebnis !== null ? (int)$spiel->ergebnis : null,
[$spiel->ergebnis ?? null],
'TURNIER'
);
$roundIndex = $spiel->runde ?? 1;
$roundKey = (string)$roundIndex;
if (!isset($stages[$stageName][$groupKey]['rounds'][$roundKey])) {
$stages[$stageName][$groupKey]['rounds'][$roundKey] = [
'index' => $roundIndex,
'name' => 'Round ' . $roundIndex,
'matchdays' => [],
];
}
$matchdayName = 'Day ' . (int)($spiel->spiel_nummer ?: $spiel->turnierspiel_id);
$stages[$stageName][$groupKey]['rounds'][$roundKey]['matchdays'][] = [
'name' => $matchdayName,
'startDate' => $startDate,
'endDate' => $endDate,
'teamHome' => ['name' => $homeName],
'teamAway' => ['name' => $awayName],
'matches' => [$match],
];
$stages[$stageName][$groupKey]['_dates'][] = $turnier->letzter_tag ?: $turnier->erster_tag;
}
foreach ($stages as $stageName => $groupBucket) {
$stageNode = [
'name' => $stageName,
'groups' => [],
];
foreach ($groupBucket as $groupKey => $groupData) {
$cutoffDate = null;
if (!empty($groupData['_dates'])) {
$cutoffDate = max($groupData['_dates']);
}
$groupNode = [
'name' => $groupData['name'],
'tournamentMode' => 'unknown',
'state' => $this->determineFinishedState($cutoffDate),
'rounds' => [],
];
ksort($groupData['rounds'], SORT_NATURAL);
foreach ($groupData['rounds'] as $round) {
$groupNode['rounds'][] = $round;
}
$stageNode['groups'][] = $groupNode;
}
$disciplineNode['stages'][] = $stageNode;
}
$eventNode['disciplines'][] = $disciplineNode;
}
$seasonNode['events'][] = $eventNode;
}
/**
* Event type 2: team-based events from veranstaltung via team/begegnung/teamspiel
*/
$veranstaltungSql = $db->getQuery(true)
->select([
'v.veranstaltung_id',
'v.bezeichnung',
'v.erster_tag',
'v.letzter_tag',
'tsm.modus AS modus'
])
->from($db->quoteName('#__sportsmanager_veranstaltung', 'v'))
->innerJoin($db->quoteName('#__sportsmanager_team', 'tm') . ' ON tm.veranstaltung_id = v.veranstaltung_id')
->leftJoin($db->quoteName('#__sportsmanager_teamspiel_modus', 'tsm') . ' ON tsm.teamspiel_modus_id = v.modus_id')
->where('v.saison_id = ' . (int)$season->saison_id)
->group('v.veranstaltung_id, v.bezeichnung, v.erster_tag, v.letzter_tag')
->order('v.erster_tag, v.veranstaltung_id');
$db->setQuery($veranstaltungSql);
$veranstaltungen = $db->loadObjectList();
foreach ($veranstaltungen as $veranstaltung) {
$modus = array_map('trim', explode(',', $veranstaltung->modus));
$eventNode = [
'name' => (string)$veranstaltung->bezeichnung,
'disciplines' => [
[
'name' => 'Teamspiel',
'shortName' => 'TS',
'stages' => [
[
'name' => 'Stage A',
'groups' => [],
],
],
],
],
];
$groupNode = [
'name' => 'Group A',
'tournamentMode' => 'unknown',
'state' => 'PLANNED',
'rounds' => [],
];
$begegnungSql = $db->getQuery(true)
->select([
'b.begegnung_id',
'b.heim_team_id',
'b.gast_team_id',
'b.zeitpunkt',
'b.spieltag',
'b.spieltag_titel',
'b.spiel_nr',
])
->from($db->quoteName('#__sportsmanager_begegnung', 'b'))
->innerJoin($db->quoteName('#__sportsmanager_team', 'th') . ' ON th.team_id = b.heim_team_id')
->innerJoin($db->quoteName('#__sportsmanager_team', 'tg') . ' ON tg.team_id = b.gast_team_id')
->where('th.veranstaltung_id = ' . (int)$veranstaltung->veranstaltung_id)
->order('COALESCE(b.spieltag, 9999) ASC, b.zeitpunkt ASC, b.begegnung_id ASC');
$db->setQuery($begegnungSql);
$begegnungen = $db->loadObjectList();
$groupDates = [];
$roundsByKey = [];
foreach ($begegnungen as $begegnung) {
$homeTeamId = (int)$begegnung->heim_team_id;
$awayTeamId = (int)$begegnung->gast_team_id;
if (!isset($this->teamCache[$homeTeamId])) {
$db->setQuery(
$db->getQuery(true)
->select(['team_id', 'teamname'])
->from($db->quoteName('#__sportsmanager_team'))
->where('team_id = ' . $homeTeamId)
);
$this->teamCache[$homeTeamId] = $db->loadObject();
}
if (!isset($this->teamCache[$awayTeamId])) {
$db->setQuery(
$db->getQuery(true)
->select(['team_id', 'teamname'])
->from($db->quoteName('#__sportsmanager_team'))
->where('team_id = ' . $awayTeamId)
);
$this->teamCache[$awayTeamId] = $db->loadObject();
}
$homeTeam = $this->teamCache[$homeTeamId];
$awayTeam = $this->teamCache[$awayTeamId];
$roundIndex = $begegnung->spieltag ?? 1;
$roundKey = (string)$roundIndex;
if (!isset($roundsByKey[$roundKey])) {
$roundsByKey[$roundKey] = [
'index' => $roundIndex,
'name' => 'Round ' . $roundIndex,
'matchdays' => [],
];
}
$teamspielSql = $db->getQuery(true)
->select([
'ts.teamspiel_id',
'ts.teamspiel_nummer',
'ts.heim_spieler_1_id',
'ts.heim_spieler_2_id',
'ts.gast_spieler_1_id',
'ts.gast_spieler_2_id',
'ts.teamspiel_heim_punkte',
'ts.teamspiel_gast_punkte',
'ts.teamspiel_heim_spielpunkte',
'ts.teamspiel_gast_spielpunkte',
'ts.ergebnis_detailliert',
])
->from($db->quoteName('#__sportsmanager_teamspiel', 'ts'))
->where('ts.begegnung_id = ' . (int)$begegnung->begegnung_id)
->order('ts.teamspiel_nummer ASC, ts.teamspiel_id ASC');
$db->setQuery($teamspielSql);
$teamspiele = $db->loadObjectList();
$matchdayMatches = [];
$teamspiele = $this->groupMatches($modus, $teamspiele);
foreach ($teamspiele as $group) {
if (empty($group['sets'])) {
continue;
}
$ts = $group['sets'][0];
// use modus here
$homePlayers = [];
$awayPlayers = [];
$homePlayers[] = $this->getPersonForSpieler($db, (int)$ts->heim_spieler_1_id, null, $this->playerCache);
if (!empty($ts->heim_spieler_2_id)) {
$homePlayers[] = $this->getPersonForSpieler($db, (int)$ts->heim_spieler_2_id, null, $this->playerCache);
}
$awayPlayers[] = $this->getPersonForSpieler($db, (int)$ts->gast_spieler_1_id, null, $this->playerCache);
if (!empty($ts->gast_spieler_2_id)) {
$awayPlayers[] = $this->getPersonForSpieler($db, (int)$ts->gast_spieler_2_id, null, $this->playerCache);
}
$startDate = $this->isoUtc($begegnung->zeitpunkt, $this->sourceTz, $this->outputTz);
$endDate = $this->isoUtc($begegnung->zeitpunkt, $this->sourceTz, $this->outputTz);
$detail = [];
foreach ($group['sets'] as $set) {
$detail[] = $set->ergebnis_detailliert ?? null;
}
$matchdayMatches[] = $this->buildMatch(
$homePlayers,
$awayPlayers,
$startDate,
$endDate,
($ts->teamspiel_heim_punkte !== null || $ts->teamspiel_gast_punkte !== null) ? 1 : null,
$detail,
'TEAM'
);
}
$matchdayName = trim((string)$begegnung->spieltag_titel) !== ''
? (string)$begegnung->spieltag_titel
: ('Spieltag ' . $roundIndex);
$roundsByKey[$roundKey]['matchdays'][] = [
'name' => $matchdayName,
'startDate' => $this->isoUtc($begegnung->zeitpunkt, $this->sourceTz, $this->outputTz),
'endDate' => $this->isoUtc($begegnung->zeitpunkt, $this->sourceTz, $this->outputTz),
'teamHome' => ['name' => $homeTeam->teamname ?? ('Team ' . $homeTeamId)],
'teamAway' => ['name' => $awayTeam->teamname ?? ('Team ' . $awayTeamId)],
'matches' => $matchdayMatches,
];
$groupDates[] = substr((string)$begegnung->zeitpunkt, 0, 10);
}
if (!empty($groupDates)) {
$groupNode['state'] = $this->determineFinishedState(max($groupDates));
}
ksort($roundsByKey, SORT_NATURAL);
foreach ($roundsByKey as $round) {
$groupNode['rounds'][] = $round;
}
$eventNode['disciplines'][0]['stages'][0]['groups'][] = $groupNode;
$seasonNode['events'][] = $eventNode;
}
$export['seasons'][] = $seasonNode;
}
$json = json_encode($export, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
if ($json === false) {
throw new RuntimeException('JSON encoding failed: ' . json_last_error_msg());
}
if ($this->outputFile) {
file_put_contents($this->outputFile, $json . PHP_EOL);
}
if (PHP_SAPI !== 'cli') {
header('Content-Type: application/json; charset=utf-8');
}
echo 'Successfully created export file: ' . $this->outputFile;
}
}
@@ -145,12 +145,6 @@ class HTML_sportsmanager_admin
</td> </td>
<?php <?php
$Spalte_Nr = self::checkZeilenumbruch($Spalte_Nr, $max_Spalten); $Spalte_Nr = self::checkZeilenumbruch($Spalte_Nr, $max_Spalten);
?>
<td style="padding-right: 15px" nowrap>
<a href="<?php echo SportsManagerURL('&task=admin_sportshub'); ?>"><?php echo 'Sportshub'; ?></a>
</td>
<?php
$Spalte_Nr = self::checkZeilenumbruch($Spalte_Nr, $max_Spalten);
} }
if (benutzerZugriff("termine_aendern")) { if (benutzerZugriff("termine_aendern")) {
?> ?>
@@ -3545,7 +3539,7 @@ class HTML_sportsmanager_admin
<?php <?php
} }
static function adminVereine($rows, $organisationAnzeigen, $ansprechpartner): void static function adminVereine($rows, $organisationAnzeigen): void
{ {
global $params; global $params;
@@ -3605,8 +3599,6 @@ class HTML_sportsmanager_admin
<th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_MEMBERS'); ?></strong></th> <th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_MEMBERS'); ?></strong></th>
<th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_TEAM_SEAT'); ?></strong></th> <th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_TEAM_SEAT'); ?></strong></th>
<th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_BEATEN'); ?></strong></th> <th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_BEATEN'); ?></strong></th>
<th></th>
<th></th>
</tr> </tr>
<?php <?php
@@ -3669,14 +3661,6 @@ class HTML_sportsmanager_admin
</td> </td>
<td nowrap><?php if (!empty($row->vereinssitz)) echo htmlentities_utf8($row->vereinssitz . (!empty($row->vereinssitz_ortsteil) ? ("-" . $row->vereinssitz_ortsteil) : "")); ?></td> <td nowrap><?php if (!empty($row->vereinssitz)) echo htmlentities_utf8($row->vereinssitz . (!empty($row->vereinssitz_ortsteil) ? ("-" . $row->vereinssitz_ortsteil) : "")); ?></td>
<td nowrap><?php echo $row->ausgetreten ? Text::_('COM_SPORTSMANAGER_YES') : Text::_('COM_SPORTSMANAGER_NO'); ?></td> <td nowrap><?php echo $row->ausgetreten ? Text::_('COM_SPORTSMANAGER_YES') : Text::_('COM_SPORTSMANAGER_NO'); ?></td>
<td>
<?PHP
if (!empty($ansprechpartner[$row->verein_id])){
$emails = implode(';', $ansprechpartner[$row->verein_id]);
echo "<a href='mailto:" . $emails . "?subject=" . $row->vereinsname . "'>E-Mail</a>&nbsp;";
}
?>
</td>
<td nowrap><small><a <td nowrap><small><a
href="<?php echo SportsManagerURL('&task=admin_verein_remove&id=' . $row->verein_id); ?>" href="<?php echo SportsManagerURL('&task=admin_verein_remove&id=' . $row->verein_id); ?>"
onclick="return confirm('<?php echo Text::_('COM_SPORTSMANAGER_WANT_REALLY_REMOVE'); ?>');" onclick="return confirm('<?php echo Text::_('COM_SPORTSMANAGER_WANT_REALLY_REMOVE'); ?>');"
@@ -9728,7 +9712,7 @@ static function adminVerbandsorganMitglieder($rows,$verbandsorgan): void
<?php <?php
} }
static function adminMannschaften($veranstaltung, $rows, $ansprechpartner): void static function adminMannschaften($veranstaltung, $rows): void
{ {
global $params; global $params;
@@ -9778,8 +9762,6 @@ static function adminVerbandsorganMitglieder($rows,$verbandsorgan): void
<th nowrap title="<?php echo Text::_('COM_SPORTSMANAGER_NUM_REQUESTED_SHFITS_TOOLTIP'); ?>"> <th nowrap title="<?php echo Text::_('COM_SPORTSMANAGER_NUM_REQUESTED_SHFITS_TOOLTIP'); ?>">
<strong><?php echo Text::_('COM_SPORTSMANAGER_NUM_REQUESTED_SHIFTS'); ?></strong></th> <strong><?php echo Text::_('COM_SPORTSMANAGER_NUM_REQUESTED_SHIFTS'); ?></strong></th>
<th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_HOME_VENUE'); ?></strong></th> <th nowrap><strong><?php echo Text::_('COM_SPORTSMANAGER_HOME_VENUE'); ?></strong></th>
<th></th>
<th></th>
</tr> </tr>
<?php <?php
@@ -9822,14 +9804,6 @@ static function adminVerbandsorganMitglieder($rows,$verbandsorgan): void
</td> </td>
<td nowrap align="center"><?php echo $row->anzahl_verschiebungen; ?></td> <td nowrap align="center"><?php echo $row->anzahl_verschiebungen; ?></td>
<td nowrap><?php if (!empty($row->name)) echo htmlentities_utf8($row->name); ?></td> <td nowrap><?php if (!empty($row->name)) echo htmlentities_utf8($row->name); ?></td>
<td>
<?PHP
if (!empty($ansprechpartner[$row->team_id])){
$emails = implode(';', $ansprechpartner[$row->team_id]);
echo "<a href='mailto:" . $emails . "?subject=" . $row->teamname . "'>E-Mail</a>&nbsp;";
}
?>
</td>
<?php if ($row->begegnungen == 0) { ?> <?php if ($row->begegnungen == 0) { ?>
<td nowrap><small><a <td nowrap><small><a
href="<?php echo SportsManagerURL('&task=admin_team_remove&veranstaltungid=' . $veranstaltung->veranstaltung_id . '&id=' . $row->team_id); ?>" href="<?php echo SportsManagerURL('&task=admin_team_remove&veranstaltungid=' . $veranstaltung->veranstaltung_id . '&id=' . $row->team_id); ?>"