togethere.cloud/public_html/api/DisciplineSettingsService.php

219 lines
7.5 KiB
PHP

<?php
/**
* DisciplineSettingsService.php
*
* Serwis walidacji, transformacji i biznesowej logiki dla ustawień dyscyplin
* Rozdziela logikę biznesową od modelu i kontrolera
*/
class DisciplineSettingsService
{
private $model;
public function __construct(DisciplineSettingsModel $model)
{
$this->model = $model;
}
/**
* Pobiera ustawienia w formacie API
* Separuje reguły gry od personalizacji
*
* @param string $discipline Nazwa dyscypliny
* @return array Ustawienia z metadanymi
*/
public function getSettingsForAPI($discipline)
{
// Waliduj nazwę dyscypliny
$this->validateDisciplineName($discipline);
$settings = $this->model->getSettings($discipline);
if (!$settings) {
// Jeśli nie istnieją, zwróć defaults
return [
'discipline' => $discipline,
'settingsVersion' => 1,
'rules' => [
'pointsToWin' => DisciplineSettingsModel::getDefaults($discipline)['pointsToWin'],
'setsToWin' => DisciplineSettingsModel::getDefaults($discipline)['setsToWin'],
'serveRotation' => DisciplineSettingsModel::getDefaults($discipline)['serveRotation'],
'specialRules' => DisciplineSettingsModel::getDefaults($discipline)['specialRules'] ?? null
],
'customization' => DisciplineSettingsModel::getDefaults($discipline)['customization'] ?? [],
'status' => 'default'
];
}
return [
'discipline' => $settings['discipline'],
'settingsVersion' => (int)$settings['settingsVersion'],
'rules' => [
'pointsToWin' => (int)$settings['pointsToWin'],
'setsToWin' => (int)$settings['setsToWin'],
'serveRotation' => (int)$settings['serveRotation'],
'specialRules' => $settings['specialRules']
],
'customization' => $settings['customization'] ?? [],
'metadata' => [
'created_at' => $settings['created_at'],
'updated_at' => $settings['updated_at'],
'updated_by' => $settings['updated_by']
],
'status' => 'custom'
];
}
/**
* Waliduje i aktualizuje ustawienia
*
* @param string $discipline Nazwa dyscypliny
* @param array $input Dane wejściowe z API
* @param int $userId ID administratora
* @return array Zaktualizowane ustawienia
* @throws InvalidArgumentException
*/
public function validateAndUpdate($discipline, array $input, $userId)
{
// Waliduj nazwę dyscypliny
$this->validateDisciplineName($discipline);
// Wydziel reguły gry i personalizację
$rules = $input['rules'] ?? [];
$customization = $input['customization'] ?? null;
// Waliduj strukturę
if (empty($rules)) {
throw new InvalidArgumentException('rules field is required');
}
// Przygotuj dane do modelu
$settings = [
'pointsToWin' => $rules['pointsToWin'] ?? 10,
'setsToWin' => $rules['setsToWin'] ?? 2,
'serveRotation' => $rules['serveRotation'] ?? 2,
'specialRules' => $rules['specialRules'] ?? null,
'customization' => $customization
];
// Model zawsze waliduje dane
$updated = $this->model->updateSettings($discipline, $settings, $userId);
return $this->formatSettingsResponse($updated);
}
/**
* Pobiera snapshot do startu meczu
*
* @param string $discipline Nazwa dyscypliny
* @param int|null $version Opcjonalnie: konkretna wersja
* @return array Snapshot
*/
public function getMatchSnapshot($discipline, $version = null)
{
$this->validateDisciplineName($discipline);
try {
$snapshot = $this->model->getSnapshot($discipline, $version);
return [
'success' => true,
'snapshot' => $snapshot
];
} catch (RuntimeException $e) {
throw new RuntimeException('Cannot create snapshot: ' . $e->getMessage());
}
}
/**
* Resetuje ustawienia do defaults
* (przydatne dla testów lub przywrócenia domyślnych)
*
* @param string $discipline Nazwa dyscypliny
* @param int $userId ID administratora
* @return array Ustawienia po resecie
*/
public function resetToDefaults($discipline, $userId)
{
$this->validateDisciplineName($discipline);
$defaults = DisciplineSettingsModel::getDefaults($discipline);
$updated = $this->model->updateSettings($discipline, $defaults, $userId);
return $this->formatSettingsResponse($updated);
}
/**
* Waliduje czy dyscyplina jest obsługiwana
*
* @param string $discipline Nazwa dyscypliny
* @throws InvalidArgumentException
*/
private function validateDisciplineName($discipline)
{
$allowed = ['ping-pong', 'rock-paper-scissors', 'table-football'];
if (!in_array($discipline, $allowed, true)) {
throw new InvalidArgumentException(
"Invalid discipline: $discipline. Allowed: " . implode(', ', $allowed)
);
}
}
/**
* Formatuje odpowiedź z ustawień
*
* @param array $settings Surowe ustawienia z modelu
* @return array Sformatowana odpowiedź
*/
private function formatSettingsResponse($settings)
{
return [
'discipline' => $settings['discipline'],
'settingsVersion' => (int)$settings['settingsVersion'],
'rules' => [
'pointsToWin' => (int)$settings['pointsToWin'],
'setsToWin' => (int)$settings['setsToWin'],
'serveRotation' => (int)$settings['serveRotation'],
'specialRules' => $settings['specialRules']
],
'customization' => $settings['customization'] ?? [],
'metadata' => [
'created_at' => $settings['created_at'],
'updated_at' => $settings['updated_at'],
'updated_by' => $settings['updated_by']
]
];
}
/**
* Porównuje wersje ustawień (do debugowania zmian)
*
* @param array $oldSettings Stare ustawienia
* @param array $newSettings Nowe ustawienia
* @return array Różnice
*/
public function compareVersions($oldSettings, $newSettings)
{
$changes = [];
foreach (['pointsToWin', 'setsToWin', 'serveRotation', 'specialRules'] as $field) {
if (($oldSettings[$field] ?? null) !== ($newSettings[$field] ?? null)) {
$changes[$field] = [
'old' => $oldSettings[$field] ?? null,
'new' => $newSettings[$field] ?? null
];
}
}
if (json_encode($oldSettings['customization'] ?? []) !== json_encode($newSettings['customization'] ?? [])) {
$changes['customization'] = [
'old' => $oldSettings['customization'] ?? [],
'new' => $newSettings['customization'] ?? []
];
}
return $changes;
}
}
?>