diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..a16c18a 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/forum-project/add_article.php b/forum-project/add_article.php index 89a4d3c..6ff8679 100644 --- a/forum-project/add_article.php +++ b/forum-project/add_article.php @@ -1,19 +1,24 @@ getMessage(); - exit; + $message = "❌ Erreur upload MinIO : " . $e->getMessage(); } } - try { - $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"); - exit; - } catch (PDOException $e) { - echo "❌ Erreur base de données : " . $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->execute([$title, $content, $imageUrl, $author_id]); + + // ✅ Redirection vers la page d'accueil + header("Location: index.php"); + exit; + } catch (PDOException $e) { + $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') {

📝 Publier un nouvel article

+ +

+ +
@@ -153,7 +170,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- ⬅ Retour au tableau de bord + + ⬅ Retour au tableau de bord + + ⬅ Retour à l’accueil +
diff --git a/forum-project/config.php b/forum-project/config.php index b8e55ef..abae0a9 100644 --- a/forum-project/config.php +++ b/forum-project/config.php @@ -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'; + +// ✅ S’assurer 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(); +} +?> diff --git a/forum-project/header.php b/forum-project/header.php index 899c428..fa844f3 100644 --- a/forum-project/header.php +++ b/forum-project/header.php @@ -1,11 +1,9 @@ - @@ -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,36 +108,35 @@ if (!ob_get_level()) ob_start(); -
- +
+ -
+ Publier un article +
+ + Profil + +
👤
+ + +
+ + Connexion + Inscription + + +
diff --git a/forum-project/profile.php b/forum-project/profile.php index 840b155..f0b1c1a 100644 --- a/forum-project/profile.php +++ b/forum-project/profile.php @@ -1,59 +1,195 @@ 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)."; + $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(); } } - // update DB - $stmt = $pdo->prepare("UPDATE utilisateurs SET bio = ?, profile_picture = ? WHERE id = ?"); - $stmt->execute([$bio, $profilePath, $userId]); - // sync session - $_SESSION['user']['bio'] = $bio; - $_SESSION['user']['profile_picture'] = $profilePath; - header('Location: profile.php'); exit; + // 🧹 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]); + + $_SESSION['user']['bio'] = $bio; + $_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); -?> - - +$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 +} +?> + + + + + +Profil de <?= htmlspecialchars($user['username']) ?> + + + +
+

Profil de

+ + + Photo de profil + +
👤
+ + +

Rôle :

+ +
+ + + + + + +
+ + +
+
+ + +
+ + +

+ ⬅ Retour au tableau de bord +

+
+ + diff --git a/forum-project/profile_view.php b/forum-project/profile_view.php index f1d7d8a..35f8f2b 100644 --- a/forum-project/profile_view.php +++ b/forum-project/profile_view.php @@ -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); diff --git a/forum-project/register.php b/forum-project/register.php index 6e72477..fabaeef 100644 --- a/forum-project/register.php +++ b/forum-project/register.php @@ -1,26 +1,28 @@ 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 "

⚠️ Ce nom d'utilisateur existe déjà.

"; + 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 "

✅ Inscription réussie ! Vous pouvez maintenant vous connecter.

"; + $message = "⚠️ Tous les champs sont obligatoires."; } } ?> @@ -29,70 +31,58 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { -Inscription - Mini CMS +Créer un compte ✨
-

Créer un compte

+

Créer un compte ✨

+

+

-

Déjà un compte ? Se connecter

+

Déjà inscrit ? Connectez-vous

- - - diff --git a/forum-project/style.css b/forum-project/style.css index 0ea7e5e..9aa0c6f 100644 --- a/forum-project/style.css +++ b/forum-project/style.css @@ -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 d’articles */ + .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 l’auteur */ + .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; diff --git a/forum-project/test_minio_upload.php b/forum-project/test_minio_upload.php index d261ee4..4ba42f3 100644 --- a/forum-project/test_minio_upload.php +++ b/forum-project/test_minio_upload.php @@ -1,7 +1,7 @@