Add documentation section to inc_droite.php with navigation links
This commit is contained in:
92
superadm/documentation.php
Normal file
92
superadm/documentation.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
$strLangue = 'fr';
|
||||
$strPage = 'documentation.php';
|
||||
$strAction = $_GET['p'] ?? 'list';
|
||||
|
||||
require_once('php/inc_start_time.php');
|
||||
require_once('php/inc_functions.php');
|
||||
require_once('php/inc_fx_doc_admin.php');
|
||||
|
||||
global $objDatabase, $vDomaine, $vblnEnvironementDev, $vblnEnvironementPreProd;
|
||||
|
||||
if (empty($_SESSION['usa_id'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$strFlash = '';
|
||||
$strError = '';
|
||||
$strModClef = isset($_GET['mod']) ? preg_replace('/[^a-z0-9_]/i', '', $_GET['mod']) : '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!fxDocAdminIsDevPreprod()) {
|
||||
$strError = 'La création est réservée aux environnements dev/préprod.';
|
||||
} else {
|
||||
$strPostAction = $_POST['action'] ?? '';
|
||||
|
||||
if ($strPostAction === 'addmodule') {
|
||||
$arrResult = fxDocAdminCreateModule(
|
||||
$_POST['doc_mod_clef'] ?? '',
|
||||
$_POST['doc_mod_titre'] ?? '',
|
||||
$_POST['doc_mod_prg'] ?? 'compte.php'
|
||||
);
|
||||
if ($arrResult['state'] === 'ok') {
|
||||
header('Location: documentation.php?p=pages&mod=' . urlencode($arrResult['mod']) . '&ok=1');
|
||||
exit;
|
||||
}
|
||||
$strError = $arrResult['message'];
|
||||
} elseif ($strPostAction === 'addpage') {
|
||||
$arrResult = fxDocAdminCreatePage(
|
||||
$_POST['mod'] ?? '',
|
||||
$_POST['doc_page_clef'] ?? '',
|
||||
$_POST['doc_prg'] ?? 'compte.php'
|
||||
);
|
||||
if ($arrResult['state'] === 'ok') {
|
||||
header('Location: ' . fxDocAdminEditUrl($arrResult['mod'], $arrResult['prg']));
|
||||
exit;
|
||||
}
|
||||
$strError = $arrResult['message'];
|
||||
$strAction = 'pages';
|
||||
$strModClef = preg_replace('/[^a-z0-9_]/i', '', $_POST['mod'] ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_GET['ok'])) {
|
||||
$strFlash = 'Enregistré.';
|
||||
}
|
||||
|
||||
include('inc_header.php');
|
||||
?>
|
||||
<div class="container-fluid" id="main">
|
||||
<div class="row">
|
||||
<div class="col-md-9 col-lg-10 order-first order-md-last py-3">
|
||||
<?php
|
||||
if ($strFlash !== '' && $strError === '') {
|
||||
echo '<div class="alert alert-success">' . fxDocAdminEsc($strFlash) . '</div>';
|
||||
}
|
||||
if ($strError !== '') {
|
||||
echo '<div class="alert alert-danger">' . fxDocAdminEsc($strError) . '</div>';
|
||||
}
|
||||
|
||||
if (!fxDocAdminSchemaReady()) {
|
||||
echo '<div class="alert alert-warning">Les tables de documentation (doc_mod / doc_page) ne sont pas installées sur cet environnement.</div>';
|
||||
} else {
|
||||
switch ($strAction) {
|
||||
case 'pages':
|
||||
fxDocAdminRenderPages($strModClef);
|
||||
break;
|
||||
case 'list':
|
||||
default:
|
||||
fxDocAdminRenderModulesList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<p> </p>
|
||||
</div>
|
||||
<?php require_once('inc_droite.php'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php require_once('inc_footer.php'); ?>
|
||||
@ -94,6 +94,19 @@ global $db, $objDatabase, $vblnEnvironementDev, $vDomaine, $vblnEnvironementPreP
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4><span>Documentation</span> & Nouveautés</h4>
|
||||
<?php
|
||||
$blnDocActive = (basename($_SERVER['SCRIPT_NAME'] ?? '') === 'documentation.php');
|
||||
?>
|
||||
<ul class="nav nav-pills flex-column">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link<?php if ($blnDocActive) { ?> active<?php } ?>"
|
||||
href="<?php echo $vDomaine; ?>/superadm/documentation.php">
|
||||
<i class="fa fa-book" aria-hidden="true"></i> Pages & modules
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4><span>Rapports</span> particuliers</h4>
|
||||
<?php
|
||||
$tabMenus = fxGetMenussuperadm(0, 0, 1);
|
||||
|
||||
337
superadm/php/inc_fx_doc_admin.php
Normal file
337
superadm/php/inc_fx_doc_admin.php
Normal file
@ -0,0 +1,337 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Admin documentation (doc_mod / doc_page / doc_anchor) — super admin.
|
||||
* Lister, creer modules et pages ; edition via /php/doc_edition.php (Trumbowyg).
|
||||
* Creation reservee dev/preprod (le contenu est ensuite pousse par la base).
|
||||
*/
|
||||
|
||||
function fxDocAdminEsc($str)
|
||||
{
|
||||
return htmlspecialchars((string)$str, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
function fxDocAdminIsDevPreprod()
|
||||
{
|
||||
global $vblnEnvironementDev, $vblnEnvironementPreProd;
|
||||
|
||||
return !empty($vblnEnvironementDev) || !empty($vblnEnvironementPreProd);
|
||||
}
|
||||
|
||||
function fxDocAdminSchemaReady()
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
static $blnReady = null;
|
||||
|
||||
if ($blnReady !== null) {
|
||||
return $blnReady;
|
||||
}
|
||||
|
||||
if (!isset($objDatabase)) {
|
||||
$blnReady = false;
|
||||
return $blnReady;
|
||||
}
|
||||
|
||||
$qry = $objDatabase->fxQuery("SHOW TABLES LIKE 'doc_page'");
|
||||
$blnReady = ($qry && mysqli_num_rows($qry) > 0);
|
||||
|
||||
return $blnReady;
|
||||
}
|
||||
|
||||
function fxDocAdminEditUrl($modClef, $prg)
|
||||
{
|
||||
global $vDomaine;
|
||||
|
||||
$prg = ($prg !== '') ? $prg : 'compte.php';
|
||||
|
||||
return $vDomaine . '/php/doc_edition.php?' . http_build_query(array(
|
||||
'mod' => $modClef,
|
||||
'anchor' => $modClef,
|
||||
'prg' => $prg,
|
||||
'bd' => 'client',
|
||||
'page' => 'compte.php',
|
||||
));
|
||||
}
|
||||
|
||||
function fxDocAdminListModules()
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
if (!fxDocAdminSchemaReady()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sql = "SELECT m.pk_doc_mod, m.doc_mod_clef, m.doc_mod_prg, m.doc_mod_titre, m.doc_mod_actif,
|
||||
(SELECT COUNT(DISTINCT p.doc_page_clef)
|
||||
FROM doc_page p
|
||||
WHERE p.doc_mod_clef = m.doc_mod_clef) AS nb_pages
|
||||
FROM doc_mod m
|
||||
ORDER BY m.doc_mod_tri, m.doc_mod_titre";
|
||||
|
||||
$rows = $objDatabase->fxGetResults($sql);
|
||||
|
||||
return is_array($rows) ? $rows : array();
|
||||
}
|
||||
|
||||
function fxDocAdminGetModule($modClef)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
if (!fxDocAdminSchemaReady() || trim($modClef) === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $objDatabase->fxGetRow(
|
||||
"SELECT * FROM doc_mod WHERE doc_mod_clef = '" . $objDatabase->fxEscape($modClef) . "' LIMIT 1"
|
||||
);
|
||||
}
|
||||
|
||||
function fxDocAdminListPages($modClef)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
if (!fxDocAdminSchemaReady() || trim($modClef) === '') {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM doc_page
|
||||
WHERE doc_mod_clef = '" . $objDatabase->fxEscape($modClef) . "'
|
||||
ORDER BY doc_tri, doc_page_clef, doc_langue DESC";
|
||||
|
||||
$rows = $objDatabase->fxGetResults($sql);
|
||||
$grouped = array();
|
||||
|
||||
if (is_array($rows)) {
|
||||
for ($i = 1; $i <= count($rows); $i++) {
|
||||
$r = $rows[$i];
|
||||
$clef = $r['doc_page_clef'] ?? '';
|
||||
if ($clef === '') {
|
||||
continue;
|
||||
}
|
||||
if (!isset($grouped[$clef])) {
|
||||
$grouped[$clef] = array(
|
||||
'clef' => $clef,
|
||||
'tri' => (int)($r['doc_tri'] ?? 0),
|
||||
'prg' => $r['doc_prg'] ?? 'compte.php',
|
||||
'fr' => null,
|
||||
'en' => null,
|
||||
);
|
||||
}
|
||||
$lng = $r['doc_langue'] ?? 'fr';
|
||||
if ($lng === 'fr' || $lng === 'en') {
|
||||
$grouped[$clef][$lng] = $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
function fxDocAdminCreateModule($clef, $titre, $prg)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
$clef = trim($clef);
|
||||
$prg = (trim($prg) !== '') ? trim($prg) : 'compte.php';
|
||||
|
||||
if ($clef === '') {
|
||||
return array('state' => 'error', 'message' => 'Clé du module requise.');
|
||||
}
|
||||
if (!preg_match('/^[a-z0-9_]+$/i', $clef)) {
|
||||
return array('state' => 'error', 'message' => 'Clé invalide (lettres, chiffres, underscore seulement).');
|
||||
}
|
||||
if (!fxDocAdminSchemaReady()) {
|
||||
return array('state' => 'error', 'message' => 'Tables de documentation absentes.');
|
||||
}
|
||||
|
||||
$intExists = (int)$objDatabase->fxGetVar(
|
||||
"SELECT COUNT(*) FROM doc_mod
|
||||
WHERE doc_mod_clef = '" . $objDatabase->fxEscape($clef) . "'
|
||||
AND doc_mod_prg = '" . $objDatabase->fxEscape($prg) . "'"
|
||||
);
|
||||
if ($intExists > 0) {
|
||||
return array('state' => 'error', 'message' => 'Ce module existe déjà.');
|
||||
}
|
||||
|
||||
$objDatabase->fxQuery(
|
||||
"INSERT INTO doc_mod (doc_mod_clef, doc_mod_prg, doc_mod_titre, doc_mod_actif, doc_mod_tri, doc_mod_creation)
|
||||
VALUES ('" . $objDatabase->fxEscape($clef) . "', '" . $objDatabase->fxEscape($prg) . "', '" . $objDatabase->fxEscape($titre) . "', 1, 0, NOW())"
|
||||
);
|
||||
|
||||
$intAnchor = (int)$objDatabase->fxGetVar(
|
||||
"SELECT COUNT(*) FROM doc_anchor
|
||||
WHERE doc_anchor_clef = '" . $objDatabase->fxEscape($clef) . "'
|
||||
AND doc_prg = '" . $objDatabase->fxEscape($prg) . "'"
|
||||
);
|
||||
if ($intAnchor === 0) {
|
||||
$objDatabase->fxQuery(
|
||||
"INSERT INTO doc_anchor (doc_anchor_clef, doc_mod_clef, doc_prg, doc_actif, doc_creation)
|
||||
VALUES ('" . $objDatabase->fxEscape($clef) . "', '" . $objDatabase->fxEscape($clef) . "', '" . $objDatabase->fxEscape($prg) . "', 1, NOW())"
|
||||
);
|
||||
}
|
||||
|
||||
return array('state' => 'ok', 'mod' => $clef, 'prg' => $prg);
|
||||
}
|
||||
|
||||
function fxDocAdminCreatePage($modClef, $pageClef, $prg)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
$modClef = trim($modClef);
|
||||
$pageClef = trim($pageClef);
|
||||
$prg = (trim($prg) !== '') ? trim($prg) : 'compte.php';
|
||||
|
||||
if ($modClef === '' || $pageClef === '') {
|
||||
return array('state' => 'error', 'message' => 'Clé du module et clé de page requises.');
|
||||
}
|
||||
if (!preg_match('/^[a-z0-9_]+$/i', $pageClef)) {
|
||||
return array('state' => 'error', 'message' => 'Clé de page invalide (lettres, chiffres, underscore seulement).');
|
||||
}
|
||||
if (!fxDocAdminSchemaReady()) {
|
||||
return array('state' => 'error', 'message' => 'Tables de documentation absentes.');
|
||||
}
|
||||
|
||||
$intExists = (int)$objDatabase->fxGetVar(
|
||||
"SELECT COUNT(*) FROM doc_page
|
||||
WHERE doc_page_clef = '" . $objDatabase->fxEscape($pageClef) . "'
|
||||
AND doc_prg = '" . $objDatabase->fxEscape($prg) . "'"
|
||||
);
|
||||
if ($intExists > 0) {
|
||||
return array('state' => 'error', 'message' => 'Cette page existe déjà.');
|
||||
}
|
||||
|
||||
$intTri = (int)$objDatabase->fxGetVar(
|
||||
"SELECT COALESCE(MAX(doc_tri), 0) + 10 FROM doc_page
|
||||
WHERE doc_mod_clef = '" . $objDatabase->fxEscape($modClef) . "'"
|
||||
);
|
||||
|
||||
foreach (array('fr', 'en') as $lng) {
|
||||
$objDatabase->fxQuery(
|
||||
"INSERT INTO doc_page (doc_mod_clef, doc_page_clef, doc_langue, doc_titre, doc_sous_titre, doc_html, doc_prg, doc_tri, doc_actif, doc_creation)
|
||||
VALUES ('" . $objDatabase->fxEscape($modClef) . "', '" . $objDatabase->fxEscape($pageClef) . "', '" . $lng . "', '', '', '', '" . $objDatabase->fxEscape($prg) . "', " . $intTri . ", 1, NOW())"
|
||||
);
|
||||
}
|
||||
|
||||
return array('state' => 'ok', 'mod' => $modClef, 'page' => $pageClef, 'prg' => $prg);
|
||||
}
|
||||
|
||||
/** Liste des modules + formulaire de creation. */
|
||||
function fxDocAdminRenderModulesList()
|
||||
{
|
||||
global $vDomaine;
|
||||
|
||||
$arrModules = fxDocAdminListModules();
|
||||
$blnDev = fxDocAdminIsDevPreprod();
|
||||
|
||||
echo '<div class="d-flex align-items-center justify-content-between mb-3">';
|
||||
echo '<h1 class="h3 mb-0">Documentation & Nouveautés</h1>';
|
||||
echo '</div>';
|
||||
echo '<p class="text-muted">Modules de documentation (pages HTML multipage). Le contenu n\'est pas lié au code : édition directe ici, puis poussé par la base.</p>';
|
||||
|
||||
if ($blnDev) {
|
||||
echo '<div class="card mb-4">';
|
||||
echo '<div class="card-header"><i class="fa fa-plus mr-2" aria-hidden="true"></i>Créer un module</div>';
|
||||
echo '<div class="card-body">';
|
||||
echo '<form method="post" action="documentation.php" class="form-row align-items-end">';
|
||||
echo '<input type="hidden" name="action" value="addmodule">';
|
||||
echo '<div class="form-group col-md-3"><label>Clé du module</label><input type="text" name="doc_mod_clef" class="form-control" placeholder="ex. promoteur_hub_annonces" required></div>';
|
||||
echo '<div class="form-group col-md-4"><label>Titre</label><input type="text" name="doc_mod_titre" class="form-control" placeholder="ex. Nouveautés MS1"></div>';
|
||||
echo '<div class="form-group col-md-3"><label>Programme (doc_prg)</label><input type="text" name="doc_mod_prg" class="form-control" value="compte.php"></div>';
|
||||
echo '<div class="form-group col-md-2"><button type="submit" class="btn btn-primary btn-block">Créer</button></div>';
|
||||
echo '</form>';
|
||||
echo '</div></div>';
|
||||
} else {
|
||||
echo '<div class="alert alert-info">La création de modules/pages est réservée aux environnements dev/préprod.</div>';
|
||||
}
|
||||
|
||||
if (empty($arrModules)) {
|
||||
echo '<div class="alert alert-warning">Aucun module de documentation.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<table class="table table-striped table-hover">';
|
||||
echo '<thead><tr><th>Titre</th><th>Clé</th><th>Programme</th><th class="text-center">Pages</th><th class="text-right">Actions</th></tr></thead><tbody>';
|
||||
|
||||
for ($i = 1; $i <= count($arrModules); $i++) {
|
||||
$m = $arrModules[$i];
|
||||
$strClef = $m['doc_mod_clef'] ?? '';
|
||||
$strPrg = $m['doc_mod_prg'] ?? 'compte.php';
|
||||
$intNb = (int)($m['nb_pages'] ?? 0);
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td>' . fxDocAdminEsc($m['doc_mod_titre'] ?? '') . '</td>';
|
||||
echo '<td><code>' . fxDocAdminEsc($strClef) . '</code></td>';
|
||||
echo '<td>' . fxDocAdminEsc($strPrg) . '</td>';
|
||||
echo '<td class="text-center">' . $intNb . '</td>';
|
||||
echo '<td class="text-right">';
|
||||
echo '<a class="btn btn-sm btn-outline-secondary mr-1" href="documentation.php?p=pages&mod=' . urlencode($strClef) . '"><i class="fa fa-list" aria-hidden="true"></i> Pages</a>';
|
||||
echo '<a class="btn btn-sm btn-primary" href="' . fxDocAdminEsc(fxDocAdminEditUrl($strClef, $strPrg)) . '" target="_blank"><i class="fa fa-pencil" aria-hidden="true"></i> Éditer</a>';
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody></table>';
|
||||
}
|
||||
|
||||
/** Liste des pages d'un module + formulaire d'ajout de page. */
|
||||
function fxDocAdminRenderPages($modClef)
|
||||
{
|
||||
$modClef = trim($modClef);
|
||||
$arrMod = fxDocAdminGetModule($modClef);
|
||||
|
||||
if ($arrMod === null) {
|
||||
echo '<div class="alert alert-danger">Module introuvable.</div>';
|
||||
echo '<a class="btn btn-outline-secondary" href="documentation.php"><i class="fa fa-chevron-left" aria-hidden="true"></i> Retour</a>';
|
||||
return;
|
||||
}
|
||||
|
||||
$strPrg = $arrMod['doc_mod_prg'] ?? 'compte.php';
|
||||
$arrPages = fxDocAdminListPages($modClef);
|
||||
$blnDev = fxDocAdminIsDevPreprod();
|
||||
|
||||
echo '<div class="d-flex align-items-center justify-content-between mb-3">';
|
||||
echo '<div><a class="btn btn-sm btn-outline-secondary mb-2" href="documentation.php"><i class="fa fa-chevron-left" aria-hidden="true"></i> Tous les modules</a>';
|
||||
echo '<h1 class="h3 mb-0">' . fxDocAdminEsc($arrMod['doc_mod_titre'] ?? $modClef) . '</h1>';
|
||||
echo '<div class="text-muted"><code>' . fxDocAdminEsc($modClef) . '</code> · ' . fxDocAdminEsc($strPrg) . '</div></div>';
|
||||
echo '<a class="btn btn-primary" href="' . fxDocAdminEsc(fxDocAdminEditUrl($modClef, $strPrg)) . '" target="_blank"><i class="fa fa-pencil" aria-hidden="true"></i> Éditer le module</a>';
|
||||
echo '</div>';
|
||||
|
||||
if ($blnDev) {
|
||||
echo '<div class="card mb-4">';
|
||||
echo '<div class="card-header"><i class="fa fa-plus mr-2" aria-hidden="true"></i>Ajouter une page</div>';
|
||||
echo '<div class="card-body">';
|
||||
echo '<form method="post" action="documentation.php" class="form-row align-items-end">';
|
||||
echo '<input type="hidden" name="action" value="addpage">';
|
||||
echo '<input type="hidden" name="mod" value="' . fxDocAdminEsc($modClef) . '">';
|
||||
echo '<input type="hidden" name="doc_prg" value="' . fxDocAdminEsc($strPrg) . '">';
|
||||
echo '<div class="form-group col-md-6"><label>Clé de la nouvelle page</label><input type="text" name="doc_page_clef" class="form-control" placeholder="ex. annonce_v4_73" required></div>';
|
||||
echo '<div class="form-group col-md-3"><button type="submit" class="btn btn-primary btn-block">Créer et éditer</button></div>';
|
||||
echo '</form>';
|
||||
echo '<small class="text-muted">La page (FR + EN) est créée vide, puis l\'éditeur s\'ouvre.</small>';
|
||||
echo '</div></div>';
|
||||
}
|
||||
|
||||
if (empty($arrPages)) {
|
||||
echo '<div class="alert alert-warning">Aucune page dans ce module.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<table class="table table-striped">';
|
||||
echo '<thead><tr><th class="text-center">Tri</th><th>Clé</th><th>Titre FR</th><th>Titre EN</th></tr></thead><tbody>';
|
||||
|
||||
foreach ($arrPages as $page) {
|
||||
$strTitreFr = isset($page['fr']['doc_titre']) ? $page['fr']['doc_titre'] : '';
|
||||
$strTitreEn = isset($page['en']['doc_titre']) ? $page['en']['doc_titre'] : '';
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td class="text-center">' . (int)$page['tri'] . '</td>';
|
||||
echo '<td><code>' . fxDocAdminEsc($page['clef']) . '</code></td>';
|
||||
echo '<td>' . fxDocAdminEsc($strTitreFr) . '</td>';
|
||||
echo '<td>' . fxDocAdminEsc($strTitreEn) . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody></table>';
|
||||
echo '<p class="text-muted"><i class="fa fa-info-circle" aria-hidden="true"></i> Le bouton « Éditer le module » ouvre toutes les pages dans l\'éditeur visuel.</p>';
|
||||
}
|
||||
Reference in New Issue
Block a user