fxQuery("SHOW TABLES LIKE 'doc_page'");
$blnReady = ($qry && mysqli_num_rows($qry) > 0);
return $blnReady;
}
/**
* Charge en mémoire toutes les pages doc pour une page PHP (comme obtenirTextepage).
* Remplit $vdoc_page[doc_page_clef] = row.
*/
function obtenirDocPage($page = null, $langue = null) {
global $objDatabase, $vdoc_page;
if ($page === null || $page === '') {
$page = fxDocPrg(0);
}
if ($langue === null || $langue === '') {
$langue = fxDocLangue();
}
$vdoc_page = array();
if (!isset($objDatabase) || !fxDocSchemaReady()) {
return $vdoc_page;
}
$sql = "SELECT *
FROM doc_page
WHERE doc_actif = 1
AND doc_langue = '" . $objDatabase->fxEscape($langue) . "'
AND doc_prg IN ('" . $objDatabase->fxEscape($page) . "', 'global')
ORDER BY doc_tri, pk_doc_page";
$rows = $objDatabase->fxGetResults($sql);
if (!is_array($rows)) {
return $vdoc_page;
}
for ($i = 1; $i <= count($rows); $i++) {
if (!empty($rows[$i]['doc_page_clef'])) {
$vdoc_page[$rows[$i]['doc_page_clef']] = $rows[$i];
}
}
return $vdoc_page;
}
/** Ligne doc_anchor par clé d'appel. */
function fxDocGetAnchorRow($clef, $mem_global = 0) {
global $objDatabase;
static $anchorCache = array();
$strPrg = fxDocPrg($mem_global);
$cacheKey = $clef . '|' . $strPrg;
if (array_key_exists($cacheKey, $anchorCache)) {
return $anchorCache[$cacheKey];
}
if (!isset($objDatabase) || $clef === '' || !fxDocSchemaReady()) {
$anchorCache[$cacheKey] = array();
return $anchorCache[$cacheKey];
}
$sql = "SELECT *
FROM doc_anchor
WHERE doc_actif = 1
AND doc_anchor_clef = '" . $objDatabase->fxEscape($clef) . "'
AND doc_prg IN ('" . $objDatabase->fxEscape($strPrg) . "', 'global')
ORDER BY FIELD(doc_prg, '" . $objDatabase->fxEscape($strPrg) . "', 'global')
LIMIT 1";
$row = $objDatabase->fxGetRow($sql);
$anchorCache[$cacheKey] = is_array($row) ? $row : array();
return $anchorCache[$cacheKey];
}
/** Résout doc_mod_clef depuis une clé d'ancre ou un code module direct. */
function fxDocResolveModClef($clef, $mem_global = 0) {
$anchor = fxDocGetAnchorRow($clef, $mem_global);
if (!empty($anchor['doc_mod_clef'])) {
return $anchor['doc_mod_clef'];
}
return $clef;
}
/** Pages actives d'un module, triées (pour carrousel overlay). */
function fxDocGetModulePages($modClef, $langue = null, $mem_global = 0) {
global $objDatabase, $vdoc_page;
if ($langue === null || $langue === '') {
$langue = fxDocLangue();
}
$strPrg = fxDocPrg($mem_global);
$modClef = fxDocResolveModClef($modClef, $mem_global);
if (!isset($objDatabase) || $modClef === '' || !fxDocSchemaReady()) {
return array();
}
$sql = "SELECT *
FROM doc_page
WHERE doc_actif = 1
AND doc_mod_clef = '" . $objDatabase->fxEscape($modClef) . "'
AND doc_langue = '" . $objDatabase->fxEscape($langue) . "'
AND doc_prg IN ('" . $objDatabase->fxEscape($strPrg) . "', 'global')
ORDER BY doc_tri, pk_doc_page";
$rows = $objDatabase->fxGetResults($sql);
$pages = array();
if (!is_array($rows)) {
return $pages;
}
for ($i = 1; $i <= count($rows); $i++) {
$pages[] = $rows[$i];
if (!empty($rows[$i]['doc_page_clef'])) {
if (!isset($vdoc_page) || !is_array($vdoc_page)) {
$vdoc_page = array();
}
$vdoc_page[$rows[$i]['doc_page_clef']] = $rows[$i];
}
}
return $pages;
}
/** Une page par doc_page_clef (mémoire ou BD). */
function fxDocGetPageRow($clef, $mem_global = 0) {
global $vdoc_page, $objDatabase;
if (!empty($vdoc_page[$clef])) {
return $vdoc_page[$clef];
}
if (!isset($objDatabase) || $clef === '' || !fxDocSchemaReady()) {
return array();
}
$strPrg = fxDocPrg($mem_global);
$langue = fxDocLangue();
static $pageCache = array();
$cacheKey = $clef . '|' . $langue . '|' . $strPrg;
if (array_key_exists($cacheKey, $pageCache)) {
return $pageCache[$cacheKey];
}
$sql = "SELECT *
FROM doc_page
WHERE doc_actif = 1
AND doc_page_clef = '" . $objDatabase->fxEscape($clef) . "'
AND doc_langue = '" . $objDatabase->fxEscape($langue) . "'
AND doc_prg IN ('" . $objDatabase->fxEscape($strPrg) . "', 'global')
ORDER BY FIELD(doc_prg, '" . $objDatabase->fxEscape($strPrg) . "', 'global')
LIMIT 1";
$row = $objDatabase->fxGetRow($sql);
$pageCache[$cacheKey] = is_array($row) ? $row : array();
return $pageCache[$cacheKey];
}
/** Crée une page doc vide si absente (miroir afficheTexte). */
function fxDocEnsurePage($clef, $mem_global = 0, $modClef = '') {
global $objDatabase;
$row = fxDocGetPageRow($clef, $mem_global);
if (!empty($row)) {
return $row;
}
$strPrg = fxDocPrg($mem_global);
$langue = fxDocLangue();
if ($modClef === '') {
$modClef = $clef;
}
$tabData = array(
'doc_mod_clef' => $modClef,
'doc_page_clef' => $clef,
'doc_langue' => $langue,
'doc_titre' => $clef,
'doc_sous_titre' => '',
'doc_html' => '',
'doc_prg' => $strPrg,
'doc_tri' => 0,
'doc_actif' => 1,
);
fxSetDocPage('add', $tabData);
if ($langue === 'fr') {
$tabDataEn = $tabData;
$tabDataEn['doc_langue'] = 'en';
fxSetDocPage('add', $tabDataEn);
}
return fxDocGetPageRow($clef, $mem_global);
}
/**
* Titre doc_titre — équivalent afficheTexte pour doc_page.
*/
function afficheDocTitre($clef, $mem_echo = 1, $mem_global = 0, $modClef = '') {
$row = fxDocGetPageRow($clef, $mem_global);
if (empty($row)) {
fxDocEnsurePage($clef, $mem_global, $modClef);
$row = fxDocGetPageRow($clef, $mem_global);
}
$str = trim($row['doc_titre'] ?? '');
if ($str === '' || $str === $clef) {
$str = '*' . $clef . '*';
}
if ($mem_echo == 1) {
echo fxDocEsc($str);
}
return $str;
}
/**
* Corps HTML doc_html — équivalent afficheAide (contenu long, HTML admin).
*/
function afficheDocHtml($clef, $mem_echo = 1, $mem_global = 0, $modClef = '') {
$row = fxDocGetPageRow($clef, $mem_global);
if (empty($row)) {
fxDocEnsurePage($clef, $mem_global, $modClef);
$row = fxDocGetPageRow($clef, $mem_global);
}
$str = $row['doc_html'] ?? '';
if ($mem_echo == 1) {
echo $str;
}
return $str;
}
/** Sous-titre doc_sous_titre. */
function afficheDocSousTitre($clef, $mem_echo = 1, $mem_global = 0, $modClef = '') {
$row = fxDocGetPageRow($clef, $mem_global);
if (empty($row)) {
fxDocEnsurePage($clef, $mem_global, $modClef);
$row = fxDocGetPageRow($clef, $mem_global);
}
$str = trim($row['doc_sous_titre'] ?? '');
if ($mem_echo == 1) {
echo fxDocEsc($str);
}
return $str;
}
/** URL pop-up doc_edition.php — module documentation paginé. */
function fxAdminDocUrl($anchorClef, $mem_global = 0) {
global $vDomaine, $vPage;
$strPrg = fxDocPrg($mem_global);
$modClef = fxDocResolveModClef($anchorClef, $mem_global);
return $vDomaine . '/php/doc_edition.php?' . http_build_query(array(
'anchor' => $anchorClef,
'mod' => $modClef,
'prg' => $strPrg,
'bd' => 'client',
'page' => !empty($vPage) ? $vPage : 'compte.php',
));
}
/** Lien crayon doc_edition.php — superadm dev/préprod + switch Textes ON. */
function fxAdminDocButton($anchorClef, $mem_global = 0) {
if (!fxAdminTextEditModeActive() || trim($anchorClef) === '') {
return '';
}
return ''
. ' '
. ' ';
}
/** Bouton ? pour ouvrir le module doc (clé doc_anchor_clef) — même rond que btn-aide-bib. */
function fxDocRenderTrigger($anchorClef, $mem_global = 0, $strAriaLabel = 'Documentation') {
$modClef = fxDocResolveModClef($anchorClef, $mem_global);
return '? ';
}
/** Panneau overlay paginé pour un module (clé doc_anchor_clef ou doc_mod_clef). */
function fxDocRenderModule($anchorClef, $mem_global = 0) {
$modClef = fxDocResolveModClef($anchorClef, $mem_global);
$pages = fxDocGetModulePages($modClef, null, $mem_global);
if (empty($pages)) {
return '';
}
$overlayId = 'ms1-doc-overlay-' . preg_replace('/[^a-z0-9_-]/i', '-', $anchorClef);
$html = '
';
$html .= '
';
$html .= '
';
$html .= '';
$html .= '
';
foreach ($pages as $idx => $page) {
$html .= '
0 ? ' hidden' : '')
. ' data-doc-page-index="' . (int)$idx . '"'
. ' data-doc-page-clef="' . fxDocEsc($page['doc_page_clef']) . '">';
$html .= '
' . ($page['doc_html'] ?? '') . '
';
$html .= '
';
}
$html .= '
';
$html .= '';
$html .= '
';
// Métadonnées titres pour JS (init header sans parser le HTML)
$html .= '';
return $html;
}
/** Trigger + overlay (appel typique à côté d'un titre de bloc). */
function fxDocRenderBlock($anchorClef, $mem_global = 0, $strAriaLabel = 'Documentation') {
return fxDocRenderTrigger($anchorClef, $mem_global, $strAriaLabel) . fxDocRenderModule($anchorClef, $mem_global);
}
/** Clés doc — panneau remboursement promoteur (fiche gestion inscriptions). */
function fxDocRefundPromoteurAnchorClef() {
return 'inscr_gestion_refund_doc';
}
function fxDocRefundPromoteurPageClef() {
return 'inscr_gestion_refund_promoteur_info';
}
function fxDocRefundPromoteurModClef() {
return 'inscr_gestion_refund_doc';
}
/** Texte par défaut si doc_html vide (avant import SQL ou édition). */
function fxDocRefundPromoteurFallback($strLangue) {
if ($strLangue === 'en') {
return array(
'titre' => 'Refunds and MS1 fees',
'html' => ''
. 'As a promoter, you may refund the customer up to 100% of the transaction amount.
'
. 'However, MS1 platform fees are not refunded to the promoter. If you refund the customer, you absorb those fees — they remain your responsibility.
'
. 'The « Max refundable » amount is the PayPal balance available for this capture, not a reimbursement of MS1 fees.
'
. ' ',
);
}
return array(
'titre' => 'Remboursement et frais MS1',
'html' => ''
. 'En tant que promoteur, vous pouvez rembourser le client jusqu\'à 100 % du montant de la transaction.
'
. 'En revanche, les frais MS1 ne sont pas remboursés par la plateforme au promoteur. Si vous remboursez le client, vous assumez ces frais : ils restent à votre charge.
'
. 'Le montant « Max remboursable » correspond au solde PayPal disponible pour cette capture, et non au remboursement des frais MS1.
'
. ' ',
);
}
/**
* Colonne droite du panneau remboursement (fiche gestion promoteur) — doc_html inline.
* Éditable via doc_edition.php (mode Textes, icône livre).
*/
function fxDocRenderRefundPromoteurAside() {
if (!fxDocSchemaReady()) {
return '';
}
$strAnchor = fxDocRefundPromoteurAnchorClef();
$strPageClef = fxDocRefundPromoteurPageClef();
$strModClef = fxDocRefundPromoteurModClef();
$strLangue = fxDocLangue();
fxDocEnsurePage($strPageClef, 0, $strModClef);
$strTitre = trim((string)afficheDocTitre($strPageClef, 0, 0, $strModClef));
$strHtml = trim((string)afficheDocHtml($strPageClef, 0, 0, $strModClef));
$tabFallback = fxDocRefundPromoteurFallback($strLangue);
if ($strTitre === '' || $strTitre === '*' . $strPageClef . '*') {
$strTitre = $tabFallback['titre'];
}
if ($strHtml === '') {
$strHtml = $tabFallback['html'];
}
$strEditBtn = function_exists('fxAdminDocButton') ? fxAdminDocButton($strAnchor, 0) : '';
$html = '';
$html .= '';
$html .= '
';
$html .= '' . fxDocEsc($strTitre) . ' ';
if ($strEditBtn !== '') {
$html .= '' . $strEditBtn . '
';
}
$html .= ' ';
$html .= '
' . $strHtml . '
';
$html .= '
';
return $html;
}
function fxSetDocMod($strAction, $tabData, $id = 0) {
global $objDatabase;
switch ($strAction) {
case 'add':
$tabFieldsValues = fxListFieldsValues($tabData, 'pk_doc_mod', 'doc_mod', $GLOBALS['arrConDatabaseMain']['db']);
$sqlValide = "SELECT COUNT(doc_mod_clef) FROM doc_mod
WHERE doc_mod_clef = '" . $objDatabase->fxEscape($tabData['doc_mod_clef']) . "'
AND doc_mod_prg = '" . $objDatabase->fxEscape($tabData['doc_mod_prg']) . "'";
if ((int)$objDatabase->fxGetVar($sqlValide) > 0) {
break;
}
$sqlInsert = "INSERT INTO doc_mod " . $tabFieldsValues['set'] . ', doc_mod_creation = NOW()';
$objDatabase->fxQuery($sqlInsert);
break;
case 'mod':
$tabFieldsValues = fxListFieldsValues($tabData, 'pk_doc_mod', 'doc_mod', $GLOBALS['arrConDatabaseMain']['db']);
$sqlUpdate = "UPDATE doc_mod " . $tabFieldsValues['set'] . ", doc_mod_maj = NOW() WHERE " . $tabFieldsValues['key'];
$objDatabase->fxQuery($sqlUpdate);
break;
}
}
function fxSetDocPage($strAction, $tabData, $id = 0) {
global $objDatabase;
switch ($strAction) {
case 'add':
$tabFieldsValues = fxListFieldsValues($tabData, 'pk_doc_page', 'doc_page', $GLOBALS['arrConDatabaseMain']['db']);
$sqlValide = "SELECT COUNT(doc_page_clef) FROM doc_page
WHERE doc_page_clef = '" . $objDatabase->fxEscape($tabData['doc_page_clef']) . "'
AND doc_langue = '" . $objDatabase->fxEscape($tabData['doc_langue']) . "'
AND doc_prg = '" . $objDatabase->fxEscape($tabData['doc_prg']) . "'";
if ((int)$objDatabase->fxGetVar($sqlValide) > 0) {
break;
}
$sqlInsert = "INSERT INTO doc_page " . $tabFieldsValues['set'] . ', doc_creation = NOW()';
$objDatabase->fxQuery($sqlInsert);
break;
case 'mod':
$tabFieldsValues = fxListFieldsValues($tabData, 'pk_doc_page', 'doc_page', $GLOBALS['arrConDatabaseMain']['db']);
$sqlUpdate = "UPDATE doc_page " . $tabFieldsValues['set'] . ", doc_maj = NOW() WHERE " . $tabFieldsValues['key'];
$objDatabase->fxQuery($sqlUpdate);
break;
}
}
function fxSetDocAnchor($strAction, $tabData, $id = 0) {
global $objDatabase;
switch ($strAction) {
case 'add':
$tabFieldsValues = fxListFieldsValues($tabData, 'pk_doc_anchor', 'doc_anchor', $GLOBALS['arrConDatabaseMain']['db']);
$sqlValide = "SELECT COUNT(doc_anchor_clef) FROM doc_anchor
WHERE doc_anchor_clef = '" . $objDatabase->fxEscape($tabData['doc_anchor_clef']) . "'
AND doc_prg = '" . $objDatabase->fxEscape($tabData['doc_prg']) . "'";
if ((int)$objDatabase->fxGetVar($sqlValide) > 0) {
break;
}
$sqlInsert = "INSERT INTO doc_anchor " . $tabFieldsValues['set'] . ', doc_creation = NOW()';
$objDatabase->fxQuery($sqlInsert);
break;
case 'mod':
$tabFieldsValues = fxListFieldsValues($tabData, 'pk_doc_anchor', 'doc_anchor', $GLOBALS['arrConDatabaseMain']['db']);
$sqlUpdate = "UPDATE doc_anchor " . $tabFieldsValues['set'] . " WHERE " . $tabFieldsValues['key'];
$objDatabase->fxQuery($sqlUpdate);
break;
}
}