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 '
Modules de documentation (pages HTML multipage). Le contenu n\'est pas lié au code : édition directe ici, puis poussé par la base.
'; if ($blnDev) { echo '| Titre | Clé | Programme | Pages | Actions |
|---|---|---|---|---|
| ' . fxDocAdminEsc($m['doc_mod_titre'] ?? '') . ' | '; echo '' . fxDocAdminEsc($strClef) . ' | ';
echo '' . fxDocAdminEsc($strPrg) . ' | '; echo '' . $intNb . ' | '; echo ''; echo ' Pages'; echo ' Éditer'; echo ' | '; echo '
' . fxDocAdminEsc($modClef) . ' · ' . fxDocAdminEsc($strPrg) . '| Tri | Clé | Titre FR | Titre EN |
|---|---|---|---|
| ' . (int)$page['tri'] . ' | '; echo '' . fxDocAdminEsc($page['clef']) . ' | ';
echo '' . fxDocAdminEsc($strTitreFr) . ' | '; echo '' . fxDocAdminEsc($strTitreEn) . ' | '; echo '
Le bouton « Éditer le module » ouvre toutes les pages dans l\'éditeur visuel.
'; }