first commit
This commit is contained in:
269
api/streamers.php
Normal file
269
api/streamers.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// api/streamers.php
|
||||
//
|
||||
// GET /api/streamers — public list (evaluated only)
|
||||
// GET /api/streamers?all=1 — full list (admin or mod)
|
||||
// POST /api/streamers — suggest a streamer (public)
|
||||
// POST /api/streamers?admin=1 — add streamer (admin only)
|
||||
// PUT /api/streamers?id=N — update streamer + rating (admin or mod)
|
||||
// DELETE /api/streamers?id=N — delete streamer (admin only)
|
||||
// ============================================================
|
||||
|
||||
require_once __DIR__ . '/db.php';
|
||||
|
||||
cors();
|
||||
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// GET — fetch streamers
|
||||
// ------------------------------------------------------------------
|
||||
if ($method === 'GET') {
|
||||
start_session();
|
||||
$is_admin = !empty($_SESSION['is_admin']);
|
||||
$is_mod = is_moderator();
|
||||
|
||||
// Detect if logged-in OAuth user is a member of any rater team
|
||||
$is_team_member = false;
|
||||
if (!$is_admin && !$is_mod && !empty($_SESSION['oauth_user']['id'])) {
|
||||
$stmt = db()->prepare("SELECT 1 FROM rater_group_members WHERE user_id = :uid LIMIT 1");
|
||||
$stmt->execute([':uid' => $_SESSION['oauth_user']['id']]);
|
||||
$is_team_member = (bool)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
// 'all=1' is admin/mod request for unfiltered list (with notes etc.)
|
||||
$all = isset($_GET['all']) && ($is_admin || $is_mod);
|
||||
// Team members must see all streamers (even unevaluated) so they can rate them
|
||||
$see_unevaluated = $all || $is_team_member;
|
||||
|
||||
if ($all) {
|
||||
$sql = "
|
||||
SELECT s.*,
|
||||
r.statistiky, r.grafika, r.alerty, r.vychytavky,
|
||||
r.nahled, r.nastaveni, r.odlisnost, r.reward, r.notes,
|
||||
g.id AS team_id, g.name AS team_name
|
||||
FROM streamers s
|
||||
LEFT JOIN ratings r ON r.streamer_id = s.id
|
||||
LEFT JOIN rater_groups g ON g.streamer_id = s.id
|
||||
ORDER BY s.evaluated DESC, s.name ASC
|
||||
";
|
||||
} elseif ($see_unevaluated) {
|
||||
// Team member: all streamers, but no admin-only fields like notes
|
||||
$sql = "
|
||||
SELECT s.id, s.name, s.platform, s.kick_name, s.status,
|
||||
s.game, s.title, s.evaluated, s.community_locked,
|
||||
r.statistiky, r.grafika, r.alerty, r.vychytavky,
|
||||
r.nahled, r.nastaveni, r.odlisnost, r.reward,
|
||||
g.id AS team_id, g.name AS team_name
|
||||
FROM streamers s
|
||||
LEFT JOIN ratings r ON r.streamer_id = s.id
|
||||
LEFT JOIN rater_groups g ON g.streamer_id = s.id
|
||||
ORDER BY s.evaluated DESC, s.name ASC
|
||||
";
|
||||
} else {
|
||||
$sql = "
|
||||
SELECT s.id, s.name, s.platform, s.kick_name, s.status,
|
||||
s.game, s.title, s.evaluated, s.community_locked,
|
||||
r.statistiky, r.grafika, r.alerty, r.vychytavky,
|
||||
r.nahled, r.nastaveni, r.odlisnost, r.reward,
|
||||
g.id AS team_id, g.name AS team_name
|
||||
FROM streamers s
|
||||
INNER JOIN ratings r ON r.streamer_id = s.id
|
||||
LEFT JOIN rater_groups g ON g.streamer_id = s.id
|
||||
WHERE s.evaluated = true
|
||||
ORDER BY (r.statistiky + r.grafika + r.alerty + r.vychytavky +
|
||||
r.nahled + r.nastaveni + r.odlisnost) DESC
|
||||
";
|
||||
}
|
||||
|
||||
$rows = db()->query($sql)->fetchAll();
|
||||
|
||||
// Reshape: nest ratings under 'r' key to match frontend format
|
||||
$out = array_map(function($row) {
|
||||
$s = [
|
||||
'id' => $row['id'],
|
||||
'name' => $row['name'],
|
||||
'platform' => $row['platform'],
|
||||
'kick' => $row['kick_name'] ?? '',
|
||||
'status' => $row['status'],
|
||||
'game' => $row['game'] ?? '',
|
||||
'title' => $row['title'] ?? '',
|
||||
'evaluated' => (bool)$row['evaluated'],
|
||||
'community_locked' => (bool)($row['community_locked'] ?? false),
|
||||
'added_by' => $row['added_by'] ?? 'admin',
|
||||
'r' => [
|
||||
's' => (int)($row['statistiky'] ?? 0),
|
||||
'g' => (int)($row['grafika'] ?? 0),
|
||||
'a' => (int)($row['alerty'] ?? 0),
|
||||
'v' => (int)($row['vychytavky'] ?? 0),
|
||||
'n' => (int)($row['nahled'] ?? 0),
|
||||
'ns' => (int)($row['nastaveni'] ?? 0),
|
||||
'o' => (int)($row['odlisnost'] ?? 0),
|
||||
],
|
||||
'reward' => (int)($row['reward'] ?? 0),
|
||||
'team_id' => isset($row['team_id']) ? (int)$row['team_id'] : null,
|
||||
'team_name' => $row['team_name'] ?? null,
|
||||
];
|
||||
if (isset($row['notes'])) {
|
||||
$s['notes'] = $row['notes'];
|
||||
}
|
||||
return $s;
|
||||
}, $rows);
|
||||
|
||||
json_out($out);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// POST — add streamer (suggestion from public, or admin add)
|
||||
// ------------------------------------------------------------------
|
||||
if ($method === 'POST') {
|
||||
$body = body();
|
||||
$is_admin_add = isset($_GET['admin']);
|
||||
|
||||
if ($is_admin_add) {
|
||||
session_start();
|
||||
if (empty($_SESSION['is_admin'])) json_error('Unauthorized', 401);
|
||||
}
|
||||
|
||||
$name = sanitize_name($body['name'] ?? '');
|
||||
if (strlen($name) < 2) json_error('Invalid streamer name');
|
||||
|
||||
$platform = in_array($body['platform'] ?? '', ['twitch','kick']) ? $body['platform'] : 'twitch';
|
||||
$kick_name = sanitize_name($body['kick_name'] ?? '');
|
||||
$submitter = substr(trim($body['submitter'] ?? ''), 0, 60);
|
||||
$added_by = $is_admin_add ? 'admin' : 'viewer';
|
||||
|
||||
try {
|
||||
$stmt = db()->prepare("
|
||||
INSERT INTO streamers (name, platform, kick_name, added_by, submitter)
|
||||
VALUES (:name, :platform, :kick_name, :added_by, :submitter)
|
||||
RETURNING id
|
||||
");
|
||||
$stmt->execute([
|
||||
':name' => $name,
|
||||
':platform' => $platform,
|
||||
':kick_name' => $kick_name,
|
||||
':added_by' => $added_by,
|
||||
':submitter' => $submitter,
|
||||
]);
|
||||
$row = $stmt->fetch();
|
||||
json_out(['ok' => true, 'id' => $row['id']], 201);
|
||||
} catch (PDOException $e) {
|
||||
if (str_contains($e->getMessage(), 'unique')) {
|
||||
json_error('Streamer already exists', 409);
|
||||
}
|
||||
json_error('DB error', 500);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// PUT — update streamer + rating (admin or mod)
|
||||
// ------------------------------------------------------------------
|
||||
if ($method === 'PUT') {
|
||||
require_mod();
|
||||
|
||||
$id = (int)($_GET['id'] ?? 0);
|
||||
if (!$id) json_error('Missing id');
|
||||
|
||||
$is_admin = !empty($_SESSION['is_admin']);
|
||||
$body = body();
|
||||
|
||||
// Lock/unlock community ratings — admin only
|
||||
if (isset($_GET['lock'])) {
|
||||
if (!$is_admin) json_error('Admin only', 403);
|
||||
$locked = !empty($body['community_locked']) ? 'true' : 'false';
|
||||
db()->prepare("UPDATE streamers SET community_locked=:l WHERE id=:id")
|
||||
->execute([':l' => $locked, ':id' => $id]);
|
||||
json_out(['ok' => true]);
|
||||
}
|
||||
|
||||
// Clamp rating values 0-10
|
||||
$clamp = fn($v) => max(0, min(10, (int)$v));
|
||||
$r = $body['r'] ?? [];
|
||||
$stats = $clamp($r['s'] ?? 0);
|
||||
$graf = $clamp($r['g'] ?? 0);
|
||||
$alert = $clamp($r['a'] ?? 0);
|
||||
$vych = $clamp($r['v'] ?? 0);
|
||||
$nahl = $clamp($r['n'] ?? 0);
|
||||
$nast = $clamp($r['ns'] ?? 0);
|
||||
$odl = $clamp($r['o'] ?? 0);
|
||||
$notes = substr(trim($body['notes'] ?? ''), 0, 2000);
|
||||
$evaluated = ($stats + $graf + $alert + $vych + $nahl + $nast + $odl) > 0;
|
||||
|
||||
// Reward — admin can override manually, mods get auto-calculated
|
||||
$reward = $is_admin
|
||||
? max(0, min(130, (int)($body['reward'] ?? 0)))
|
||||
: ($evaluated ? (int)round(30 + (($stats+$graf+$alert+$vych+$nahl+$nast+$odl) / 70) * 100) : 0);
|
||||
|
||||
$db = db();
|
||||
|
||||
// Moderators can only update ratings, not streamer metadata (status/game/title)
|
||||
if ($is_admin) {
|
||||
$kick = sanitize_name($body['kick'] ?? '');
|
||||
$status = in_array($body['status'] ?? '', ['live','offline']) ? $body['status'] : 'offline';
|
||||
$game = substr(trim($body['game'] ?? ''), 0, 100);
|
||||
$title = substr(trim($body['title'] ?? ''), 0, 200);
|
||||
|
||||
$db->prepare("
|
||||
UPDATE streamers
|
||||
SET kick_name=:kick, status=:status, game=:game, title=:title, evaluated=:evaluated
|
||||
WHERE id=:id
|
||||
")->execute([
|
||||
':kick'=>$kick, ':status'=>$status, ':game'=>$game,
|
||||
':title'=>$title, ':evaluated'=>$evaluated?'true':'false', ':id'=>$id,
|
||||
]);
|
||||
} else {
|
||||
// Mod: only update evaluated flag
|
||||
$db->prepare("UPDATE streamers SET evaluated=:evaluated WHERE id=:id")
|
||||
->execute([':evaluated'=>$evaluated?'true':'false', ':id'=>$id]);
|
||||
}
|
||||
|
||||
// Upsert rating row
|
||||
$db->prepare("
|
||||
INSERT INTO ratings
|
||||
(streamer_id, statistiky, grafika, alerty, vychytavky,
|
||||
nahled, nastaveni, odlisnost, reward, notes)
|
||||
VALUES
|
||||
(:sid, :s, :g, :a, :v, :n, :ns, :o, :reward, :notes)
|
||||
ON CONFLICT (streamer_id) DO UPDATE SET
|
||||
statistiky = EXCLUDED.statistiky,
|
||||
grafika = EXCLUDED.grafika,
|
||||
alerty = EXCLUDED.alerty,
|
||||
vychytavky = EXCLUDED.vychytavky,
|
||||
nahled = EXCLUDED.nahled,
|
||||
nastaveni = EXCLUDED.nastaveni,
|
||||
odlisnost = EXCLUDED.odlisnost,
|
||||
reward = EXCLUDED.reward,
|
||||
notes = EXCLUDED.notes,
|
||||
updated_at = NOW()
|
||||
")->execute([
|
||||
':sid' => $id,
|
||||
':s' => $stats,
|
||||
':g' => $graf,
|
||||
':a' => $alert,
|
||||
':v' => $vych,
|
||||
':n' => $nahl,
|
||||
':ns' => $nast,
|
||||
':o' => $odl,
|
||||
':reward' => $reward,
|
||||
':notes' => $notes,
|
||||
]);
|
||||
|
||||
json_out(['ok' => true]);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// DELETE — remove streamer (admin only)
|
||||
// ------------------------------------------------------------------
|
||||
if ($method === 'DELETE') {
|
||||
require_admin();
|
||||
|
||||
$id = (int)($_GET['id'] ?? 0);
|
||||
if (!$id) json_error('Missing id');
|
||||
|
||||
db()->prepare("DELETE FROM streamers WHERE id = :id")->execute([':id' => $id]);
|
||||
json_out(['ok' => true]);
|
||||
}
|
||||
|
||||
json_error('Method not allowed', 405);
|
||||
Reference in New Issue
Block a user