mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
127 lines
3.6 KiB
PHP
127 lines
3.6 KiB
PHP
<?php
|
|
/**
|
|
* PeerTube video relink endpoint (admin).
|
|
*
|
|
* POST /admin/actions/peertube-relink.php
|
|
* Body: JSON { thesis_id: 123, uuid: "bmpQZTUPv4ou8ufiwajV63" }
|
|
*
|
|
* Links an existing PeerTube video to a thesis by inserting a thesis_files row
|
|
* with file_path = 'peertube_ids:{uuid}'. Only videos that are on the channel
|
|
* but NOT linked to any TFE can be relinked.
|
|
*/
|
|
require_once __DIR__ . '/../../../bootstrap.php';
|
|
require_once __DIR__ . '/../../../src/AdminAuth.php';
|
|
AdminAuth::requireLogin();
|
|
|
|
function peertubeRelinkError(int $code, string $message): never {
|
|
http_response_code($code);
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['ok' => false, 'error' => $message]);
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
peertubeRelinkError(405, 'Méthode non autorisée.');
|
|
}
|
|
|
|
$csrfHeader = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
|
|
if (!isset($_SESSION['csrf_token'])
|
|
|| !hash_equals($_SESSION['csrf_token'], $csrfHeader)) {
|
|
peertubeRelinkError(403, 'Token CSRF invalide.');
|
|
}
|
|
|
|
$body = json_decode(file_get_contents('php://input'), true);
|
|
if (!is_array($body)) {
|
|
peertubeRelinkError(400, 'JSON invalide.');
|
|
}
|
|
|
|
$thesisId = filter_var($body['thesis_id'] ?? '', FILTER_VALIDATE_INT);
|
|
$uuid = trim($body['uuid'] ?? '');
|
|
|
|
if (!$thesisId || $uuid === '') {
|
|
peertubeRelinkError(400, 'Paramètres invalides (thesis_id + uuid requis).');
|
|
}
|
|
|
|
// Validate UUID format (shortUUID or full UUID)
|
|
if (!preg_match('/^[a-zA-Z0-9\-_]+$/', $uuid)) {
|
|
peertubeRelinkError(400, 'UUID invalide.');
|
|
}
|
|
|
|
require_once APP_ROOT . '/src/Database.php';
|
|
require_once APP_ROOT . '/src/PeerTubeService.php';
|
|
|
|
$db = new Database();
|
|
|
|
if (!PeerTubeService::isConfigured($db)) {
|
|
peertubeRelinkError(503, 'PeerTube non configuré.');
|
|
}
|
|
|
|
// Check thesis exists
|
|
$thesis = $db->getThesis($thesisId);
|
|
if (!$thesis) {
|
|
peertubeRelinkError(404, 'TFE introuvable.');
|
|
}
|
|
|
|
// Check this UUID is not already linked to this thesis
|
|
$pdo = $db->getConnection();
|
|
$stmt = $pdo->prepare(
|
|
"SELECT id FROM thesis_files
|
|
WHERE thesis_id = ? AND file_path = ?"
|
|
);
|
|
$stmt->execute([$thesisId, 'peertube_ids:' . $uuid]);
|
|
if ($stmt->fetch()) {
|
|
peertubeRelinkError(409, 'Cette vidéo est déjà liée à ce TFE.');
|
|
}
|
|
|
|
// Verify the video exists on the channel
|
|
$info = PeerTubeService::fetchVideoInfo($db, $uuid);
|
|
if ($info === null) {
|
|
peertubeRelinkError(404, 'Vidéo introuvable sur PeerTube.');
|
|
}
|
|
|
|
// Verify it's not already linked to another TFE
|
|
$stmt = $pdo->prepare(
|
|
"SELECT t.identifier FROM thesis_files tf
|
|
JOIN theses t ON t.id = tf.thesis_id
|
|
WHERE tf.file_path = ? AND t.deleted_at IS NULL"
|
|
);
|
|
$stmt->execute(['peertube_ids:' . $uuid]);
|
|
$existing = $stmt->fetch();
|
|
if ($existing) {
|
|
peertubeRelinkError(409,
|
|
'Cette vidéo est déjà liée au TFE ' . htmlspecialchars($existing['identifier'] ?? '?')
|
|
. '. Dé-liez-la d\'abord avant de la relier à un autre.'
|
|
);
|
|
}
|
|
|
|
// Determine file type from PeerTube info
|
|
$videoName = $info['name'] ?? $uuid;
|
|
$fileType = 'video'; // default
|
|
$catId = (int)($info['category']['id'] ?? 0);
|
|
if ($catId === 16) {
|
|
$fileType = 'audio';
|
|
}
|
|
|
|
$db->insertThesisFile(
|
|
$thesisId,
|
|
$fileType,
|
|
'peertube_ids:' . $uuid,
|
|
$videoName,
|
|
0, // size unknown (not on disk)
|
|
'video/mp4', // PeerTube streams HLS, mime is nominal
|
|
null,
|
|
null
|
|
);
|
|
|
|
$newId = $pdo->lastInsertId();
|
|
|
|
error_log("[peertube-relink] thesis_id=$thesisId uuid=$uuid file_type=$fileType new_id=$newId");
|
|
|
|
header('Content-Type: application/json');
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'id' => (int)$newId,
|
|
'message' => 'Vidéo PeerTube reliée avec succès.',
|
|
]);
|
|
exit;
|