8.5 KiB
8.5 KiB
🎯 Wdrażanie Endpoint'u Ustawień Dyscyplin
📋 Szybki Start
Wszystkie pliki zostały już stworzone. Aby wdrożyć system:
1. Pliki do wdrażania
✅ private_html/api/DisciplineSettingsModel.php
✅ private_html/api/DisciplineSettingsService.php
✅ private_html/api/discipline-settings.php
✅ private_html/administration/disciplines/ping-pong/settings/index.php
✅ private_html/administration/disciplines/rock-paper-scissors/settings/index.php
✅ private_html/administration/disciplines/table-football/settings/index.php
✅ private_html/administration/disciplines/ping-pong/index.php (zaktualizowany panel)
✅ private_html/tests/discipline_settings_test.php
2. Baza danych
Tabela settings_disciplines jest automatycznie tworzona na pierwszy GET request.
Jeśli chcesz ją ręcznie stworzyć:
CREATE TABLE IF NOT EXISTS settings_disciplines (
id INT AUTO_INCREMENT PRIMARY KEY,
discipline VARCHAR(50) NOT NULL UNIQUE,
-- Reguły gry (logika)
pointsToWin INT NOT NULL DEFAULT 10,
setsToWin INT NOT NULL DEFAULT 2,
serveRotation INT NOT NULL DEFAULT 2,
specialRules TEXT,
-- Personalizacja UI (nie wpływa na logiką gry)
customization JSON,
-- Versioning ustawień
settingsVersion INT NOT NULL DEFAULT 1,
-- Metadane
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
updated_by INT,
INDEX idx_discipline (discipline),
INDEX idx_version (settingsVersion)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
🧪 Testowanie
Test 1: Uruchom test jednostkowy
cd private_html/tests/
php discipline_settings_test.php
Oczekiwana odpowiedź: 10 testów PASS ✅
Test 2: Pobierz ustawienia (cURL)
# Zaloguj się jako admin
curl -c cookies.txt -X POST \
"http://localhost/login/login.php" \
-d "email=admin@example.com&password=hasło"
# Pobierz ustawienia
curl -b cookies.txt \
"http://localhost/administration/disciplines/ping-pong/settings"
Oczekiwana odpowiedź:
{
"success": true,
"data": {
"discipline": "ping-pong",
"settingsVersion": 1,
"rules": { ... },
"customization": { ... }
}
}
Test 3: Pobierz snapshot (bez admin)
curl "http://localhost/api/discipline-settings.php?discipline=ping-pong&snapshot=true"
Test 4: Panel administracyjny
Otwórz w przeglądarce:
http://localhost/administration/disciplines/ping-pong/
🚀 Użycie w Grze
JavaScript - pobierz ustawienia na start meczu:
async function loadGameSettings() {
const response = await fetch(
'/api/discipline-settings.php?discipline=ping-pong&snapshot=true'
);
const result = await response.json();
if (result.success) {
const snapshot = result.snapshot;
// Uruchom grę z ustawieniami
const game = new PingPongGame({
pointsToWin: snapshot.rules.pointsToWin,
setsToWin: snapshot.rules.setsToWin,
serveRotation: snapshot.rules.serveRotation,
settingsVersion: snapshot.settingsVersion
});
// Stosuj customization
document.body.style.backgroundColor = snapshot.customization.tableColor;
}
}
PHP - zapisz snapshot w meczu:
$model = new DisciplineSettingsModel($pdo);
$snapshot = $model->getSnapshot('ping-pong');
// Zapisz w bazie
$stmt = $pdo->prepare(
"UPDATE matches SET settingsSnapshot = ? WHERE id = ?"
);
$stmt->execute([json_encode($snapshot), $matchId]);
📊 Struktura Odpowiedzi API
GET /administration/disciplines/ping-pong/settings
{
"success": true,
"data": {
"discipline": "ping-pong",
"settingsVersion": 1,
"rules": {
"pointsToWin": 11,
"setsToWin": 3,
"serveRotation": 2,
"specialRules": "Deuce at 10-10..."
},
"customization": {
"tableColor": "#2d5016",
"ballColor": "#ff6600",
"paddleColor": "#000000",
"uiTheme": "dark"
},
"metadata": {
"created_at": "2026-01-28 12:30:45",
"updated_at": "2026-01-28 12:30:45",
"updated_by": 1
},
"status": "custom"
}
}
POST /administration/disciplines/ping-pong/settings
{
"success": true,
"message": "Settings for ping-pong have been updated successfully",
"data": { ... }
}
GET /api/discipline-settings.php?snapshot=true
{
"success": true,
"snapshot": {
"discipline": "ping-pong",
"settingsVersion": 1,
"rules": {
"pointsToWin": 11,
"setsToWin": 3,
"serveRotation": 2,
"specialRules": "..."
},
"snapshotTimestamp": "2026-01-28 12:35:10"
}
}
🔐 Bezpieczeństwo
Panel administracyjny (/administration/disciplines/*/settings)
- ✅ Wymaga zalogowania
- ✅ Wymaga roli
admin - ✅ POST zawsze wymaga admin role
- ✅ GET wymaga admin role
API publiczny (/api/discipline-settings.php)
- ✅ Nie wymaga logowania
- ✅ Tylko GET
- ✅ Brak zmian
- ✅ Ratelimiting (opcjonalnie): można dodać w przyszłości
💡 Najlepsze Praktyki
1. Snapshot dla startu meczu
// ❌ ŹLE - ustawienia mogą się zmienić w trakcie meczu
$settings = $model->getSettings('ping-pong');
// ✅ DOBRZE - snapshot z momentu startu
$snapshot = $model->getSnapshot('ping-pong');
saveMatchSnapshot($matchId, $snapshot);
2. Versioning
// Każda zmiana automatycznie zwiększa wersję
// Wersja 1 → 2 → 3 → ...
$updated = $service->validateAndUpdate('ping-pong', $input, $userId);
echo $updated['settingsVersion']; // 2
3. Walidacja
// ✅ Walidacja zawsze w serwisie
try {
$result = $service->validateAndUpdate('ping-pong', $input, $userId);
} catch (InvalidArgumentException $e) {
// Błędy walidacji
echo "Błąd: " . $e->getMessage();
}
🔧 Integracja z Istniejącymi Systemami
1. Z tabelą matches
Dodaj kolumnę do matches:
ALTER TABLE matches ADD COLUMN settingsSnapshot JSON AFTER Score;
2. Z systemem meczy
// Przy starcie meczu pobierz snapshot
$snapshot = $model->getSnapshot($discipline);
$match = createMatch([
'team1_id' => $team1,
'team2_id' => $team2,
'settingsSnapshot' => json_encode($snapshot)
]);
3. Z systemem auditowania
// Log zmian
$before = $service->getSettingsForAPI('ping-pong');
$service->validateAndUpdate('ping-pong', $input, $adminId);
$after = $service->getSettingsForAPI('ping-pong');
$changes = $service->compareVersions($before, $after);
logAuditEvent('settings_updated', [
'discipline' => 'ping-pong',
'changes' => $changes,
'admin_id' => $adminId
]);
📈 Rozszerzenia w Przyszłości
Historia zmian
CREATE TABLE settings_disciplines_history (
id INT AUTO_INCREMENT PRIMARY KEY,
discipline VARCHAR(50),
version INT,
settings JSON,
changed_by INT,
changed_at DATETIME,
PRIMARY KEY (discipline, version)
);
Scheduled changes
// Zmiana ustawień w określonym czasie
INSERT INTO settings_scheduled_changes (
discipline,
settings_json,
scheduled_at
) VALUES ('ping-pong', '...', '2026-02-01 00:00:00');
A/B testing
// Różne ustawienia dla różnych grup graczy
INSERT INTO settings_ab_tests (
discipline,
variant_a,
variant_b,
split_percentage
) VALUES ('ping-pong', '...', '...', 50);
⚠️ Troubleshooting
Problem: "Table not found"
Rozwiązanie: Tabela tworzy się automatycznie na pierwszy GET. Jeśli nie działa:
$model = new DisciplineSettingsModel($pdo);
$model->ensureTableExists(); // Ręczne wywołanie
Problem: "Invalid JSON"
Rozwiązanie: Sprawdź czy customization jest poprawnym JSON:
json_validate($input['customization']); // PHP 8.3+
// lub
json_last_error() === JSON_ERROR_NONE
Problem: "Validation failed - odd numbers"
Rozwiązanie: pointsToWin i setsToWin muszą być nieparzyste:
- ✅ Poprawne: 11, 21, 3, 5
- ❌ Błędne: 10, 20, 2, 4
📞 Wsparcie
Jeśli masz problemy:
- Sprawdź logi:
error_logw PHP - Uruchom testy:
php discipline_settings_test.php - Sprawdź logowanie: czy jesteś zalogowany jako admin?
- Walidacja: czy dane spełniają wymagania?