Refonte complète du projet
This commit is contained in:
4
.env.example
Normal file
4
.env.example
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
DB_HOST=localhost
|
||||||
|
DB_NAME=cms_simplifie
|
||||||
|
DB_USER=root
|
||||||
|
DB_PASS=root
|
||||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.env
|
||||||
|
/vendor/
|
||||||
|
/node_modules/
|
||||||
|
*.log
|
||||||
|
*.sql
|
||||||
12
README.md
Normal file
12
README.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
CMS Simplifié
|
||||||
|
|
||||||
|
Présentation
|
||||||
|
|
||||||
|
Ce mini-projet a été réalisé dans le cadre du module Développement Web (BTS CIEL – 2ᵉ année).
|
||||||
|
Il s'agit d'un mini système de gestion de contenu** qui permet de gérer des articles de manière simple.
|
||||||
|
|
||||||
|
Le site est organisé en deux parties :
|
||||||
|
- Zone publique*: les visiteurs peuvent consulter les articles sans se connecter.
|
||||||
|
- Zone administration: un administrateur peut se connecter pour ajouter, modifier ou supprimer des articles.
|
||||||
|
|
||||||
|
L’objectif principal est de pratiquer le développement web dynamique avec PHP pur et MySQL, en mettant en œuvre toutes les étapes du cycle CRUD (Create, Read, Update, Delete), la gestion des sessions et la sécurisation des données.
|
||||||
18
includes/db.php
Normal file
18
includes/db.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'cms_simplifie';
|
||||||
|
$user = 'root';
|
||||||
|
$pass = 'root';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
die("Erreur de connexion : " . $e->getMessage());
|
||||||
|
}
|
||||||
6
includes/footer.php
Normal file
6
includes/footer.php
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<p>© 2025 Mini CMS. Tous droits réservés.</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
17
includes/header.php
Normal file
17
includes/header.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>CMS</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>Mini CMS</h1>
|
||||||
|
<nav>
|
||||||
|
<a href="index.php">Accueil</a>
|
||||||
|
<a href="add.php">Ajouter un article</a>
|
||||||
|
<a href="login.php">Connexion</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
34
public/add.php
Normal file
34
public/add.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$titre = $_POST['titre'] ?? '';
|
||||||
|
$contenu = $_POST['contenu'] ?? '';
|
||||||
|
|
||||||
|
if ($titre && $contenu) {
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO articles (titre, contenu, date_creation) VALUES (?, ?, NOW())");
|
||||||
|
$stmt->execute([$titre, $contenu]);
|
||||||
|
echo "<p>Article ajouté avec succès.</p>";
|
||||||
|
} else {
|
||||||
|
echo "<p style='color:red;'>Veuillez remplir tous les champs.</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Ajouter un article</h2>
|
||||||
|
<form method="post">
|
||||||
|
<label>Titre :</label><br>
|
||||||
|
<input type="text" name="titre" required><br><br>
|
||||||
|
<label>Contenu :</label><br>
|
||||||
|
<textarea name="contenu" rows="5" required></textarea><br><br>
|
||||||
|
<input type="submit" value="Ajouter">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
22
public/admin.php
Normal file
22
public/admin.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Tableau de bord</h2>
|
||||||
|
<p>Bienvenue, <?= htmlspecialchars($_SESSION['user']) ?> !</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="add.php">Ajouter un article</a></li>
|
||||||
|
<li><a href="edit.php">Modifier un article</a></li>
|
||||||
|
<li><a href="delete.php">Supprimer un article</a></li>
|
||||||
|
<li><a href="index.php">Voir les articles</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
29
public/article.php
Normal file
29
public/article.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
$id = $_GET['id'] ?? null;
|
||||||
|
|
||||||
|
if (!$id || !is_numeric($id)) {
|
||||||
|
echo "<p>Article introuvable (404)</p>";
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM articles WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$article = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$article) {
|
||||||
|
echo "<p>Article introuvable (404)</p>";
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<article>
|
||||||
|
<h2><?= htmlspecialchars($article['titre']) ?></h2>
|
||||||
|
<p><?= nl2br(htmlspecialchars($article['contenu'])) ?></p>
|
||||||
|
<small>Publié le <?= $article['date_creation'] ?></small>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
45
public/delete.php
Normal file
45
public/delete.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $_GET['id'] ?? null;
|
||||||
|
if (!$id || !is_numeric($id)) {
|
||||||
|
echo "<p>Article introuvable (404)</p>";
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM articles WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$article = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$article) {
|
||||||
|
echo "<p>Article introuvable (404)</p>";
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM articles WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
echo "<p>Article supprimé avec succès.</p>";
|
||||||
|
echo '<a href="admin.php">Retour au tableau de bord</a>';
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Supprimer l'article</h2>
|
||||||
|
<p>Êtes-vous sûr de vouloir supprimer l'article "<strong><?= htmlspecialchars($article['titre']) ?></strong>" ?</p>
|
||||||
|
<form method="post">
|
||||||
|
<input type="submit" value="Oui, supprimer">
|
||||||
|
<a href="admin.php">Annuler</a>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
50
public/edit.php
Normal file
50
public/edit.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $_GET['id'] ?? null;
|
||||||
|
if (!$id || !is_numeric($id)) {
|
||||||
|
echo "<p>Article introuvable (404)</p>";
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM articles WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$article = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$article) {
|
||||||
|
echo "<p>Article introuvable (404)</p>";
|
||||||
|
require_once '../includes/footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$titre = $_POST['titre'] ?? '';
|
||||||
|
$contenu = $_POST['contenu'] ?? '';
|
||||||
|
if ($titre && $contenu) {
|
||||||
|
$stmt = $pdo->prepare("UPDATE articles SET titre=?, contenu=? WHERE id=?");
|
||||||
|
$stmt->execute([$titre, $contenu, $id]);
|
||||||
|
echo "<p>Article mis à jour avec succès.</p>";
|
||||||
|
} else {
|
||||||
|
echo "<p style='color:red;'>Veuillez remplir tous les champs.</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Modifier l'article</h2>
|
||||||
|
<form method="post">
|
||||||
|
<label>Titre :</label><br>
|
||||||
|
<input type="text" name="titre" value="<?= htmlspecialchars($article['titre']) ?>" required><br><br>
|
||||||
|
<label>Contenu :</label><br>
|
||||||
|
<textarea name="contenu" rows="5" required><?= htmlspecialchars($article['contenu']) ?></textarea><br><br>
|
||||||
|
<input type="submit" value="Modifier">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
18
public/index.php
Normal file
18
public/index.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
$stmt = $pdo->query("SELECT id, titre, SUBSTRING(contenu,1,150) AS extrait, date_creation
|
||||||
|
FROM articles ORDER BY date_creation DESC LIMIT 10");
|
||||||
|
?>
|
||||||
|
<h2>Derniers articles</h2>
|
||||||
|
<?php while ($row = $stmt->fetch()): ?>
|
||||||
|
<article>
|
||||||
|
<h3><a href="article.php?id=<?= $row['id'] ?>"><?= htmlspecialchars($row['titre']) ?></a></h3>
|
||||||
|
<p><?= htmlspecialchars($row['extrait']) ?>...</p>
|
||||||
|
<small>Publié le <?= $row['date_creation'] ?></small>
|
||||||
|
</article>
|
||||||
|
<hr>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
34
public/login.php
Normal file
34
public/login.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once '../includes/db.php';
|
||||||
|
require_once '../includes/header.php';
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$login = $_POST['login'] ?? '';
|
||||||
|
$password = $_POST['password'] ?? '';
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM utilisateur WHERE login = ?");
|
||||||
|
$stmt->execute([$login]);
|
||||||
|
$user = $stmt->fetch();
|
||||||
|
|
||||||
|
if ($user && password_verify($password, $user['password'])) {
|
||||||
|
$_SESSION['user'] = $user['login'];
|
||||||
|
header("Location: admin.php");
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
$error = "Identifiants incorrects";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Connexion administrateur</h2>
|
||||||
|
<?php if (!empty($error)) echo "<p style='color:red;'>$error</p>"; ?>
|
||||||
|
<form method="post">
|
||||||
|
<label>Login :</label><br>
|
||||||
|
<input type="text" name="login" required><br><br>
|
||||||
|
<label>Mot de passe :</label><br>
|
||||||
|
<input type="password" name="password" required><br><br>
|
||||||
|
<input type="submit" value="Se connecter">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php require_once '../includes/footer.php'; ?>
|
||||||
5
public/logout.php
Normal file
5
public/logout.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
session_destroy();
|
||||||
|
header("Location: login.php");
|
||||||
|
exit;
|
||||||
27
public/style.css
Normal file
27
public/style.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header, footer {
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a {
|
||||||
|
color: #fff;
|
||||||
|
margin: 0 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user