feat #58 : wizard multi-étapes création/édition article #59
+1
-1
File diff suppressed because one or more lines are too long
+50
-14
@@ -544,7 +544,10 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ($draft === null) { header('Location: /new'); exit; }
|
||||
if ($draft === null) {
|
||||
header('Location: /new');
|
||||
exit;
|
||||
}
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$articles->updatePartialMeta($uuid, [
|
||||
'published' => isset($_POST['published']) && $_POST['published'] !== '',
|
||||
@@ -559,7 +562,10 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ($draft === null) { header('Location: /new'); exit; }
|
||||
if ($draft === null) {
|
||||
header('Location: /new');
|
||||
exit;
|
||||
}
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$articles->updatePartialMeta($uuid, ['category' => trim($_POST['category'] ?? '')]);
|
||||
header('Location: /new/' . rawurlencode($uuid) . '/4');
|
||||
@@ -572,7 +578,10 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if ($draft === null) { header('Location: /new'); exit; }
|
||||
if ($draft === null) {
|
||||
header('Location: /new');
|
||||
exit;
|
||||
}
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$_vals = array_values(array_filter(array_map('trim', explode(',', (string)($_POST['tags_flat'] ?? ''))), fn ($_v) => $_v !== ''));
|
||||
$articles->updatePartialMeta($uuid, ['tags' => $_vals !== [] ? ['tags' => $_vals] : []]);
|
||||
@@ -582,14 +591,22 @@ switch ($action) {
|
||||
$_tagTypes = $articles->getTagTypes();
|
||||
$flatTagValues = [];
|
||||
foreach ($_tagTypes as $_tk => $_) {
|
||||
foreach ($articles->getAllTagValues($_tk) as $_v) { $flatTagValues[$_v] = true; }
|
||||
foreach ($articles->getAllTagValues($_tk) as $_v) {
|
||||
$flatTagValues[$_v] = true;
|
||||
}
|
||||
}
|
||||
foreach ($articles->getAllTagValues('tags') as $_v) {
|
||||
$flatTagValues[$_v] = true;
|
||||
}
|
||||
foreach ($articles->getAllTagValues('tags') as $_v) { $flatTagValues[$_v] = true; }
|
||||
ksort($flatTagValues);
|
||||
$flatTagValues = array_keys($flatTagValues);
|
||||
$flatArticleTags = [];
|
||||
foreach (($draft['tags'] ?? []) as $_tagVals) {
|
||||
foreach ((array)$_tagVals as $_v) { if (!in_array($_v, $flatArticleTags, true)) $flatArticleTags[] = $_v; }
|
||||
foreach ((array)$_tagVals as $_v) {
|
||||
if (!in_array($_v, $flatArticleTags, true)) {
|
||||
$flatArticleTags[] = $_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
$draftContent = (string)($draft['content'] ?? '');
|
||||
require_once BASE_PATH . '/src/TagSuggester.php';
|
||||
@@ -597,7 +614,10 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if ($draft === null) { header('Location: /new'); exit; }
|
||||
if ($draft === null) {
|
||||
header('Location: /new');
|
||||
exit;
|
||||
}
|
||||
require_once BASE_PATH . '/src/Parsedown.php';
|
||||
$_pd = new Parsedown();
|
||||
$autoSeoDesc = mb_strimwidth(trim((string)preg_replace('/\s+/', ' ', strip_tags($_pd->text((string)($draft['content'] ?? ''))))), 0, 155, '…');
|
||||
@@ -903,14 +923,22 @@ switch ($action) {
|
||||
$_tagTypes = $articles->getTagTypes();
|
||||
$flatTagValues = [];
|
||||
foreach ($_tagTypes as $_tk => $_) {
|
||||
foreach ($articles->getAllTagValues($_tk) as $_v) { $flatTagValues[$_v] = true; }
|
||||
foreach ($articles->getAllTagValues($_tk) as $_v) {
|
||||
$flatTagValues[$_v] = true;
|
||||
}
|
||||
}
|
||||
foreach ($articles->getAllTagValues('tags') as $_v) {
|
||||
$flatTagValues[$_v] = true;
|
||||
}
|
||||
foreach ($articles->getAllTagValues('tags') as $_v) { $flatTagValues[$_v] = true; }
|
||||
ksort($flatTagValues);
|
||||
$flatTagValues = array_keys($flatTagValues);
|
||||
$flatArticleTags = [];
|
||||
foreach (($draft['tags'] ?? []) as $_tagVals) {
|
||||
foreach ((array)$_tagVals as $_v) { if (!in_array($_v, $flatArticleTags, true)) $flatArticleTags[] = $_v; }
|
||||
foreach ((array)$_tagVals as $_v) {
|
||||
if (!in_array($_v, $flatArticleTags, true)) {
|
||||
$flatArticleTags[] = $_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
$draftContent = (string)($draft['content'] ?? '');
|
||||
require_once BASE_PATH . '/src/TagSuggester.php';
|
||||
@@ -962,10 +990,18 @@ switch ($action) {
|
||||
$autoSlug = slugify($draftData['title'] ?? '');
|
||||
$postSlug = $draftData['slug'] ?? $article['slug'];
|
||||
$changes = [];
|
||||
if ($titleChanged) { $changes[] = 'titre modifié'; }
|
||||
if (($draftData['category'] ?? '') !== ($article['category'] ?? '')) { $changes[] = 'catégorie modifiée'; }
|
||||
if (($draftData['tags'] ?? []) !== ($article['tags'] ?? [])) { $changes[] = 'tags modifiés'; }
|
||||
if (($draftData['content'] ?? '') !== ($article['content'] ?? '')) { $changes[] = 'contenu modifié'; }
|
||||
if ($titleChanged) {
|
||||
$changes[] = 'titre modifié';
|
||||
}
|
||||
if (($draftData['category'] ?? '') !== ($article['category'] ?? '')) {
|
||||
$changes[] = 'catégorie modifiée';
|
||||
}
|
||||
if (($draftData['tags'] ?? []) !== ($article['tags'] ?? [])) {
|
||||
$changes[] = 'tags modifiés';
|
||||
}
|
||||
if (($draftData['content'] ?? '') !== ($article['content'] ?? '')) {
|
||||
$changes[] = 'contenu modifié';
|
||||
}
|
||||
if ((bool)($draftData['published'] ?? false) !== (bool)($article['published'] ?? false)) {
|
||||
$changes[] = ($draftData['published'] ?? false) ? 'article publié' : 'article dépublié';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ $_base = $mode === 'create' ? '/new/' . rawurlencode($uuid ?? '') : '/edit/' . r
|
||||
$_wActive = ($_wn === $step);
|
||||
$_wDone = ($_wn < $step);
|
||||
$_wHref = ($_wDone && ($uuid ?? '') !== '') ? htmlspecialchars($_base . '/' . $_wn) : null;
|
||||
?>
|
||||
?>
|
||||
<?php if ($_wi > 0): ?>
|
||||
<span class="wizard-sep text-muted px-1">›</span>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -92,7 +92,7 @@ $_hasUuid = $_wizUuid !== '';
|
||||
<?php foreach ($existingFiles as $_fi => $_f):
|
||||
$_fUrl = '/file?uuid=' . rawurlencode($_wizUuid) . '&name=' . rawurlencode($_f['name']);
|
||||
$_isCover = ($_f['name'] === $_coverFile);
|
||||
?>
|
||||
?>
|
||||
<div class="border rounded p-1 d-flex align-items-center gap-2" style="max-width:220px">
|
||||
<?php if ($_f['is_image']): ?>
|
||||
<img src="<?= htmlspecialchars($_fUrl) ?>" alt="" style="width:36px;height:36px;object-fit:cover;border-radius:3px;flex-shrink:0<?= $_isCover ? ';outline:2px solid #0d6efd' : '' ?>">
|
||||
@@ -129,7 +129,7 @@ $_hasUuid = $_wizUuid !== '';
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($_sidebarImgs as $_img):
|
||||
$_iUrl = '/file?uuid=' . rawurlencode($_wizUuid) . '&name=' . rawurlencode($_img['name']);
|
||||
?>
|
||||
?>
|
||||
<img src="<?= htmlspecialchars($_iUrl) ?>"
|
||||
alt="<?= htmlspecialchars($_img['name']) ?>"
|
||||
title="<?= htmlspecialchars($_img['name']) ?>"
|
||||
|
||||
@@ -39,7 +39,7 @@ $_formAction = $mode === 'create' ? '/new/' . rawurlencode($uuid) . '/3' : '/edi
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($allCategories as $_cat => $_count):
|
||||
$_isPriv = in_array($_cat, $privateCats ?? [], true);
|
||||
?>
|
||||
?>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary wz-cat-pick<?= ($_cat === ($category ?? '')) ? ' active' : '' ?>"
|
||||
data-cat="<?= htmlspecialchars($_cat) ?>">
|
||||
<?= htmlspecialchars($_cat) ?>
|
||||
|
||||
@@ -53,7 +53,7 @@ $_detectedInText = array_keys(array_filter($_candidates, fn ($_c) => !$_c['known
|
||||
<?php foreach ($flatTagValues as $_v):
|
||||
$_isActive = in_array($_v, $flatArticleTags, true);
|
||||
$_inText = in_array($_v, $_knownInText, true);
|
||||
?>
|
||||
?>
|
||||
<button type="button"
|
||||
class="btn btn-sm <?= $_isActive ? 'btn-secondary' : 'btn-outline-secondary' ?> wz-tag-pill py-0"
|
||||
data-value="<?= htmlspecialchars($_v) ?>"
|
||||
@@ -80,7 +80,7 @@ $_detectedInText = array_keys(array_filter($_candidates, fn ($_c) => !$_c['known
|
||||
'proper' => 'NP',
|
||||
default => '',
|
||||
};
|
||||
?>
|
||||
?>
|
||||
<button type="button"
|
||||
class="btn btn-sm <?= $_isActive ? 'btn-info' : 'btn-outline-info' ?> wz-tag-pill py-0"
|
||||
data-value="<?= htmlspecialchars($_v) ?>"
|
||||
|
||||
@@ -106,7 +106,7 @@ $_catVal = trim($category ?? '');
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($_imgFiles as $_f):
|
||||
$_fUrl = '/file?uuid=' . rawurlencode($uuid) . '&name=' . rawurlencode($_f['name']);
|
||||
?>
|
||||
?>
|
||||
<label class="position-relative" style="cursor:pointer">
|
||||
<input type="radio" name="cover_file" value="<?= htmlspecialchars($_f['name']) ?>"
|
||||
class="position-absolute" style="opacity:0" <?= ($_f['name'] === $_coverFile) ? 'checked' : '' ?>>
|
||||
|
||||
@@ -60,7 +60,7 @@ $_slugFinal = ($titleChanged && $autoSlug !== $postSlug) ? $autoSlug : $postSlu
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
?>
|
||||
<div class="d-flex gap-3 mb-1 small">
|
||||
<span class="diff-del px-2 py-1 rounded">− Supprimé</span>
|
||||
<span class="diff-ins px-2 py-1 rounded">+ Ajouté</span>
|
||||
@@ -69,11 +69,12 @@ $_slugFinal = ($titleChanged && $autoSlug !== $postSlug) ? $autoSlug : $postSlu
|
||||
<?php $inEllipsis = false;
|
||||
for ($i = 0; $i < $total; $i++):
|
||||
[$op, $line] = $diffLines[$i];
|
||||
?>
|
||||
?>
|
||||
<?php if (!isset($show[$i])): ?>
|
||||
<?php if (!$inEllipsis): $inEllipsis = true; ?>
|
||||
<div class="diff-ellipsis text-muted px-2">⋯</div>
|
||||
<?php endif; continue; ?>
|
||||
<?php endif;
|
||||
continue; ?>
|
||||
<?php else: $inEllipsis = false; endif; ?>
|
||||
<?php if ($op === '-'): ?>
|
||||
<div class="diff-del px-2">− <?= htmlspecialchars($line) ?></div>
|
||||
|
||||
Reference in New Issue
Block a user