1. config.php
<?php
// Passwort für Adminbereich
define('ADMIN_PASSWORD', 'DEIN_PASSWORT_HIER');
// Matchoptionen
define('WINNING_SETS', 2);       // 2 Gewinnsätze
define('MATCH_TIEBREAK', false); // Optional Match-Tiebreak aktivieren
2. db.php
<?php
$dbFile = __DIR__ . '/turnier.sqlite';
$initDB = !file_exists($dbFile);
try {
$db = new PDO("sqlite:$dbFile");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($initDB) {
$db->exec("
CREATE TABLE IF NOT EXISTS tournament (
id INTEGER PRIMARY KEY,
name TEXT,
start_date TEXT,
end_date TEXT,
final_date TEXT,
type TEXT
);
CREATE TABLE IF NOT EXISTS players (
id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE IF NOT EXISTS matches (
id INTEGER PRIMARY KEY,
round INTEGER,
player1_id INTEGER,
player2_id INTEGER,
score1 INTEGER,
score2 INTEGER,
winner_id INTEGER
);
");
}
} catch (PDOException $e) {
die("DB Fehler: " . $e->getMessage());
}
3. functions.php
<?php
require_once 'db.php';
require_once 'config.php';
function isAdmin() {
return isset($_GET['admin']) && $_GET['admin'] === ADMIN_PASSWORD;
}
function fetchPlayers() {
global $db;
return $db->query("SELECT * FROM players ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
}
function fetchMatches() {
global $db;
return $db->query("SELECT * FROM matches ORDER BY round, id")->fetchAll(PDO::FETCH_ASSOC);
}
function nextPowerOfTwo($n) {
$p = 1;
while ($p < $n) $p *= 2;
return $p;
}
function getWinner($score1, $score2) {
if ($score1 > $score2) return 1;
if ($score2 > $score1) return 2;
return 0;
}
function getPlayerName($id) {
global $db;
if(!$id) return '—';
return $db->query("SELECT name FROM players WHERE id=$id")->fetchColumn();
}
// Funktion für grafischen Turnierbaum
function buildTreeByRounds($matches) {
$tree = [];
foreach($matches as $m){
$tree[$m['round']][] = $m;
}
return $tree;
}
4. style.css
body { font-family: Arial, sans-serif; margin:20px; }
h1,h2,h3 { margin-bottom:10px; }
.admin { background:#f9f9f9; padding:10px; border:1px solid #ccc; margin-bottom:20px; }
input { width:50px; }
table { border-collapse: collapse; }
td, th { border:1px solid #999; padding:5px 10px; text-align:center; }
/* Turnierbaum */
.bracket { display:flex; gap:40px; margin-top:20px; }
.round { display:flex; flex-direction:column; gap:20px; }
.match { border:1px solid #333; padding:5px 10px; min-width:150px; text-align:center; position:relative; background:#f0f0f0; }
.winner { font-weight:bold; color:green; }
/* Verbindungslinien */
.match::after {
content:"";
position:absolute;
right:-20px;
top:50%;
width:20px;
height:2px;
background:#333;
}
.round:last-child .match::after { display:none; } /* Finale hat keine Linie */
5. index.php (Zuschaueransicht mit Linien)
<?php
require_once 'functions.php';
$tournament = $db->query("SELECT * FROM tournament LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$matches = fetchMatches();
$tree = buildTreeByRounds($matches);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tennis KO-Turnier</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1><?=htmlspecialchars($tournament['name'] ?? 'Kein Turnier')?> (<?=htmlspecialchars($tournament['type'] ?? '')?>)</h1>
<?php if (!$tournament): ?>
<p>Kein Turnier erstellt.</p>
<?php else: ?>
<p>Von <?=$tournament['start_date']?> bis <?=$tournament['end_date']?>, Finaltag: <?=$tournament['final_date']?></p>
<div class="bracket">
<?php foreach($tree as $roundNumber => $matchesRound): ?>
<div class="round">
<h3>Runde <?=$roundNumber?></h3>
<?php foreach($matchesRound as $m):
$p1 = getPlayerName($m['player1_id']);
$p2 = getPlayerName($m['player2_id']);
$winner = $m['winner_id'] ? getPlayerName($m['winner_id']) : '';
?>
<div class="match <?= $m['winner_id'] ? 'winner' : '' ?>">
<div><?=$p1?></div>
<div>vs</div>
<div><?=$p2?></div>
<?php if($winner): ?>
<div class="winner">Sieger: <?=$winner?></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
</body>
</html>
6. admin.php
<?php
require_once 'functions.php';
if(!isAdmin()) die("Kein Zugriff. Admin-Passwort nicht korrekt.");
// Ergebnisse eintragen
if(isset($_POST['match_id'])){
$matchId = intval($_POST['match_id']);
$score1 = intval($_POST['score1']);
$score2 = intval($_POST['score2']);
$match = $db->query("SELECT * FROM matches WHERE id=$matchId")->fetch(PDO::FETCH_ASSOC);
$winner = getWinner($score1,$score2);
$winnerId = $winner==1 ? $match['player1_id'] : ($winner==2 ? $match['player2_id'] : null);
$stmt = $db->prepare("UPDATE matches SET score1=?, score2=?, winner_id=? WHERE id=?");
$stmt->execute([$score1,$score2,$winnerId,$matchId]);
// Nächsten Gegner automatisch eintragen
if($winnerId){
$nextRound = $match['round']+1;
$nextMatch = $db->query("SELECT * FROM matches WHERE round=$nextRound AND (player1_id IS NULL OR player2_id IS NULL) LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if($nextMatch){
if(is_null($nextMatch['player1_id'])) $db->prepare("UPDATE matches SET player1_id=? WHERE id=?")->execute([$winnerId,$nextMatch['id']]);
else $db->prepare("UPDATE matches SET player2_id=? WHERE id=?")->execute([$winnerId,$nextMatch['id']]);
}
}
header("Location: admin.php?admin=".ADMIN_PASSWORD); exit;
}
// Neues Turnier erstellen
if(isset($_POST['action']) && $_POST['action']=='new_tournament'){
$db->exec("DELETE FROM tournament");
$db->exec("DELETE FROM players");
$db->exec("DELETE FROM matches");
$stmt = $db->prepare("INSERT INTO tournament (name,start_date,end_date,final_date,type) VALUES (?,?,?,?,?)");
$stmt->execute([$_POST['name'],$_POST['start_date'],$_POST['end_date'],$_POST['final_date'],$_POST['type']]);
$teams = array_filter(array_map('trim', explode("\n", $_POST['players'])));
foreach($teams as $t) $db->prepare("INSERT INTO players (name) VALUES (?)")->execute([$t]);
$playerIds = $db->query("SELECT id FROM players ORDER BY id")->fetchAll(PDO::FETCH_COLUMN);
$slots = nextPowerOfTwo(count($playerIds));
for($i=0;$i<$slots/2;$i++){
$
Analyse angehalten
Ich kann hier keinen Python-Run ausführen (das war ein interner Werkzeugaufruf, der nicht nötig ist) – ich mache dir stattdessen sauber die fehlende komplette admin.php fertig, damit das Projekt wirklich lauffähig ist.
✅ admin.php (FERTIGE VOLLSTÄNDIGE VERSION)
<?php
require_once 'functions.php';
if (!isAdmin()) {
die("Kein Zugriff. Admin-Passwort nicht korrekt.");
}
/* =========================
ERGEBNIS EINTRAGEN
========================= */
if (isset($_POST['match_id'])) {
$matchId = intval($_POST['match_id']);
$score1 = intval($_POST['score1']);
$score2 = intval($_POST['score2']);
$match = $db->query("SELECT * FROM matches WHERE id=$matchId")->fetch(PDO::FETCH_ASSOC);
$winner = getWinner($score1, $score2);
$winnerId = null;
if ($winner == 1) $winnerId = $match['player1_id'];
if ($winner == 2) $winnerId = $match['player2_id'];
$stmt = $db->prepare("
UPDATE matches
SET score1=?, score2=?, winner_id=?
WHERE id=?
");
$stmt->execute([$score1, $score2, $winnerId, $matchId]);
/* =========================
WEITERGABE INS NÄCHSTE MATCH
========================= */
if ($winnerId) {
$nextRound = $match['round'] + 1;
$nextMatch = $db->query("
SELECT * FROM matches
WHERE round=$nextRound
AND (player1_id IS NULL OR player2_id IS NULL)
ORDER BY id ASC
LIMIT 1
")->fetch(PDO::FETCH_ASSOC);
if ($nextMatch) {
if (is_null($nextMatch['player1_id'])) {
$db->prepare("UPDATE matches SET player1_id=? WHERE id=?")
->execute([$winnerId, $nextMatch['id']]);
} else {
$db->prepare("UPDATE matches SET player2_id=? WHERE id=?")
->execute([$winnerId, $nextMatch['id']]);
}
}
}
header("Location: admin.php?admin=" . ADMIN_PASSWORD);
exit;
}
/* =========================
NEUES TURNIER ERSTELLEN
========================= */
if (isset($_POST['action']) && $_POST['action'] === 'new_tournament') {
$db->exec("DELETE FROM tournament");
$db->exec("DELETE FROM players");
$db->exec("DELETE FROM matches");
$stmt = $db->prepare("
INSERT INTO tournament (name, start_date, end_date, final_date, type)
VALUES (?, ?, ?, ?, ?)
");
$stmt->execute([
$_POST['name'],
$_POST['start_date'],
$_POST['end_date'],
$_POST['final_date'],
$_POST['type']
]);
/* =========================
TEAMS / SPIELER EINLESEN
(DOPPEL VARIANTE A: "A / B")
========================= */
$teams = array_filter(array_map('trim', explode("\n", $_POST['players'])));
foreach ($teams as $team) {
$db->prepare("INSERT INTO players (name) VALUES (?)")
->execute([$team]);
}
$playerIds = $db->query("SELECT id FROM players ORDER BY id")
->fetchAll(PDO::FETCH_COLUMN);
$slots = nextPowerOfTwo(count($playerIds));
/* =========================
MATCHES ERSTELLEN (RUNDE 1)
========================= */
for ($i = 0; $i < $slots / 2; $i++) {
$p1 = $playerIds[$i] ?? null;
$p2 = $playerIds[$i + ($slots / 2)] ?? null;
$db->prepare("
INSERT INTO matches (round, player1_id, player2_id)
VALUES (1, ?, ?)
")->execute([$p1, $p2]);
}
header("Location: admin.php?admin=" . ADMIN_PASSWORD);
exit;
}
/* =========================
DATEN LADEN
========================= */
$matches = fetchMatches();
$tournament = $db->query("SELECT * FROM tournament LIMIT 1")
->fetch(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Admin Tennis Turnier</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Adminbereich Tennis KO-Turnier</h1>
<?php if (!$tournament): ?>
<h2>Neues Turnier erstellen</h2>
<form method="post">
<input type="hidden" name="action" value="new_tournament">
<p>Turniername:<br>
<input type="text" name="name" required></p>
<p>Startdatum:<br>
<input type="date" name="start_date" required></p>
<p>Enddatum:<br>
<input type="date" name="end_date" required></p>
<p>Finaltag:<br>
<input type="date" name="final_date" required></p>
<p>Typ:<br>
<select name="type">
<option>Einzel</option>
<option>Doppel</option>
</select></p>
<p>Teams (Doppel: Spieler1 / Spieler2, eine Zeile pro Team):</p>
<textarea name="players" rows="10" cols="40"></textarea>
<br><br>
<button type="submit">Turnier erstellen</button>
</form>
<?php else: ?>
<h2>Ergebnisse eintragen</h2>
<?php foreach ($matches as $m): ?>
<?php
$p1 = getPlayerName($m['player1_id']);
$p2 = getPlayerName($m['player2_id']);
?>
<form method="post">
<?=htmlspecialchars($p1)?> vs <?=htmlspecialchars($p2)?>
<input type="hidden" name="match_id" value="<?=$m['id']?>">
<input type="number" name="score1" min="0" max="3" required>
<input type="number" name="score2" min="0" max="3" required>
<button type="submit">Speichern</button>
</form>
<?php endforeach; ?>
<?php endif; ?>
</body>
</html>


Instagram