Initial commit - mini cms final

This commit is contained in:
Aya Tess tess
2025-11-03 21:53:58 +01:00
parent a366336dc1
commit a01f620ef9
14 changed files with 422 additions and 197 deletions

1
.idea/vcs.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/infrastructure" vcs="Git" />
</component>
</project>

View File

@@ -1,19 +1,24 @@
<?php
session_start();
require_once 'config.php';
// ✅ Vérification que l'utilisateur est connecté
if (!isset($_SESSION['user']) || !isset($_SESSION['user']['id'])) {
header("Location: login.php");
exit;
}
$author_id = $_SESSION['user']['id'];
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = trim($_POST['title'] ?? '');
$content = trim($_POST['content'] ?? '');
$author_id = $_SESSION['user_id'] ?? null;
if (!$author_id) {
echo "❌ Erreur : utilisateur non connecté.";
exit;
}
$imageUrl = null;
global $s3Client, $bucketName;
// ✅ Upload de l'image sur MinIO
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
$fileName = time() . '_' . basename($_FILES['image']['name']);
$tmpPath = $_FILES['image']['tmp_name'];
@@ -27,19 +32,27 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
]);
$imageUrl = "http://localhost:9000/$bucketName/$fileName";
} catch (Exception $e) {
echo "❌ Erreur upload MinIO : " . $e->getMessage();
exit;
$message = "❌ Erreur upload MinIO : " . $e->getMessage();
}
}
// ✅ Insertion de l'article dans la base de données
if ($title && $content) {
try {
$stmt = $pdo->prepare("INSERT INTO posts (title, content, image_url, user_id, date_creation)
VALUES (?, ?, ?, ?, NOW())");
$stmt = $pdo->prepare("
INSERT INTO posts (title, content, image_url, user_id, date_creation)
VALUES (?, ?, ?, ?, NOW())
");
$stmt->execute([$title, $content, $imageUrl, $author_id]);
header("Location: dashboard.php");
// ✅ Redirection vers la page d'accueil
header("Location: index.php");
exit;
} catch (PDOException $e) {
echo "❌ Erreur base de données : " . $e->getMessage();
$message = "❌ Erreur base de données : " . $e->getMessage();
}
} else {
$message = "⚠️ Tous les champs doivent être remplis.";
}
}
?>
@@ -140,6 +153,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<div class="container">
<h2>📝 Publier un nouvel article</h2>
<?php if ($message): ?>
<p style="color:red;"><?= htmlspecialchars($message) ?></p>
<?php endif; ?>
<form method="POST" enctype="multipart/form-data">
<label for="title">Titre :</label>
<input type="text" id="title" name="title" required>
@@ -153,7 +170,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<button type="submit">Publier larticle</button>
</form>
<?php if ($_SESSION['user']['role'] === 'admin'): ?>
<a href="dashboard.php" class="retour">⬅ Retour au tableau de bord</a>
<?php else: ?>
<a href="index.php" class="retour">⬅ Retour à laccueil</a>
<?php endif; ?>
</div>
<footer>🕒 <?= date('Y') ?> — Mini CMS by Aya 💖</footer>

View File

@@ -4,10 +4,9 @@ if (session_status() === PHP_SESSION_NONE) {
}
require_once __DIR__ . '/vendor/autoload.php';
use Aws\S3\S3Client;
// ✅ Connexion PDO
// ✅ Connexion PDO MySQL UTF-8 universelle
try {
$pdo = new PDO(
'mysql:host=mysql;dbname=forum_database;charset=utf8mb4',
@@ -15,14 +14,15 @@ try {
'mypassword',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
]
);
} catch (PDOException $e) {
die("Erreur de connexion MySQL : " . $e->getMessage());
die("Erreur de connexion MySQL : " . $e->getMessage());
}
// ✅ Client MinIO
// ✅ Configuration du client MinIO (S3-compatible)
$s3Client = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
@@ -35,3 +35,36 @@ $s3Client = new S3Client([
]);
$bucketName = 'bucketforum';
// ✅ Sassurer que le bucket existe (création auto si absent)
try {
$buckets = $s3Client->listBuckets();
$bucketExists = false;
foreach ($buckets['Buckets'] as $bucket) {
if ($bucket['Name'] === $bucketName) {
$bucketExists = true;
break;
}
}
if (!$bucketExists) {
$s3Client->createBucket(['Bucket' => $bucketName]);
// Rendre le bucket public automatiquement
$policy = json_encode([
'Version' => '2012-10-17',
'Statement' => [[
'Effect' => 'Allow',
'Principal' => '*',
'Action' => ['s3:GetObject'],
'Resource' => "arn:aws:s3:::{$bucketName}/*"
]]
]);
$s3Client->putBucketPolicy([
'Bucket' => $bucketName,
'Policy' => $policy
]);
}
} catch (Exception $e) {
echo "⚠️ Impossible de vérifier/créer le bucket MinIO : " . $e->getMessage();
}
?>

View File

@@ -1,11 +1,9 @@
<?php
// Démarre la session et le tampon proprement (évite les erreurs de headers)
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (!ob_get_level()) ob_start();
?>
<!DOCTYPE html>
<html lang="fr">
<head>
@@ -42,40 +40,60 @@ if (!ob_get_level()) ob_start();
color: #fff8f9;
text-shadow: 0 0 5px white;
}
/* ✅ Zone cliquable agrandie et fluide */
.profile-menu {
position: relative;
display: inline-block;
cursor: pointer;
padding: 5px 10px;
border-radius: 25px;
transition: background 0.3s;
}
.profile-menu:hover {
background: rgba(255, 255, 255, 0.2);
}
.profile-pic {
width: 40px;
height: 40px;
width: 42px;
height: 42px;
border-radius: 50%;
object-fit: cover;
border: 2px solid white;
cursor: pointer;
vertical-align: middle;
}
.dropdown {
display: none;
position: absolute;
right: 0;
top: 55px;
background: white;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(0,0,0,0.15);
margin-top: 8px;
min-width: 160px;
box-shadow: 0 3px 12px rgba(0,0,0,0.15);
min-width: 180px;
overflow: hidden;
z-index: 1000;
}
.dropdown a {
color: #ff91a4;
padding: 10px 15px;
padding: 12px 16px;
text-decoration: none;
display: block;
transition: 0.2s;
}
.dropdown a:hover {
background: #ffe5ec;
}
.profile-menu:hover .dropdown {
/* ✅ Ouverture plus fluide (hover ou clic sur toute la zone) */
.profile-menu:hover .dropdown,
.profile-menu:focus-within .dropdown {
display: block;
}
.logo {
display: flex;
align-items: center;
@@ -90,7 +108,7 @@ if (!ob_get_level()) ob_start();
</style>
</head>
<body>
<header>
<header>
<div class="logo">
<?php if (file_exists('logo_aya.png')): ?>
<img src="logo_aya.png" alt="Logo Aya">
@@ -105,7 +123,7 @@ if (!ob_get_level()) ob_start();
<a href="dashboard.php">Gestion</a>
<?php endif; ?>
<a href="add_article.php">Publier un article</a>
<div class="profile-menu">
<div class="profile-menu" tabindex="0">
<?php if (!empty($_SESSION['user']['profile_picture'])): ?>
<img src="<?= htmlspecialchars($_SESSION['user']['profile_picture']) ?>" alt="Profil" class="profile-pic">
<?php else: ?>
@@ -117,9 +135,8 @@ if (!ob_get_level()) ob_start();
</div>
</div>
<?php else: ?>
<!-- Boutons connexion / inscription -->
<a href="login.php">Connexion</a>
<a href="register.php">Inscription</a>
<?php endif; ?>
</nav>
</header>
</header>

View File

@@ -1,59 +1,195 @@
<?php
// /var/www/html/profile.php
session_start();
require_once 'config.php';
include 'header.php';
if (!isset($_SESSION['user']) || !isset($_SESSION['user']['id'])) {
header('Location: login.php'); exit;
header("Location: login.php");
exit;
}
$userId = (int)$_SESSION['user']['id'];
$userId = $_SESSION['user']['id'];
$message = '';
// POST handling (update or delete)
// ✅ Mise à jour de la bio et/ou de la photo
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$uploadDir = __DIR__ . '/uploads/profiles/';
if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
// delete?
if (isset($_POST['delete_picture'])) {
// remove file if any
if (!empty($_SESSION['user']['profile_picture']) && file_exists(__DIR__ . '/' . $_SESSION['user']['profile_picture'])) {
@unlink(__DIR__ . '/' . $_SESSION['user']['profile_picture']);
}
$stmt = $pdo->prepare("UPDATE utilisateurs SET profile_picture = NULL WHERE id = ?");
$stmt->execute([$userId]);
$_SESSION['user']['profile_picture'] = null;
header('Location: profile.php'); exit;
}
// update (bio + optional file)
$bio = trim($_POST['bio'] ?? '');
$profilePath = $_SESSION['user']['profile_picture'] ?? null;
if (!empty($_FILES['profile_picture']['name'])) {
$fname = time() . '_' . preg_replace('/[^A-Za-z0-9_.-]/', '', basename($_FILES['profile_picture']['name']));
$target = $uploadDir . $fname;
if (in_array(strtolower(pathinfo($fname, PATHINFO_EXTENSION)), ['jpg','jpeg','png']) && move_uploaded_file($_FILES['profile_picture']['tmp_name'], $target)) {
$profilePath = 'uploads/profiles/' . $fname;
} else {
$message = "❌ Problème lors de l'upload (format jpg/png uniquement).";
}
}
// update DB
$stmt = $pdo->prepare("UPDATE utilisateurs SET bio = ?, profile_picture = ? WHERE id = ?");
$stmt->execute([$bio, $profilePath, $userId]);
$profilePictureUrl = $_SESSION['user']['profile_picture'] ?? null;
global $s3Client, $bucketName;
// 📸 Upload d'une nouvelle image
if (isset($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
$fileName = 'profile_' . $userId . '_' . time() . '_' . basename($_FILES['profile_picture']['name']);
$tmpPath = $_FILES['profile_picture']['tmp_name'];
try {
$s3Client->putObject([
'Bucket' => $bucketName,
'Key' => $fileName,
'SourceFile' => $tmpPath,
'ACL' => 'public-read'
]);
$profilePictureUrl = "http://localhost:9000/$bucketName/$fileName";
} catch (Exception $e) {
$message = "❌ Erreur upload MinIO : " . $e->getMessage();
}
}
// 🧹 Suppression de la photo
if (isset($_POST['delete_picture'])) {
$profilePictureUrl = null;
}
try {
$stmt = $pdo->prepare("UPDATE utilisateurs SET bio = ?, profile_picture = ? WHERE id = ?");
$stmt->execute([$bio, $profilePictureUrl, $userId]);
// sync session
$_SESSION['user']['bio'] = $bio;
$_SESSION['user']['profile_picture'] = $profilePath;
header('Location: profile.php'); exit;
$_SESSION['user']['profile_picture'] = $profilePictureUrl;
$message = "✅ Profil mis à jour avec succès !";
} catch (PDOException $e) {
$message = "❌ Erreur base de données : " . $e->getMessage();
}
}
// fetch fresh data
$stmt = $pdo->prepare("SELECT username, bio, profile_picture FROM utilisateurs WHERE id = ?");
// ✅ Récupération des infos utilisateur
$stmt = $pdo->prepare("SELECT username, role, bio, profile_picture FROM utilisateurs WHERE id = ?");
$stmt->execute([$userId]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
?>
<!-- include the HTML/CSS you prefer (same as earlier). -->
<?php include 'footer.php'; ?>
$user = $stmt->fetch();
// ✅ Détermine la redirection correcte
if ($user['role'] === 'admin') {
$redirectPage = "dashboard.php"; // Admin → tableau de bord admin
} else {
$redirectPage = "index.php"; // Utilisateur → accueil public
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Profil de <?= htmlspecialchars($user['username']) ?></title>
<style>
body {
font-family: 'Poppins', sans-serif;
background: linear-gradient(120deg, #fff4f7, #ffe6ea);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 6px 18px rgba(255, 100, 150, 0.2);
text-align: center;
width: 400px;
}
h2 {
color: #ff69b4;
margin-bottom: 15px;
}
.profile-picture {
width: 120px;
height: 120px;
border-radius: 50%;
object-fit: cover;
border: 3px solid #ff69b4;
margin-bottom: 10px;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 15px;
}
textarea {
padding: 10px;
border-radius: 8px;
border: 1px solid #ddd;
resize: vertical;
font-family: 'Poppins', sans-serif;
}
button {
background: linear-gradient(45deg, #ff69b4, #ffa07a);
border: none;
color: white;
padding: 10px;
border-radius: 20px;
cursor: pointer;
font-weight: 600;
transition: 0.3s;
}
button:hover {
opacity: 0.9;
}
.actions {
display: flex;
justify-content: center;
gap: 10px;
}
.message {
margin: 10px 0;
color: #ff69b4;
font-weight: bold;
}
a {
color: #ff69b4;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h2>Profil de <?= htmlspecialchars($user['username']) ?></h2>
<?php if (!empty($user['profile_picture'])): ?>
<img src="<?= htmlspecialchars($user['profile_picture']) ?>" class="profile-picture" alt="Photo de profil">
<?php else: ?>
<div style="font-size:60px;">👤</div>
<?php endif; ?>
<p><strong>Rôle :</strong> <?= htmlspecialchars($user['role']) ?></p>
<form method="POST" enctype="multipart/form-data">
<label for="bio">Votre bio :</label>
<textarea name="bio" id="bio" rows="4"><?= htmlspecialchars($user['bio'] ?? '') ?></textarea>
<label for="profile_picture">Changer la photo :</label>
<input type="file" name="profile_picture" id="profile_picture" accept="image/png, image/jpeg">
<div class="actions">
<button type="submit" name="update_profile">Mettre à jour</button>
<button type="submit" name="delete_picture" style="background:#ddd;color:#333;">Supprimer la photo</button>
</div>
</form>
<?php if ($message): ?>
<div class="message"><?= htmlspecialchars($message) ?></div>
<?php endif; ?>
<p style="margin-top:20px;">
<a href="<?= $redirectPage ?>">⬅ Retour au tableau de bord</a>
</p>
</div>
</body>
</html>

View File

@@ -10,13 +10,11 @@ if ($id <= 0) {
exit;
}
// fetch user
$stmt = $pdo->prepare("SELECT id, username, bio, profile_picture FROM utilisateurs WHERE id = ?");
$stmt->execute([$id]);
$u = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$u) { echo "Utilisateur introuvable."; exit; }
// fetch posts by user
$stmt2 = $pdo->prepare("SELECT id, title, content, image_url, date_creation FROM posts WHERE user_id = ? ORDER BY date_creation DESC");
$stmt2->execute([$id]);
$posts = $stmt2->fetchAll(PDO::FETCH_ASSOC);

View File

@@ -1,26 +1,28 @@
<?php
session_start();
require_once "config.php";
include "header.php";
require_once 'config.php';
// Vérifier si le formulaire a été soumis
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$username = trim($_POST["username"]);
$password = password_hash($_POST["password"], PASSWORD_BCRYPT);
$role = "auteur"; // Par défaut, tout nouvel utilisateur est auteur
$message = '';
// Vérifier si le nom d'utilisateur existe déjà
$stmt = $pdo->prepare("SELECT id FROM utilisateurs WHERE username = ?");
$stmt->execute([$username]);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
if ($stmt->rowCount() > 0) {
echo "<p style='color:red;text-align:center;'>⚠️ Ce nom d'utilisateur existe déjà.</p>";
if ($username && $email && $password) {
$hashedPassword = password_hash($password, PASSWORD_BCRYPT);
$role = 'auteur'; // ✅ tout nouvel utilisateur est un auteur
try {
$stmt = $pdo->prepare("INSERT INTO utilisateurs (username, email, password, role) VALUES (?, ?, ?, ?)");
$stmt->execute([$username, $email, $hashedPassword, $role]);
header("Location: login.php");
exit;
} catch (PDOException $e) {
$message = "❌ Erreur lors de l'inscription : " . $e->getMessage();
}
} else {
// Insérer le nouvel utilisateur
$stmt = $pdo->prepare("INSERT INTO utilisateurs (username, password, role) VALUES (?, ?, ?)");
$stmt->execute([$username, $password, $role]);
echo "<p style='color:green;text-align:center;'>✅ Inscription réussie ! Vous pouvez maintenant vous connecter.</p>";
$message = "⚠️ Tous les champs sont obligatoires.";
}
}
?>
@@ -29,70 +31,58 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Inscription - Mini CMS</title>
<title>Créer un compte ✨</title>
<style>
body {
background: linear-gradient(135deg, #ffb6c1, #ffa07a);
font-family: 'Poppins', sans-serif;
margin: 0;
height: 100vh;
background: linear-gradient(120deg, #ffe0ec, #fff6f8);
display: flex;
justify-content: center;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.container {
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
width: 400px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
width: 380px;
text-align: center;
}
h2 {
color: #ff69b4;
margin-bottom: 20px;
}
input[type=text], input[type=password] {
input {
width: 90%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 8px;
border: 1px solid #ccc;
}
button {
background: linear-gradient(45deg, #ff69b4, #ffa07a);
color: white;
border: none;
padding: 12px 25px;
border-radius: 25px;
color: white;
padding: 10px 20px;
border-radius: 20px;
cursor: pointer;
font-weight: bold;
}
button:hover {
opacity: 0.9;
}
a {
color: #ff69b4;
text-decoration: none;
font-weight: 600;
width: 95%;
}
a:hover {
text-decoration: underline;
}
button:hover { opacity: 0.9; }
.message { color: red; margin-bottom: 10px; }
a { color: #ff69b4; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h2>Créer un compte</h2>
<h2>Créer un compte</h2>
<?php if ($message): ?><div class="message"><?= $message ?></div><?php endif; ?>
<form method="POST">
<input type="text" name="username" placeholder="Nom d'utilisateur" required><br>
<input type="email" name="email" placeholder="Email" required><br>
<input type="password" name="password" placeholder="Mot de passe" required><br>
<button type="submit">S'inscrire</button>
</form>
<p>Déjà un compte ? <a href="login.php">Se connecter</a></p>
<p>Déjà inscrit ? <a href="login.php">Connectez-vous</a></p>
</div>
</body>
</html>
<?php include "footer.php"; ?>

View File

@@ -1,4 +1,4 @@
/* 🎨 — Thème global rose/orangé élégant */
body {
font-family: "Poppins", sans-serif;
background: #fffafc;
@@ -7,7 +7,7 @@ body {
padding: 0;
}
/* 🌟 — En-tête du site */
header {
background: linear-gradient(90deg, #ffa45b, #ff6fa7);
color: white;
@@ -26,7 +26,7 @@ header a:hover {
text-decoration: underline;
}
/* 👤 — Auteur dans la liste darticles */
.article-meta {
display: flex;
align-items: center;
@@ -51,7 +51,7 @@ header a:hover {
text-decoration: underline;
}
/* 🧍‍♀️ — Page de profil publique (profile_view.php) */
.profile-view {
max-width: 900px;
margin: 60px auto;
@@ -91,7 +91,7 @@ header a:hover {
margin-top: 5px;
}
/* 📰 — Articles de lauteur */
.user-articles h3 {
color: #ff6fa7;
margin-bottom: 15px;
@@ -140,7 +140,7 @@ header a:hover {
opacity: 0.9;
}
/* 📱 — Responsive */
@media (max-width: 768px) {
header {
flex-direction: column;

View File

@@ -1,7 +1,7 @@
<?php
require_once __DIR__ . '/config.php'; // doit définir $s3Client et $bucketName
// crée un petit fichier temporaire
$tmp = '/tmp/test_minio_upload_'.time().'.txt';
file_put_contents($tmp, "test upload ".time());

0
infrastructure/README.md Normal file
View File

View File

@@ -12,10 +12,9 @@ services:
- ../forum-project:/var/www/html
env_file:
- .env
depends_on:
- mysql
- minio
mysql:
image: mysql:8.1
@@ -33,6 +32,7 @@ services:
volumes:
- mysql_data:/var/lib/mysql
- ./setup-mysql:/docker-entrypoint-initdb.d
- ./setup-mysql/my.cnf:/etc/mysql/conf.d/my.cnf
minio:
@@ -64,5 +64,3 @@ services:
volumes:
mysql_data:
minio_data:

29
infrastructure/setup-minio/init-minio.sh Normal file → Executable file
View File

@@ -1,13 +1,26 @@
#!/bin/sh
set -e
# Attendre que MinIO démarre
echo "Waiting for MinIO to start..."
sleep 10
echo "⏳ Attente du démarrage de MinIO..."
sleep 5
# Créer un alias pour MinIO
mc alias set localminio http://minio:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD
# Configuration du client MinIO (mc)
echo "🔧 Configuration du client MinIO..."
mc alias set myminio http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"
# Créer le bucket (ignore erreur si existe déjà)
mc mb localminio/bucketforum || true
# Création du bucket sil nexiste pas déjà
echo "🪣 Vérification du bucket 'bucketforum'..."
if ! mc ls myminio | grep -q "bucketforum"; then
mc mb myminio/bucketforum
echo "✅ Bucket 'bucketforum' créé."
else
echo " Bucket 'bucketforum' déjà existant."
fi
# Définir une politique publique sur le bucket (optionnel)
mc policy set public localminio/bucketforum
# Rendre le bucket public
echo "🌍 Configuration de la politique publique..."
mc anonymous set public myminio/bucketforum
# Vérification du statut
echo "✅ Bucket 'bucketforum' est public et prêt à être utilisé."

View File

@@ -1,33 +1,41 @@
-- encodage base
CREATE DATABASE IF NOT EXISTS forum_database
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE forum_database;
-- table utilisateurs
CREATE TABLE IF NOT EXISTS utilisateurs (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) UNIQUE,
role VARCHAR(50) DEFAULT 'user',
bio TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
profile_picture VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- table posts
CREATE TABLE IF NOT EXISTS posts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
title VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
content LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
image_url VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES utilisateurs(id)
);
date_creation DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES utilisateurs(id) ON DELETE CASCADE
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
INSERT INTO utilisateurs (username, password, email)
-- données initiales
INSERT INTO utilisateurs (username, password, email, role)
VALUES
('aya', 'password123', 'ayae@example.com'),
('tess', 'password456', 'tess@example.com');
('admin', '$2y$10$4U8a64xTrD/GQDnj8tCNsemA47765p.5gtflWWBKl6UGl2aj/uOlC', 'admin@example.com', 'admin'),
('aya', '$2y$10$vhtGydzlL8AFMbRTeRVC2OtDkud47TZCHt98HcAjjGGVlLlm2Bn66', 'aya@example.com', 'user');
INSERT INTO posts (user_id, title, content)
VALUES
(1, 'Bienvenue sur le forum', 'Ceci est le premier post !'),
(2, 'Deuxième post', 'Un autre test pour vérifier la base.');
ALTER TABLE posts
DROP FOREIGN KEY posts_ibfk_1;
ALTER TABLE posts
ADD CONSTRAINT posts_ibfk_1
FOREIGN KEY (user_id) REFERENCES utilisateurs(id)
ON DELETE CASCADE;
(1, 'Bienvenue sur le Mini CMS', 'Ceci est un article de démonstration publié par ladministrateur !'),
(2, 'Un premier article test', 'Bienvenue dans notre CMS simplifié. Partagez vos idées ici !');

View File

@@ -0,0 +1,10 @@
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-character-set-client-handshake
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4