Initial commit : CMS Simplifié
This commit is contained in:
55
public/add.php
Normal file
55
public/add.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
session_start();
|
||||
if(!isset($_SESSION['user_id'])){ header('Location: login.php'); exit; }
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$error = null;
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$titre = trim($_POST['titre'] ?? '');
|
||||
$contenu = trim($_POST['contenu'] ?? '');
|
||||
if($titre!=='' && $contenu!==''){
|
||||
$stmt = $pdo->prepare("INSERT INTO articles(titre,contenu) VALUES(?,?)");
|
||||
$stmt->execute([$titre,$contenu]);
|
||||
header('Location: admin.php'); exit;
|
||||
} else { $error = 'Champs obligatoires.'; }
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Ajouter un article</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css?v=6" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar">
|
||||
<div class="container container-narrow d-flex align-items-center gap-3">
|
||||
<a class="navbar-brand fw-semibold" href="admin.php">Administration</a>
|
||||
<div class="ms-auto navbar-text">Connecté: <?= htmlspecialchars($_SESSION['user_login']) ?></div>
|
||||
<a class="btn btn-outline-accent btn-sm" href="logout.php">Se déconnecter</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-4" style="max-width:820px">
|
||||
<div class="card p-4">
|
||||
<h1 class="h4 mb-3">Ajouter un article</h1>
|
||||
<?php if($error): ?><div class="alert alert-danger"><?= htmlspecialchars($error) ?></div><?php endif; ?>
|
||||
<form method="post" class="vstack gap-3">
|
||||
<div>
|
||||
<label class="form-label">Titre</label>
|
||||
<input class="form-control" type="text" name="titre" required>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Contenu</label>
|
||||
<textarea class="form-control" rows="10" name="contenu" required></textarea>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-accent">Enregistrer</button>
|
||||
<a class="btn btn-outline-accent" href="admin.php">Annuler</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
54
public/admin.php
Normal file
54
public/admin.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
session_start();
|
||||
if(!isset($_SESSION['user_id'])) { header('Location: login.php'); exit; }
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$stmt = $pdo->query("SELECT * FROM articles ORDER BY date_creation DESC");
|
||||
$articles = $stmt->fetchAll();
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Administration</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css?v=6" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar">
|
||||
<div class="container container-narrow d-flex align-items-center gap-3">
|
||||
<a class="navbar-brand fw-semibold" href="/">CMS Simplifié</a>
|
||||
<div class="ms-auto navbar-text">Connecté: <?= htmlspecialchars($_SESSION['user_login']) ?></div>
|
||||
<a class="btn btn-outline-accent btn-sm" href="logout.php">Se déconnecter</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h1 class="h4 m-0">Articles</h1>
|
||||
<a class="btn btn-accent btn-sm" href="add.php">Ajouter</a>
|
||||
</div>
|
||||
|
||||
<?php if(!$articles): ?>
|
||||
<div class="alert alert-secondary">Aucun article.</div>
|
||||
<?php else: ?>
|
||||
<div class="list-group">
|
||||
<?php foreach($articles as $a): ?>
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="fw-semibold item-title"><?= htmlspecialchars($a['titre']) ?></div>
|
||||
<small class="text-muted"><?= htmlspecialchars($a['date_creation']) ?></small>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn btn-outline-accent btn-sm" href="edit.php?id=<?= (int)$a['id'] ?>">Modifier</a>
|
||||
<a class="btn btn-danger btn-sm" href="delete.php?id=<?= (int)$a['id'] ?>">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
40
public/article.php
Normal file
40
public/article.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$id=filter_input(INPUT_GET,'id',FILTER_VALIDATE_INT);
|
||||
if(!$id){http_response_code(404);exit('404 - Article non trouvé');}
|
||||
$stmt=$pdo->prepare("SELECT id,titre,contenu,date_creation FROM articles WHERE id=?");
|
||||
$stmt->execute([$id]);
|
||||
$article=$stmt->fetch();
|
||||
if(!$article){http_response_code(404);exit('404 - Article non trouvé');}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title><?= htmlspecialchars($article['titre']) ?></title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar">
|
||||
<div class="container container-narrow">
|
||||
<a class="navbar-brand fw-semibold" href="/">CMS Simplifié</a>
|
||||
<a class="btn btn-sm btn-light" href="/">Accueil</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-4">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<h1 class="h3 mb-2"><?= htmlspecialchars($article['titre']) ?></h1>
|
||||
<span class="badge badge-date"><?= htmlspecialchars($article['date_creation']) ?></span>
|
||||
</div>
|
||||
<div class="mt-3"><?= nl2br(htmlspecialchars($article['contenu'])) ?></div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<a class="btn btn-outline-secondary btn-sm" href="/">← Retour</a>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
119
public/assets/style.css
Normal file
119
public/assets/style.css
Normal file
@@ -0,0 +1,119 @@
|
||||
:root{
|
||||
--bg-dark:#121212;
|
||||
--bg-card:#1e1e1e;
|
||||
--text-light:#f5f5f5;
|
||||
--text-muted:#b3b3b3;
|
||||
--accent:#d4af37;
|
||||
}
|
||||
|
||||
body{
|
||||
background:var(--bg-dark);
|
||||
color:var(--text-light);
|
||||
font-family:'Inter',sans-serif;
|
||||
}
|
||||
|
||||
.container-narrow{max-width:860px}
|
||||
|
||||
.navbar{
|
||||
background:linear-gradient(90deg,#1a1a1a,#333);
|
||||
box-shadow:0 2px 15px rgba(0,0,0,.6);
|
||||
}
|
||||
.navbar .navbar-brand{
|
||||
color:var(--accent)!important;
|
||||
font-weight:600;
|
||||
letter-spacing:.5px;
|
||||
}
|
||||
.navbar .navbar-text{
|
||||
color:var(--text-light)!important;
|
||||
}
|
||||
.navbar a.btn-outline-accent{
|
||||
border-color:var(--accent)!important;
|
||||
color:var(--accent)!important;
|
||||
}
|
||||
.navbar a.btn-outline-accent:hover{
|
||||
background:var(--accent);
|
||||
color:#000!important;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5{color:var(--text-light);margin:0 0 .6rem}
|
||||
.item-title{color:var(--text-light)}
|
||||
.text-muted{color:var(--text-muted)!important}
|
||||
|
||||
.card{
|
||||
background:var(--bg-card);
|
||||
border:1px solid #2d2d2d;
|
||||
box-shadow:0 8px 25px rgba(0,0,0,.5);
|
||||
color:var(--text-light);
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
.btn-accent{
|
||||
background:var(--accent);
|
||||
color:#000;
|
||||
border:0;
|
||||
font-weight:600;
|
||||
transition:.25s;
|
||||
}
|
||||
.btn-accent:hover{
|
||||
background:#b8952d;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
.btn-outline-accent{
|
||||
background:transparent;
|
||||
border:1px solid var(--accent);
|
||||
color:var(--accent);
|
||||
font-weight:600;
|
||||
transition:.25s;
|
||||
}
|
||||
.btn-outline-accent:hover{
|
||||
background:var(--accent);
|
||||
color:#000;
|
||||
}
|
||||
|
||||
.btn-danger{
|
||||
background:#b51c1c;
|
||||
border:none;
|
||||
color:#fff;
|
||||
font-weight:600;
|
||||
transition:.25s;
|
||||
}
|
||||
.btn-danger:hover{
|
||||
background:#d62828;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.form-control,textarea{
|
||||
background:#2a2a2a;
|
||||
border:1px solid #444;
|
||||
color:var(--text-light);
|
||||
}
|
||||
.form-control:focus,textarea:focus{
|
||||
border-color:var(--accent);
|
||||
box-shadow:0 0 0 .15rem rgba(212,175,55,.25);
|
||||
background:#2f2f2f;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.alert{
|
||||
background:#2d2d2d;
|
||||
color:#ccc;
|
||||
border:none;
|
||||
}
|
||||
.list-group-item{
|
||||
background:#1c1c1c;
|
||||
border:1px solid #333;
|
||||
}
|
||||
.list-group-item .text-muted{
|
||||
color:var(--text-muted)!important;
|
||||
}
|
||||
|
||||
a{
|
||||
color:var(--accent);
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
}
|
||||
a:hover{
|
||||
text-decoration:underline;
|
||||
color:#f1c94e;
|
||||
}
|
||||
46
public/delete.php
Normal file
46
public/delete.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
session_start();
|
||||
if(!isset($_SESSION['user_id'])){ header('Location: login.php'); exit; }
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$id = filter_input(INPUT_GET,'id',FILTER_VALIDATE_INT);
|
||||
if(!$id){ http_response_code(404); exit('404'); }
|
||||
$stmt = $pdo->prepare("SELECT id,titre FROM articles WHERE id=?");
|
||||
$stmt->execute([$id]);
|
||||
$article = $stmt->fetch();
|
||||
if(!$article){ http_response_code(404); exit('404'); }
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$del = $pdo->prepare("DELETE FROM articles WHERE id=?");
|
||||
$del->execute([$id]);
|
||||
header('Location: admin.php'); exit;
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Supprimer un article</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css?v=6" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar">
|
||||
<div class="container container-narrow d-flex align-items-center gap-3">
|
||||
<a class="navbar-brand fw-semibold" href="admin.php">Administration</a>
|
||||
<div class="ms-auto navbar-text">Connecté: <?= htmlspecialchars($_SESSION['user_login']) ?></div>
|
||||
<a class="btn btn-outline-accent btn-sm" href="logout.php">Se déconnecter</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-4" style="max-width:700px">
|
||||
<div class="card p-4">
|
||||
<h1 class="h4 mb-3">Confirmation</h1>
|
||||
<div class="alert alert-warning mb-4">Supprimer « <?= htmlspecialchars($article['titre']) ?> » ?</div>
|
||||
<form method="post" class="d-flex gap-2">
|
||||
<button class="btn btn-accent">Confirmer</button>
|
||||
<a class="btn btn-outline-accent" href="admin.php">Annuler</a>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
61
public/edit.php
Normal file
61
public/edit.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
session_start();
|
||||
if(!isset($_SESSION['user_id'])){ header('Location: login.php'); exit; }
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$id = filter_input(INPUT_GET,'id',FILTER_VALIDATE_INT);
|
||||
if(!$id){ http_response_code(404); exit('404'); }
|
||||
$stmt = $pdo->prepare("SELECT id,titre,contenu FROM articles WHERE id=?");
|
||||
$stmt->execute([$id]);
|
||||
$article = $stmt->fetch();
|
||||
if(!$article){ http_response_code(404); exit('404'); }
|
||||
$error = null;
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$titre = trim($_POST['titre'] ?? '');
|
||||
$contenu = trim($_POST['contenu'] ?? '');
|
||||
if($titre!=='' && $contenu!==''){
|
||||
$upd = $pdo->prepare("UPDATE articles SET titre=?,contenu=? WHERE id=?");
|
||||
$upd->execute([$titre,$contenu,$id]);
|
||||
header('Location: admin.php'); exit;
|
||||
} else { $error = 'Champs obligatoires.'; }
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Modifier un article</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css?v=6" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar">
|
||||
<div class="container container-narrow d-flex align-items-center gap-3">
|
||||
<a class="navbar-brand fw-semibold" href="admin.php">Administration</a>
|
||||
<div class="ms-auto navbar-text">Connecté: <?= htmlspecialchars($_SESSION['user_login']) ?></div>
|
||||
<a class="btn btn-outline-accent btn-sm" href="logout.php">Se déconnecter</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-4" style="max-width:820px">
|
||||
<div class="card p-4">
|
||||
<h1 class="h4 mb-3">Modifier l’article</h1>
|
||||
<?php if($error): ?><div class="alert alert-danger"><?= htmlspecialchars($error) ?></div><?php endif; ?>
|
||||
<form method="post" class="vstack gap-3">
|
||||
<div>
|
||||
<label class="form-label">Titre</label>
|
||||
<input class="form-control" type="text" name="titre" required value="<?= htmlspecialchars($article['titre']) ?>">
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Contenu</label>
|
||||
<textarea class="form-control" rows="10" name="contenu" required><?= htmlspecialchars($article['contenu']) ?></textarea>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-accent">Mettre à jour</button>
|
||||
<a class="btn btn-outline-accent" href="admin.php">Annuler</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
48
public/index.php
Normal file
48
public/index.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$stmt=$pdo->prepare("SELECT id,titre,SUBSTRING(contenu,1,180) AS intro,date_creation FROM articles ORDER BY date_creation DESC LIMIT 10");
|
||||
$stmt->execute();
|
||||
$articles=$stmt->fetchAll();
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Accueil</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg">
|
||||
<div class="container container-narrow">
|
||||
<a class="navbar-brand fw-semibold" href="/">CMS Simplifié</a>
|
||||
<div class="ms-auto">
|
||||
<a class="btn btn-sm btn-light" href="login.php">Admin</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-4">
|
||||
<h1 class="mb-4">Derniers articles</h1>
|
||||
<?php if(!$articles): ?>
|
||||
<div class="alert alert-secondary">Aucun article pour le moment.</div>
|
||||
<?php else: ?>
|
||||
<div class="row g-4">
|
||||
<?php foreach($articles as $a): ?>
|
||||
<div class="col-12">
|
||||
<div class="card p-3">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<h5 class="mb-2"><?= htmlspecialchars($a['titre']) ?></h5>
|
||||
<span class="badge badge-date"><?= htmlspecialchars($a['date_creation']) ?></span>
|
||||
</div>
|
||||
<p class="mb-3"><?= nl2br(htmlspecialchars($a['intro'])) ?>...</p>
|
||||
<a class="btn btn-accent btn-sm" href="article.php?id=<?= (int)$a['id'] ?>">Lire</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
52
public/login.php
Normal file
52
public/login.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
session_start();
|
||||
require __DIR__ . '/../inc/db.php';
|
||||
$error=null;
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$login=isset($_POST['login'])?trim($_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_id']=$user['id'];
|
||||
$_SESSION['user_login']=$user['login'];
|
||||
header('Location: admin.php'); exit;
|
||||
} else { $error='Identifiants incorrects.'; }
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Connexion</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="assets/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar">
|
||||
<div class="container container-narrow">
|
||||
<a class="navbar-brand fw-semibold" href="/">CMS Simplifié</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container container-narrow py-5" style="max-width:520px">
|
||||
<div class="card p-4">
|
||||
<h1 class="h4 mb-3">Connexion</h1>
|
||||
<?php if($error): ?><div class="alert alert-danger"><?= htmlspecialchars($error) ?></div><?php endif; ?>
|
||||
<form method="post" class="vstack gap-3">
|
||||
<div>
|
||||
<label class="form-label">Login</label>
|
||||
<input class="form-control" type="text" name="login" required>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Mot de passe</label>
|
||||
<input class="form-control" type="password" name="password" required>
|
||||
</div>
|
||||
<button class="btn btn-accent">Se connecter</button>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
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;
|
||||
Reference in New Issue
Block a user