Initial commit

This commit is contained in:
Cedric Abonnel
2026-05-08 12:55:46 +02:00
commit 700329f156
46 changed files with 8495 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title><?= htmlspecialchars($title ?? 'varlog') ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- SEO -->
<meta name="description" content="Varlog est un journal personnel en ligne de Cédrix développé par ces soins. Informatique, hack et loisirs techniques.">
<meta name="robots" content="index, follow">
<!-- Open Graph -->
<meta property="og:title" content="<?= htmlspecialchars($title ?? 'varlog') ?>">
<meta property="og:description" content="Découvrez les derniers articles publiés sur le journal personnel varlog.">
<meta property="og:type" content="website">
<meta property="og:locale" content="fr_FR">
<meta property="og:url" content="https://varlog.a5l.fr/">
<meta property="og:site_name" content="varlog">
<!-- Favicon (si dispo) -->
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon">
<!-- CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body class="bg-light text-dark">
<header>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4" role="navigation" aria-label="Navigation principale">
<div class="container-fluid">
<a class="navbar-brand" href="route.php">📝 varlog</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Basculer la navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="route.php?action=create">Nouveau post</a></li>
</ul>
</div>
</div>
</nav>
</header>
<main class="container" role="main">
<?= $content ?>
</main>
<footer class="text-center text-muted py-4 mt-5 small" role="contentinfo">
&copy; <?= date('Y') ?> — <strong>varlog</strong> est un journal personnel développé par Cédrix
</footer>
<!-- JS Bootstrap (optionnel) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
+64
View File
@@ -0,0 +1,64 @@
<?php
ob_start();
// Valeur par défaut pour le champ datetime-local
$dateValue = $published_at ?? date('Y-m-d\TH:i');
?>
<h1 class="mb-4"><?= $action === 'edit' ? 'Modifier le post' : 'Créer un nouveau post' ?></h1>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<ul class="mb-0">
<?php foreach ($errors as $error): ?>
<li><?= htmlspecialchars($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form method="POST" action="<?= htmlspecialchars($formAction) ?>" enctype="multipart/form-data">
<div class="mb-3">
<label for="title" class="form-label">Titre</label>
<input type="text" class="form-control" id="title" name="title" required value="<?= htmlspecialchars($title) ?>">
</div>
<div class="mb-2">
<small class="text-muted">
Écris en <strong>Markdown</strong> <a href="https://www.markdownguide.org/cheat-sheet/" target="_blank">guide rapide</a>
</small>
</div>
<div class="mb-3">
<label for="content" class="form-label">Contenu</label>
<textarea class="form-control" id="content" name="content" rows="6"><?= htmlspecialchars($content) ?></textarea>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="published_at" class="form-label">Date de publication</label>
<input type="datetime-local" class="form-control" id="published_at" name="published_at" value="<?= $dateValue ?>">
</div>
<div class="col-md-6 d-flex align-items-end">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="published" name="published" <?= $published ? 'checked' : '' ?>>
<label class="form-check-label" for="published">Publié</label>
</div>
</div>
</div>
<div class="mb-3">
<label for="files" class="form-label">Fichiers</label>
<input type="file" class="form-control" id="files" name="files[]" multiple>
</div>
<button type="submit" class="btn btn-success">Enregistrer</button>
<a href="route.php" class="btn btn-secondary">Annuler</a>
</form>
<?php
$content = ob_get_clean();
$title = $action === 'edit' ? 'Modifier le post' : 'Nouveau post';
include __DIR__ . '/layout.php';
+46
View File
@@ -0,0 +1,46 @@
<?php
require_once BASE_PATH . '/src/Parsedown.php';
$Parsedown = new Parsedown();
ob_start();
?>
<h1 class="mb-4 text-center">📝 Tous les posts</h1>
<div class="row row-cols-1 row-cols-md-2 g-4">
<?php foreach ($posts as $post): ?>
<div class="col">
<div class="card shadow-sm h-100 border-<?php echo $post['is_published'] ? 'primary' : 'warning'; ?>">
<div class="card-body d-flex flex-column">
<h5 class="card-title text-primary">
<?= htmlspecialchars($post['title']) ?>
<?php if (!$post['is_published']): ?>
<span class="badge bg-warning text-dark ms-2">⏳ Brouillon</span>
<?php endif; ?>
</h5>
<div class="card-text text-body">
<?php
$html = $Parsedown->text($post['content']);
$preview = mb_strimwidth(strip_tags($html), 0, 300, '…');
echo '<p>' . $preview . '</p>';
?>
</div>
<p class="text-muted small mt-auto mb-2">📅 Publié le <?= date('d/m/Y', strtotime($post['created_at'])) ?></p>
<div class="d-flex justify-content-end gap-2">
<a href="route.php?action=view&id=<?= $post['id'] ?>" class="btn btn-sm btn-outline-primary">🔍 Voir</a>
<a href="route.php?action=edit&id=<?= $post['id'] ?>" class="btn btn-sm btn-outline-secondary">✏️ Modifier</a>
</div>
<a href="route.php?action=view&id=<?= $post['id'] ?>" class="stretched-link"></a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php
$content = ob_get_clean();
$title = "Liste des posts";
include __DIR__ . '/layout.php';
+70
View File
@@ -0,0 +1,70 @@
<?php
require_once __DIR__ . '/../src/Parsedown.php';
$Parsedown = new Parsedown();
ob_start();
?>
<a href="route.php" class="btn btn-secondary mb-3">← Retour</a>
<div class="card mb-4">
<div class="card-body">
<h2 class="card-title"><?= htmlspecialchars($post['title']) ?></h2>
<div class="card-text">
<?= $Parsedown->text($post['content']) ?>
</div>
<p class="text-muted small mt-2">Publié le <?= $post['created_at'] ?></p>
</div>
</div>
<?php
require_once __DIR__ . '/../src/FileManager.php';
$uploadDir = __DIR__ . '/../public/assets/uploads';
$publicDir = 'assets/uploads';
$fileManager = new FileManager($db, $uploadDir);
$files = $fileManager->getFilesForPost($post['id']);
?>
<?php if ($files): ?>
<h5>Fichiers attachés</h5>
<div class="row">
<?php foreach ($files as $file): ?>
<div class="col-md-4 mb-3">
<div class="card">
<div class="card-body">
<?php
$fileUrl = $publicDir . '/' . $file['file_path'];
$type = $file['file_type'];
?>
<?php if ($type === 'image'): ?>
<img src="<?= $fileUrl ?>" class="img-fluid" alt="<?= htmlspecialchars($file['original_name']) ?>">
<?php elseif ($type === 'video'): ?>
<video controls class="w-100">
<source src="<?= $fileUrl ?>" type="video/mp4">
</video>
<?php elseif ($type === 'audio'): ?>
<audio controls class="w-100">
<source src="<?= $fileUrl ?>" type="audio/mpeg">
</audio>
<?php else: ?>
<p><a href="<?= $fileUrl ?>" target="_blank">📎 <?= htmlspecialchars($file['original_name']) ?></a></p>
<?php endif; ?>
</div>
<div class="card-footer text-end">
<small class="text-muted">Ajouté le <?= $file['uploaded_at'] ?></small>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<a href="route.php?action=delete&id=<?= $post['id'] ?>" class="btn btn-danger mt-3" onclick="return confirm('Supprimer ce post ?')">Supprimer ce post</a>
<?php
$content = ob_get_clean();
$title = htmlspecialchars($post['title']);
include __DIR__ . '/layout.php';