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 = ''; // 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 = ''; 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; } }