/* ============================================================

0. SESSION & PROTECTION

============================================================ */

session_start();

if (!isset($_SESSION['email'])) {

header("Location: login.php");

exit;

}

/* ============================================================

1. CONNEXION BDD (PDO $bdd)

============================================================ */

if (!isset($bdd)) {

$paths = [__DIR__ . '/db.php', __DIR__ . '/../db.php'];

foreach ($paths as $p) {

if (file_exists($p)) { require_once $p; break; }

}

}

if (!isset($bdd) || !($bdd instanceof PDO)) {

die('Configuration base de données introuvable.');

}

/* ============================================================

1b. HELPER — substr UTF-8 safe & chemin image

============================================================ */

if (!function_exists('safeSubstr')) {

function safeSubstr($s, $start, $len) {

if (function_exists('mb_substr')) return mb_substr($s, $start, $len, 'UTF-8');

return substr($s, 0, $len);

}

}

// ? CORRECTIF : Force le dossier d'upload à la racine du site public

$uploadDir = rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/images/resource/';

/* ============================================================

1c. MODE DIAGNOSTIC (Pour vérifier où vont les images)

============================================================ */

if (isset($_GET['debug'])) {

echo '

';

echo '

? Diagnostic Images

';

echo 'DOCUMENT_ROOT : ' . htmlspecialchars($_SERVER['DOCUMENT_ROOT']) . '
';

echo 'Dossier cible : ' . htmlspecialchars($uploadDir) . '
';

echo 'Le dossier existe : ' . (is_dir($uploadDir) ? '? OUI' : '? NON') . '
';

echo 'Accessible en écriture : ' . (is_writable($uploadDir) ? '? OUI' : '? NON') . '
';

echo 'Fichiers récents dans images/resource/ :
';

if (is_dir($uploadDir)) {

$files = array_diff(scandir($uploadDir), ['.', '..']);

$files = array_slice(array_reverse($files), 0, 5);

foreach ($files as $f) {

$full = $uploadDir . $f;

echo '  • ' . htmlspecialchars($f) . ' (' . number_format(filesize($full)) . ' bytes)
';

}

}

echo '

';

}

/* ============================================================

2. AJAX (save / get / delete)

============================================================ */

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {

header('Content-Type: application/json; charset=utf-8');

$response = ['success' => false, 'message' => ''];

try {

// Créer le dossier si inexistant

if (!is_dir($uploadDir)) @mkdir($uploadDir, 0755, true);

if ($_POST['action'] === 'save') {

$id = !empty($_POST['id']) ? (int)$_POST['id'] : null;

$titre = trim($_POST['titre'] ?? '');

$categorie = trim($_POST['categorie'] ?? '');

$cat2 = trim($_POST['cat2'] ?? '');

$devel = $_POST['devel'] ?? '';

$date_pub = $_POST['date_publication'] ?? date('Y-m-d');

$date_ev = !empty($_POST['date_evenement']) ? $_POST['date_evenement'] : null;

$existing_img = trim($_POST['existing_img'] ?? '');

$editeur = $_SESSION['email'] ?? ($_SESSION['username'] ?? 'admin');

if ($titre === '') throw new Exception('Le titre est obligatoire.');

if (trim(strip_tags($devel)) === '') throw new Exception('Le contenu est obligatoire.');

if ($date_pub === '') $date_pub = date('Y-m-d');

$img_filename = $existing_img ?: null;

if (isset($_FILES['img_main']) && $_FILES['img_main']['error'] === UPLOAD_ERR_OK) {

$ext = strtolower(pathinfo($_FILES['img_main']['name'], PATHINFO_EXTENSION));

if (!in_array($ext, ['jpg','jpeg','png','gif','webp'], true)) {

throw new Exception('Format image non autorisé.');

}

// Nom de fichier sécurisé (sans espaces)

$baseName = preg_replace('/[^a-zA-Z0-9]/', '_', pathinfo($_FILES['img_main']['name'], PATHINFO_FILENAME));

$newName = 'actu_' . substr($baseName, 0, 20) . '_' . uniqid() . '.' . $ext;

if (!move_uploaded_file($_FILES['img_main']['tmp_name'], $uploadDir . $newName)) {

throw new Exception("Échec de l'upload vers : " . $uploadDir . $newName);

}

// Supprimer l'ancienne image si elle existe

if ($existing_img && file_exists($uploadDir . $existing_img)) {

@unlink($uploadDir . $existing_img);

}

$img_filename = $newName;

}

$img_short = $img_filename;

if ($id) {

$sql = "UPDATE news_events SET img_short=?, img_main=?, categorie=?, titre=?, devel=?, cat2=?,

editeur=?, date_publication=?, date_evenement=? WHERE id=?";

$stmt = $bdd->prepare($sql);

$stmt->execute([$img_short, $img_filename, $categorie, $titre, $devel, $cat2,

$editeur, $date_pub, $date_ev, $id]);

$response = ['success' => true, 'message' => 'Article modifié.', 'id' => $id];

} else {

$sql = "INSERT INTO news_events

(img_short, img_main, categorie, titre, devel, cat2, editeur, date_publication, date_evenement)

VALUES (?,?,?,?,?,?,?,?,?)";

$stmt = $bdd->prepare($sql);

$stmt->execute([$img_short, $img_filename, $categorie, $titre, $devel, $cat2,

$editeur, $date_pub, $date_ev]);

$response = ['success' => true, 'message' => 'Article créé.', 'id' => $bdd->lastInsertId()];

}

}

elseif ($_POST['action'] === 'get') {

$id = (int)($_POST['id'] ?? 0);

if (!$id) throw new Exception('ID manquant.');

$stmt = $bdd->prepare("SELECT * FROM news_events WHERE id=?");

$stmt->execute([$id]);

$row = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$row) throw new Exception('Article introuvable.');

$row['devel'] = html_entity_decode($row['devel'] ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8');

$response = ['success' => true, 'article' => $row];

}

elseif ($_POST['action'] === 'delete') {

$id = (int)($_POST['id'] ?? 0);

if (!$id) throw new Exception('ID manquant.');

$stmt = $bdd->prepare("SELECT img_main FROM news_events WHERE id=?");

$stmt->execute([$id]);

$img = $stmt->fetchColumn();

if ($img && file_exists($uploadDir . $img)) @unlink($uploadDir . $img);

$stmt = $bdd->prepare("DELETE FROM news_events WHERE id=?");

$stmt->execute([$id]);

$response = ['success' => true, 'message' => 'Article supprimé.'];

}

else throw new Exception('Action inconnue.');

} catch (Exception $e) {

$response = ['success' => false, 'message' => $e->getMessage()];

}

echo json_encode($response);

exit;

}

/* ============================================================

3. LECTURE — liste allégée

============================================================ */

$articles = [];

try {

$stmt = $bdd->query("SELECT id, img_main, titre, categorie, cat2, editeur, date_publication, date_evenement

FROM news_events ORDER BY date_publication DESC, id DESC");

$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (Exception $e) { error_log('Fetch: ' . $e->getMessage()); }

$totalArticles = count($articles);

$categories = [];

try {

$stmt = $bdd->query("SELECT DISTINCT categorie FROM news_events WHERE categorie IS NOT NULL AND categorie != '' ORDER BY categorie");

$categories = $stmt->fetchAll(PDO::FETCH_COLUMN);

} catch (Exception $e) {}

include 'menu.php';

?>

Actualités & Événements

Gérez les articles publiés sur le site.

Articles

$rowData = [

'id' => (int)$row['id'],

'titre' => $row['titre'] ?? '',

'categorie' => $row['categorie'] ?? '',

'cat2' => $row['cat2'] ?? '',

'img_main' => $row['img_main'] ?? '',

'editeur' => $row['editeur'] ?? '',

'date_publication' => $row['date_publication'] ?? '',

'date_evenement' => $row['date_evenement'] ?? '',

];

$jsonAttr = htmlspecialchars(json_encode($rowData, JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');

$title = $row['titre'] ?? '';

// ? CORRECTIF : Vérification physique du fichier sur le serveur

$imgExists = !empty($row['img_main']) && file_exists($uploadDir . $row['img_main']);

?>

data-categorie=""

data-title="">

ImageTitre de l'articleCatégorieDateActions
Aucun article pour le moment

Cliquez sur « Nouvel Article » pour commencer.

class="article-thumb"

alt=""

loading="lazy"

onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';">