| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/clients/client2/web31/web/slots/includes/ |
Upload File : |
<?php
/**
* Reel Royale · Wettmodul – Ergebnis-Import (modular)
* ---------------------------------------------------------------------------
* Holt Spielergebnisse von einer kostenlosen API (Standard: OpenLigaDB) und
* trägt sie in vorhandene bet_matches ein. Beendete Spiele werden – sofern
* noch offen – per BettingService::setMatchResult() automatisch abgerechnet.
*
* Bewusst defensiv:
* - greift NUR auf bereits angelegte Spiele zu (Quoten bleiben Admin-Sache),
* - Zuordnung der Teams über Namen (+ optionale Alias-Tabelle),
* - idempotent: bereits beendete Spiele werden übersprungen.
*
* OpenLigaDB: https://api.openligadb.de/getmatchdata/{league}/{season}
* (kostenlos, ohne Key). Für die WM ggf. league/season anpassen.
* ---------------------------------------------------------------------------
*/
class BetResultImporter
{
/** @var BettingService */
private $svc;
/** @var PDO */
private $pdo;
/** Alias => kanonischer Teamname (für abweichende API-Schreibweisen). */
private $aliases = [];
public function __construct(BettingService $svc, PDO $pdo)
{
$this->svc = $svc;
$this->pdo = $pdo;
}
public function setAliases(array $map): void
{
foreach ($map as $k => $v) {
$this->aliases[$this->norm($k)] = $this->norm($v);
}
}
private function norm(string $s): string
{
$s = mb_strtolower(trim($s));
$s = str_replace(['ä','ö','ü','ß'], ['a','o','u','ss'], $s);
return preg_replace('/[^a-z0-9]/', '', $s);
}
/** HTTP-GET mit kurzem Timeout; liefert dekodiertes JSON oder null. */
private function fetchJson(string $url): ?array
{
$ctx = stream_context_create(['http' => ['timeout' => 12, 'header' => "Accept: application/json\r\n"]]);
$raw = @file_get_contents($url, false, $ctx);
if ($raw === false) {
if (function_exists('curl_init')) {
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 12, CURLOPT_HTTPHEADER => ['Accept: application/json']]);
$raw = curl_exec($ch);
curl_close($ch);
}
if ($raw === false || $raw === null) {
return null;
}
}
$data = json_decode($raw, true);
return is_array($data) ? $data : null;
}
/**
* Importiert Ergebnisse für ein Turnier (per Slug) aus OpenLigaDB.
* @return array Report
*/
public function importOpenLigaDB(string $tournamentSlug, string $league, string $season, bool $autoSettle = true): array
{
$tid = (int)$this->pdo->query('SELECT id FROM bet_tournaments WHERE slug = ' . $this->pdo->quote($tournamentSlug))->fetchColumn();
if (!$tid) {
return ['ok' => false, 'error' => "Turnier '$tournamentSlug' nicht gefunden."];
}
$url = "https://api.openligadb.de/getmatchdata/" . rawurlencode($league) . "/" . rawurlencode($season);
$data = $this->fetchJson($url);
if ($data === null) {
return ['ok' => false, 'error' => "API nicht erreichbar: $url"];
}
// Teamname (normalisiert) => team_id
$teamIndex = [];
foreach ($this->svc->teams($tid) as $t) {
$teamIndex[$this->norm($t['name'])] = (int)$t['id'];
if (!empty($t['short_name'])) {
$teamIndex[$this->norm($t['short_name'])] = (int)$t['id'];
}
}
$report = ['ok' => true, 'checked' => 0, 'updated' => 0, 'settled' => 0, 'skipped' => 0, 'unmatched' => []];
foreach ($data as $apiMatch) {
$report['checked']++;
if (empty($apiMatch['matchIsFinished'])) {
$report['skipped']++;
continue;
}
$home = $this->resolveTeam($apiMatch['team1']['teamName'] ?? '', $teamIndex);
$away = $this->resolveTeam($apiMatch['team2']['teamName'] ?? '', $teamIndex);
if (!$home || !$away) {
$report['unmatched'][] = ($apiMatch['team1']['teamName'] ?? '?') . ' – ' . ($apiMatch['team2']['teamName'] ?? '?');
continue;
}
// Endergebnis (resultTypeID 2 = Endergebnis), sonst letztes Ergebnis
$score = $this->finalScore($apiMatch);
if ($score === null) {
$report['skipped']++;
continue;
}
// Vorhandenes Spiel suchen (gleiche Paarung, noch nicht beendet)
$st = $this->pdo->prepare(
'SELECT id, status FROM bet_matches
WHERE tournament_id = ? AND home_team_id = ? AND away_team_id = ? LIMIT 1'
);
$st->execute([$tid, $home, $away]);
$match = $st->fetch();
if (!$match) {
$report['unmatched'][] = ($apiMatch['team1']['teamName'] ?? '?') . ' – ' . ($apiMatch['team2']['teamName'] ?? '?') . ' (kein Spiel angelegt)';
continue;
}
// ext_ref pflegen (Idempotenz/Audit)
if (!empty($apiMatch['matchID'])) {
$this->pdo->prepare('UPDATE bet_matches SET ext_ref = ? WHERE id = ? AND (ext_ref IS NULL OR ext_ref = "")')
->execute(['oldb-' . $apiMatch['matchID'], (int)$match['id']]);
}
if ($match['status'] === 'finished') {
$report['skipped']++;
continue;
}
$res = $this->svc->setMatchResult((int)$match['id'], $score[0], $score[1], $autoSettle, null, 'import:openligadb');
$report['updated']++;
$report['settled'] += count($res['settled']);
}
return $report;
}
private function resolveTeam(string $name, array $index): ?int
{
$n = $this->norm($name);
if (isset($this->aliases[$n])) {
$n = $this->aliases[$n];
}
return $index[$n] ?? null;
}
/** @return int[]|null [home, away] */
private function finalScore(array $apiMatch): ?array
{
$results = $apiMatch['matchResults'] ?? [];
$final = null;
foreach ($results as $r) {
if ((int)($r['resultTypeID'] ?? 0) === 2) { $final = $r; break; }
$final = $r; // Fallback: letztes vorhandenes
}
if (!$final || !isset($final['pointsTeam1'], $final['pointsTeam2'])) {
return null;
}
return [(int)$final['pointsTeam1'], (int)$final['pointsTeam2']];
}
}