Commit 17472ee0 authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix: tournament creation was silently failing — wrong column names in insert

The store() method used column names that don't exist in the database:
- rounds_count → rounds_total + swiss_rounds
- entry_fee → entry_fee_coins
- prize_pool → prize_pool_coins
- start_date → starts_at
- organization_id → org_id
- swiss_org_id, swiss_event_id → removed (don't exist in table)
- created_by → removed (UUID FK to profiles, admin users aren't in profiles)

Also:
- Time control is now a proper dropdown with all 14 enum values grouped
  by category (bullet/blitz/rapid/classical)
- Format dropdown now uses correct enum values (swiss_to_bracket, team_battle
  instead of invalid group_stage)
- Swiss API tournament creation limited to formats it actually supports
  (swiss, round_robin) — other formats use local bracket/arena engines
- Insert failure now shows error instead of fake success message
- On success, redirects to the new tournament page instead of list
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent b845b5a0
...@@ -195,10 +195,13 @@ class TournamentsController ...@@ -195,10 +195,13 @@ class TournamentsController
$swissEventId = $eventResponse['body']['id'] ?? null; $swissEventId = $eventResponse['body']['id'] ?? null;
} }
if ($swissEventId && $tournamentMode === 'single') { $swissFormats = ['swiss', 'round_robin'];
$format = $_POST['format'] ?? 'swiss';
if ($swissEventId && $tournamentMode === 'single' && in_array($format, $swissFormats)) {
$swissType = $format === 'round_robin' ? 'round_robin' : 'swiss';
$tournamentResponse = SwissApiService::createTournament($swissEventId, [ $tournamentResponse = SwissApiService::createTournament($swissEventId, [
'name' => trim($_POST['name']), 'name' => trim($_POST['name']),
'tournamentType' => $_POST['format'] ?? 'swiss', 'tournamentType' => $swissType,
'roundsNumber' => (int)($_POST['rounds_count'] ?? 5), 'roundsNumber' => (int)($_POST['rounds_count'] ?? 5),
'maxPlayers' => (int)($_POST['max_players'] ?? 200), 'maxPlayers' => (int)($_POST['max_players'] ?? 200),
]); ]);
...@@ -208,33 +211,45 @@ class TournamentsController ...@@ -208,33 +211,45 @@ class TournamentsController
} }
} }
$timeControl = trim($_POST['time_control'] ?? 'rapid_10_0');
$roundsCount = (int)($_POST['rounds_count'] ?? 5);
$data = [ $data = [
'name' => trim($_POST['name']), 'name' => trim($_POST['name']),
'description' => trim($_POST['description'] ?? ''), 'description' => trim($_POST['description'] ?? ''),
'game_key' => $_POST['game_key'], 'game_key' => $_POST['game_key'],
'organization_id' => $orgId ?: null,
'format' => $_POST['format'], 'format' => $_POST['format'],
'tournament_mode' => $tournamentMode, 'tournament_mode' => $tournamentMode,
'rounds_count' => (int)($_POST['rounds_count'] ?? 5), 'rounds_total' => $roundsCount,
'time_control' => trim($_POST['time_control'] ?? ''), 'swiss_rounds' => $roundsCount,
'time_control' => $timeControl,
'max_players' => (int)$_POST['max_players'], 'max_players' => (int)$_POST['max_players'],
'entry_fee' => (int)($_POST['entry_fee'] ?? 0), 'entry_fee_coins' => (int)($_POST['entry_fee'] ?? 0),
'prize_pool' => (int)($_POST['prize_pool'] ?? 0), 'prize_pool_coins' => (int)($_POST['prize_pool'] ?? 0),
'start_date' => $_POST['start_date'], 'starts_at' => $_POST['start_date'] ?: date('c'),
'end_date' => $_POST['end_date'] ?? null,
'banner_url' => trim($_POST['banner_url'] ?? ''),
'status' => 'draft', 'status' => 'draft',
'swiss_org_id' => $swissOrgId,
'swiss_event_id' => $swissEventId,
'swiss_api_tournament_id' => $swissTournamentId,
'created_by' => $_SESSION['user']['username'] ?? 'system',
]; ];
if ($orgId) {
$data['org_id'] = $orgId;
}
if ($swissTournamentId) {
$data['swiss_api_tournament_id'] = $swissTournamentId;
}
if (!empty($_POST['banner_url'])) {
$data['banner_url'] = trim($_POST['banner_url']);
}
$result = $this->db->insert('el3ab_tournaments', $data); $result = $this->db->insert('el3ab_tournaments', $data);
$tournamentId = $result['id'] ?? null; $tournamentId = $result['id'] ?? null;
if (!$tournamentId) {
Response::error('فشل في إنشاء البطولة - تحقق من البيانات المدخلة', '/tournaments/create');
return;
}
// Initialize phases for multi-phase tournaments // Initialize phases for multi-phase tournaments
if ($tournamentMode === 'multi_phase' && !empty($_POST['phases']) && $tournamentId) { if ($tournamentMode === 'multi_phase' && !empty($_POST['phases'])) {
$phaseConfigs = json_decode($_POST['phases'], true) ?? []; $phaseConfigs = json_decode($_POST['phases'], true) ?? [];
if (!empty($phaseConfigs)) { if (!empty($phaseConfigs)) {
$phaseManager = new PhaseManager(); $phaseManager = new PhaseManager();
...@@ -243,7 +258,7 @@ class TournamentsController ...@@ -243,7 +258,7 @@ class TournamentsController
} }
AuditLog::log('create', 'tournament', $data['name'], null, $data); AuditLog::log('create', 'tournament', $data['name'], null, $data);
Response::success('تم إنشاء البطولة بنجاح', '/tournaments'); Response::success('تم إنشاء البطولة بنجاح', "/tournaments/{$tournamentId}");
} }
public function edit(array $params, string $method): void public function edit(array $params, string $method): void
......
...@@ -122,22 +122,47 @@ ...@@ -122,22 +122,47 @@
<option value="round_robin" <?= ($tournament['format'] ?? '') === 'round_robin' ? 'selected' : '' ?>>دوري كامل</option> <option value="round_robin" <?= ($tournament['format'] ?? '') === 'round_robin' ? 'selected' : '' ?>>دوري كامل</option>
<option value="single_elimination" <?= ($tournament['format'] ?? '') === 'single_elimination' ? 'selected' : '' ?>>خروج مباشر</option> <option value="single_elimination" <?= ($tournament['format'] ?? '') === 'single_elimination' ? 'selected' : '' ?>>خروج مباشر</option>
<option value="double_elimination" <?= ($tournament['format'] ?? '') === 'double_elimination' ? 'selected' : '' ?>>خروج مزدوج</option> <option value="double_elimination" <?= ($tournament['format'] ?? '') === 'double_elimination' ? 'selected' : '' ?>>خروج مزدوج</option>
<option value="swiss_to_bracket" <?= ($tournament['format'] ?? '') === 'swiss_to_bracket' ? 'selected' : '' ?>>سويسري + خروج مغلوب</option>
<option value="arena" <?= ($tournament['format'] ?? '') === 'arena' ? 'selected' : '' ?>>أرينا</option> <option value="arena" <?= ($tournament['format'] ?? '') === 'arena' ? 'selected' : '' ?>>أرينا</option>
<option value="group_stage" <?= ($tournament['format'] ?? '') === 'group_stage' ? 'selected' : '' ?>>مجموعات</option> <option value="team_battle" <?= ($tournament['format'] ?? '') === 'team_battle' ? 'selected' : '' ?>>معركة فرق</option>
</select> </select>
<span class="form-error"></span> <span class="form-error"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="form-label">عدد الجولات</label> <label class="form-label">عدد الجولات</label>
<input type="number" name="rounds_count" class="form-input" value="<?= $tournament['rounds_count'] ?? 5 ?>" min="1" max="30"> <input type="number" name="rounds_count" class="form-input" value="<?= $tournament['rounds_total'] ?? $tournament['swiss_rounds'] ?? 5 ?>" min="1" max="30">
</div> </div>
</div> </div>
<div class="grid grid-2 gap-4"> <div class="grid grid-2 gap-4">
<div class="form-group"> <div class="form-group">
<label class="form-label">التحكم بالوقت</label> <label class="form-label">التحكم بالوقت *</label>
<input type="text" name="time_control" class="form-input" value="<?= View::e($tournament['time_control'] ?? '') ?>" placeholder="مثال: 10+5" dir="ltr"> <?php $currentTc = $tournament['time_control'] ?? 'rapid_10_0'; ?>
<select name="time_control" class="form-input" required>
<optgroup label="بوليت">
<option value="bullet_1_0" <?= $currentTc === 'bullet_1_0' ? 'selected' : '' ?>>بوليت 1+0</option>
<option value="bullet_1_1" <?= $currentTc === 'bullet_1_1' ? 'selected' : '' ?>>بوليت 1+1</option>
<option value="bullet_2_1" <?= $currentTc === 'bullet_2_1' ? 'selected' : '' ?>>بوليت 2+1</option>
</optgroup>
<optgroup label="بليتز">
<option value="blitz_3_0" <?= $currentTc === 'blitz_3_0' ? 'selected' : '' ?>>بليتز 3+0</option>
<option value="blitz_3_2" <?= $currentTc === 'blitz_3_2' ? 'selected' : '' ?>>بليتز 3+2</option>
<option value="blitz_5_0" <?= $currentTc === 'blitz_5_0' ? 'selected' : '' ?>>بليتز 5+0</option>
<option value="blitz_5_3" <?= $currentTc === 'blitz_5_3' ? 'selected' : '' ?>>بليتز 5+3</option>
</optgroup>
<optgroup label="رابيد">
<option value="rapid_10_0" <?= $currentTc === 'rapid_10_0' ? 'selected' : '' ?>>رابيد 10+0</option>
<option value="rapid_10_5" <?= $currentTc === 'rapid_10_5' ? 'selected' : '' ?>>رابيد 10+5</option>
<option value="rapid_15_10" <?= $currentTc === 'rapid_15_10' ? 'selected' : '' ?>>رابيد 15+10</option>
<option value="rapid_30_0" <?= $currentTc === 'rapid_30_0' ? 'selected' : '' ?>>رابيد 30+0</option>
</optgroup>
<optgroup label="كلاسيكال">
<option value="classical_60_0" <?= $currentTc === 'classical_60_0' ? 'selected' : '' ?>>كلاسيكال 60+0</option>
<option value="classical_90_30" <?= $currentTc === 'classical_90_30' ? 'selected' : '' ?>>كلاسيكال 90+30</option>
</optgroup>
<option value="custom" <?= $currentTc === 'custom' ? 'selected' : '' ?>>مخصص</option>
</select>
</div> </div>
<div class="form-group"> <div class="form-group">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment