Files
ASPIC/sites_web.php
T

135 lines
5.1 KiB
PHP

<?php
/**
* ASPIC — sites_web.php
*
* Endpoint interne (11 septembre 2026, chantier Compétences/Missions) —
* gestion des sites créés par un collaborateur en mission (voir
* mission_agent.php). Volontairement séparé de ce dernier : la publication
* est une décision humaine explicite, jamais un outil laissé entre les mains
* du modèle (même discipline que la clôture d'une mission, jamais calculée
* automatiquement — voir Réflexions stratégiques section 18).
*
* GET : liste les sites (brouillon/publié) avec leurs fichiers.
* POST { "action": "publier", "SIT_Incr": 3 } : copie les fichiers du
* brouillon (hors racine web, /var/www/sites_brouillons) vers le dossier
* réellement servi (/var/www/html/sites_publies/{SIT_CheminDossier}/),
* marque SIT_Statut='publie' et SIT_DatePublication. Le dossier de
* destination est d'abord vidé puis repeuplé UNIQUEMENT à partir des
* fichiers connus d'ASP_SitesWebFichiers — jamais une copie de dossier brute
* qui traînerait un fichier orphelin resté sur le disque.
*
* Une fois publié, le rattachement à un nom de domaine réel
* (SIT_NomDomaine + vhost Apache ou entrée dans npm-app-1) reste une étape
* d'infrastructure manuelle, faite par Jean-Marc — hors du périmètre de cet
* endpoint.
*/
session_start();
header('Content-Type: application/json; charset=utf-8');
require __DIR__ . '/db.php';
if (empty($_SESSION['USR_Code'])) {
http_response_code(401);
echo json_encode(['error' => 'Non identifié — veuillez vous connecter.']);
exit;
}
const RACINE_BROUILLONS_SW = '/var/www/sites_brouillons';
const RACINE_PUBLIEES_SW = __DIR__ . '/sites_publies';
try {
$pdo = getDbConnection();
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Connexion base de données impossible']);
exit;
}
function supprimerDossierRecursif(string $dossier): void
{
if (!is_dir($dossier)) return;
$elements = array_diff(scandir($dossier), ['.', '..']);
foreach ($elements as $element) {
$chemin = $dossier . '/' . $element;
is_dir($chemin) ? supprimerDossierRecursif($chemin) : @unlink($chemin);
}
@rmdir($dossier);
}
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
$sites = $pdo->query('SELECT * FROM ASP_SitesWeb ORDER BY SIT_DateCreation DESC')->fetchAll();
foreach ($sites as &$s) {
$stmt = $pdo->prepare('SELECT SWF_CheminRelatif, SWF_Taille, SWF_DateModification FROM ASP_SitesWebFichiers WHERE SWF_SiteIncr = ? ORDER BY SWF_CheminRelatif');
$stmt->execute([$s['SIT_Incr']]);
$s['fichiers'] = $stmt->fetchAll();
}
echo json_encode(['sites' => $sites]);
exit;
}
if ($method === 'POST') {
$data = json_decode(file_get_contents('php://input'), true) ?? [];
$action = (string) ($data['action'] ?? '');
$sitIncr = (int) ($data['SIT_Incr'] ?? 0);
if ($action !== 'publier') {
http_response_code(400);
echo json_encode(['error' => 'Action inconnue (seule "publier" est supportée)']);
exit;
}
if ($sitIncr <= 0) {
http_response_code(400);
echo json_encode(['error' => 'SIT_Incr manquant ou invalide']);
exit;
}
$stmt = $pdo->prepare('SELECT * FROM ASP_SitesWeb WHERE SIT_Incr = ?');
$stmt->execute([$sitIncr]);
$site = $stmt->fetch();
if (!$site) {
http_response_code(404);
echo json_encode(['error' => 'Site introuvable']);
exit;
}
$stmt = $pdo->prepare('SELECT SWF_CheminRelatif FROM ASP_SitesWebFichiers WHERE SWF_SiteIncr = ?');
$stmt->execute([$sitIncr]);
$fichiers = $stmt->fetchAll(PDO::FETCH_COLUMN);
if (!$fichiers) {
http_response_code(400);
echo json_encode(['error' => 'Ce site ne contient encore aucun fichier — rien à publier.']);
exit;
}
$dossierBrouillon = RACINE_BROUILLONS_SW . '/' . $site['SIT_CheminDossier'];
$dossierPublie = RACINE_PUBLIEES_SW . '/' . $site['SIT_CheminDossier'];
supprimerDossierRecursif($dossierPublie);
@mkdir($dossierPublie, 0777, true);
@chmod($dossierPublie, 0777);
foreach ($fichiers as $relatif) {
$source = realpath($dossierBrouillon . '/' . $relatif);
$racineBrouillonReelle = realpath($dossierBrouillon);
if ($source === false || $racineBrouillonReelle === false || !str_starts_with($source, $racineBrouillonReelle)) {
continue; // fichier référencé en base mais absent/anormal sur disque — ignoré, jamais bloquant pour les autres
}
$destination = $dossierPublie . '/' . $relatif;
@mkdir(dirname($destination), 0777, true);
@chmod(dirname($destination), 0777);
copy($source, $destination);
@chmod($destination, 0666);
}
$pdo->prepare("UPDATE ASP_SitesWeb SET SIT_Statut = 'publie', SIT_DatePublication = NOW() WHERE SIT_Incr = ?")
->execute([$sitIncr]);
echo json_encode(['success' => true, 'chemin_publie' => 'sites_publies/' . $site['SIT_CheminDossier']]);
exit;
}
http_response_code(405);
echo json_encode(['error' => 'Méthode non autorisée']);