diff --git a/images/doc/dossardposition.png b/images/doc/dossardposition.png new file mode 100644 index 0000000..3c24210 Binary files /dev/null and b/images/doc/dossardposition.png differ diff --git a/php/inc_fx_promoteur.php b/php/inc_fx_promoteur.php index 392f0e3..6be39ed 100644 --- a/php/inc_fx_promoteur.php +++ b/php/inc_fx_promoteur.php @@ -3708,7 +3708,7 @@ function fxBibStaticFallback($clef) { 'bib_v4_dist_print_col_prenom' => ['fr' => 'Prénom', 'en' => 'First name'], // MSIN-4471 — Feuille bénévole : nom+prénom + case remise. 'bib_v4_dist_print_col_nom_prenom' => ['fr' => 'Nom, Prénom', 'en' => 'Last name, First name'], - 'bib_v4_dist_print_col_check' => ['fr' => '', 'en' => ''], + 'bib_v4_dist_print_col_check' => ['fr' => 'OK', 'en' => 'OK'], 'bib_v4_dist_print_col_sexe' => ['fr' => 'Sexe', 'en' => 'Gender'], 'bib_v4_dist_print_empty_epr' => ['fr' => 'Aucun dossard assigné pour cette épreuve.', 'en' => 'No bib assigned for this race.'], 'bib_v4_dist_print_last' => ['fr' => 'Dernière impression : %s — %s', 'en' => 'Last print: %s — %s'], @@ -9510,6 +9510,71 @@ function fxBibDistPrintIntroPageClefs() { ); } +/** MSIN-4471 — Chemin absolu du logo MS1 (pied / bandeau PDF). */ +function fxBibDistPrintMs1LogoPath() { + $strDocRoot = $_SERVER['DOCUMENT_ROOT'] ?? dirname(__DIR__); + $strPath = rtrim($strDocRoot, '/\\') . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'logoms1inscription.png'; + return is_file($strPath) ? $strPath : ''; +} + +/** + * MSIN-4471 — Texte brut d'un nœud DOM (espaces normalisés). + */ +function fxBibDistPrintDomPlainText($node) { + if (!$node) { + return ''; + } + $str = $node->textContent ?? ''; + $str = preg_replace('/\s+/u', ' ', $str); + return trim((string)$str); +} + +/** + * MSIN-4471 — Écrit un fragment inline (texte + strong/em) en mode Write. + */ +function fxBibDistPrintWriteInline($pdf, $node, $fltLineH = 5, $fltFontSize = 10) { + if (!$node) { + return; + } + foreach ($node->childNodes as $child) { + if ($child->nodeType === XML_TEXT_NODE) { + $strText = preg_replace('/\s+/u', ' ', $child->nodeValue); + if ($strText !== null && $strText !== '') { + $pdf->SetFont('Arial', '', $fltFontSize); + $pdf->Write($fltLineH, fxBibDistPrintPdfText($strText)); + } + continue; + } + if ($child->nodeType !== XML_ELEMENT_NODE) { + continue; + } + $strTag = strtolower($child->nodeName); + if ($strTag === 'br') { + $pdf->Ln($fltLineH); + continue; + } + if (in_array($strTag, array('strong', 'b'), true)) { + $strText = fxBibDistPrintDomPlainText($child); + if ($strText !== '') { + $pdf->SetFont('Arial', 'B', $fltFontSize); + $pdf->Write($fltLineH, fxBibDistPrintPdfText($strText)); + $pdf->SetFont('Arial', '', $fltFontSize); + } + continue; + } + if (in_array($strTag, array('em', 'i'), true)) { + $strText = fxBibDistPrintDomPlainText($child); + if ($strText !== '') { + $pdf->SetFont('Arial', 'I', $fltFontSize); + $pdf->Write($fltLineH, fxBibDistPrintPdfText($strText)); + $pdf->SetFont('Arial', '', $fltFontSize); + } + continue; + } + fxBibDistPrintWriteInline($pdf, $child, $fltLineH, $fltFontSize); + } +} + /** * MSIN-4471 — Résout un src img vers un fichier sous images/doc/ uniquement. * Accepte /images/doc/x.png, images/doc/x.png (refuse tout autre chemin). @@ -9570,6 +9635,207 @@ function fxBibDistPrintWriteImage($pdf, $strPath) { $pdf->Ln(max(8, $fltH + 2)); } +/** + * MSIN-4471 — Rendu flyer des pages intro (bandeau déjà dans Header). + * Structure attendue : lead

puis blocs

+

(cartes numérotées). + * Si pas de h3 : repli sur fxBibDistPrintWriteHtml. + */ +function fxBibDistPrintWriteIntroFlyer($pdf, $strHtml) { + $strHtml = trim((string)$strHtml); + if ($strHtml === '') { + return; + } + if (!class_exists('DOMDocument', false)) { + fxBibDistPrintWriteHtml($pdf, $strHtml); + return; + } + + $dom = new DOMDocument(); + $blnPrev = libxml_use_internal_errors(true); + $dom->loadHTML( + '

' . $strHtml . '
', + LIBXML_HTML_NODEFDTD + ); + libxml_clear_errors(); + libxml_use_internal_errors($blnPrev); + + $root = $dom->getElementById('ms1-bib-dist-root'); + if (!$root) { + foreach ($dom->getElementsByTagName('div') as $el) { + if ($el->getAttribute('id') === 'ms1-bib-dist-root') { + $root = $el; + break; + } + } + } + if (!$root) { + fxBibDistPrintWriteHtml($pdf, $strHtml); + return; + } + + // Déballer
si présent. + $article = null; + foreach ($root->childNodes as $child) { + if ($child->nodeType === XML_ELEMENT_NODE && strtolower($child->nodeName) === 'article') { + $article = $child; + break; + } + } + $scope = $article ?: $root; + + $tabBlocks = array(); + foreach ($scope->childNodes as $child) { + if ($child->nodeType !== XML_ELEMENT_NODE) { + continue; + } + $strTag = strtolower($child->nodeName); + if (in_array($strTag, array('p', 'h2', 'h3', 'h4', 'ul', 'ol', 'blockquote', 'img'), true)) { + $tabBlocks[] = $child; + } + } + + $blnHasH3 = false; + foreach ($tabBlocks as $el) { + if (strtolower($el->nodeName) === 'h3') { + $blnHasH3 = true; + break; + } + } + if (!$blnHasH3) { + fxBibDistPrintWriteHtml($pdf, $strHtml); + return; + } + + $fltLeft = method_exists($pdf, 'GetLeftMargin') ? $pdf->GetLeftMargin() : 12; + $fltRight = method_exists($pdf, 'GetRightMargin') ? $pdf->GetRightMargin() : 12; + $fltBottom = method_exists($pdf, 'GetBreakMargin') ? $pdf->GetBreakMargin() : 18; + $fltPageW = $pdf->GetPageWidth(); + $fltContentW = $fltPageW - $fltLeft - $fltRight; + $intTip = 0; + $blnLeadDone = false; + + $i = 0; + $intN = count($tabBlocks); + while ($i < $intN) { + $el = $tabBlocks[$i]; + $strTag = strtolower($el->nodeName); + + // Premier

= encadré d'intro (lead). + if ($strTag === 'p' && !$blnLeadDone) { + $blnLeadDone = true; + $strLead = fxBibDistPrintDomPlainText($el); + $fltInnerW = $fltContentW - 10; + $pdf->SetFont('Arial', 'I', 10); + $intLines = max(2, (int)ceil($pdf->GetStringWidth(fxBibDistPrintPdfText($strLead)) / max(1, $fltInnerW)) + 1); + $fltBoxH = max(12, 4 + ($intLines * 4.5) + 3); + if ($pdf->GetY() + $fltBoxH > $pdf->GetPageHeight() - $fltBottom) { + $pdf->AddPage(); + } + $fltY0 = $pdf->GetY(); + $pdf->SetFillColor(232, 240, 254); + $pdf->Rect($fltLeft, $fltY0, $fltContentW, $fltBoxH, 'F'); + $pdf->SetFillColor(47, 95, 208); + $pdf->Rect($fltLeft, $fltY0, 2.5, $fltBoxH, 'F'); + $pdf->SetXY($fltLeft + 6, $fltY0 + 3.5); + $pdf->SetFont('Arial', 'I', 10); + $pdf->SetTextColor(40, 55, 90); + $pdf->MultiCell($fltInnerW, 4.5, fxBibDistPrintPdfText($strLead), 0, 'L'); + $pdf->SetY($fltY0 + $fltBoxH + 5); + $pdf->SetTextColor(0, 0, 0); + $i++; + continue; + } + + if ($strTag === 'h3' || $strTag === 'h2' || $strTag === 'h4') { + $intTip++; + $strTitleRaw = fxBibDistPrintDomPlainText($el); + $strTitle = $strTitleRaw; + $strNum = (string)$intTip; + if (preg_match('/^(\d+)\s*[\.\)\—\-–]\s*(.+)$/u', $strTitleRaw, $m)) { + $strNum = $m[1]; + $strTitle = $m[2]; + } + + $bodyNode = null; + if (($i + 1) < $intN && strtolower($tabBlocks[$i + 1]->nodeName) === 'p') { + $bodyNode = $tabBlocks[$i + 1]; + $i += 2; + } else { + $i++; + } + $strBodyPlain = $bodyNode ? fxBibDistPrintDomPlainText($bodyNode) : ''; + + $fltBadge = 12; + $fltPad = 4.5; + $fltInnerLeft = $fltLeft + 6 + $fltBadge + 5; + $fltInnerW = ($fltLeft + $fltContentW) - $fltPad - $fltInnerLeft; + + $pdf->SetFont('Arial', 'B', 11); + $intTitleLines = max(1, (int)ceil($pdf->GetStringWidth(fxBibDistPrintPdfText($strTitle)) / max(1, $fltInnerW))); + $fltTitleH = $intTitleLines * 5.5; + $pdf->SetFont('Arial', '', 10); + $fltBodyH = 0; + if ($strBodyPlain !== '') { + $intBodyLines = max(1, (int)ceil($pdf->GetStringWidth(fxBibDistPrintPdfText($strBodyPlain)) / max(1, $fltInnerW))); + $fltBodyH = $intBodyLines * 4.8; + } + $fltCardH = max(24, $fltPad + $fltTitleH + 2 + $fltBodyH + $fltPad + 1); + + if ($pdf->GetY() + $fltCardH > $pdf->GetPageHeight() - $fltBottom) { + $pdf->AddPage(); + } + $fltY0 = $pdf->GetY(); + + $pdf->SetFillColor(247, 249, 252); + $pdf->SetDrawColor(200, 210, 228); + $pdf->Rect($fltLeft, $fltY0, $fltContentW, $fltCardH, 'FD'); + $pdf->SetFillColor(47, 95, 208); + $pdf->Rect($fltLeft, $fltY0, 3.2, $fltCardH, 'F'); + + $fltBadgeX = $fltLeft + 7; + $fltBadgeY = $fltY0 + ($fltCardH - $fltBadge) / 2; + $pdf->SetFillColor(47, 95, 208); + $pdf->Rect($fltBadgeX, $fltBadgeY, $fltBadge, $fltBadge, 'F'); + $pdf->SetTextColor(255, 255, 255); + $pdf->SetFont('Arial', 'B', 12); + $pdf->SetXY($fltBadgeX, $fltBadgeY + 2.8); + $pdf->Cell($fltBadge, 6, fxBibDistPrintPdfText($strNum), 0, 0, 'C'); + + $pdf->SetTextColor(25, 40, 70); + $pdf->SetFont('Arial', 'B', 11); + $pdf->SetXY($fltInnerLeft, $fltY0 + $fltPad); + $pdf->MultiCell($fltInnerW, 5.5, fxBibDistPrintPdfText($strTitle), 0, 'L'); + + if ($bodyNode) { + $pdf->SetTextColor(55, 65, 80); + $pdf->SetX($fltInnerLeft); + $pdf->SetLeftMargin($fltInnerLeft); + fxBibDistPrintWriteInline($pdf, $bodyNode, 4.8, 10); + $pdf->SetLeftMargin($fltLeft); + $pdf->Ln(2); + } + + $pdf->SetY($fltY0 + $fltCardH + 3.5); + $pdf->SetTextColor(0, 0, 0); + $pdf->SetX($fltLeft); + continue; + } + + // Autres blocs (ul/ol/img…) : rendu classique. + if ($strTag === 'p') { + // p après les cartes (rare) : texte simple. + $pdf->SetFont('Arial', '', 10); + $pdf->MultiCell($fltContentW, 5, fxBibDistPrintPdfText(fxBibDistPrintDomPlainText($el)), 0, 'L'); + $pdf->Ln(2); + $i++; + continue; + } + + fxBibDistPrintWriteHtml($pdf, $dom->saveHTML($el)); + $i++; + } +} + /** * MSIN-4471 — Rendu HTML simplifié (doc_html) vers FPDF. * Tags supportés : h2–h4, p, ul/ol/li, strong/b, em/i, br, img, blockquote, article/div/span. @@ -9715,7 +9981,9 @@ function fxBibDistPrintWriteHtml($pdf, $strHtml) { } } -/** MSIN-4471 — Dessine le QR résultats événement (kc.php?t=eve) centré. */ +/** + * MSIN-4471 — Dessine le QR résultats événement (kc.php?t=eve) centré. + */ function fxBibDistPrintDrawEventQr($pdf, $int_eve_id) { $int_eve_id = (int)$int_eve_id; if ($int_eve_id <= 0 || !function_exists('fxKcEveResultatsQrPngBinary')) { @@ -9763,18 +10031,25 @@ function fxBibOutputDistPrintIntroPages($pdf, $int_eve_id, $strLangue = 'fr') { $pdf->blnIntroMode = true; $pdf->eprTitle = ''; + $pdf->documentSubtitle = ''; $strDefaultDocTitle = fxBibTexte('bib_v4_dist_print_title', 0); + // Marges flyer : place pour bandeau + logo pied de page. + $pdf->SetMargins(12, 40, 12); + $pdf->SetAutoPageBreak(true, 18); + foreach (fxBibDistPrintIntroPageClefs() as $strClef) { $row = function_exists('fxDocGetPageRow') ? fxDocGetPageRow($strClef, 0) : array(); $strTitre = trim((string)($row['doc_titre'] ?? '')); + $strSous = trim((string)($row['doc_sous_titre'] ?? '')); $strHtml = trim((string)($row['doc_html'] ?? '')); if ($strTitre === '' && $strHtml === '') { continue; } $pdf->documentTitle = ($strTitre !== '') ? $strTitre : $strClef; + $pdf->documentSubtitle = $strSous; $pdf->AddPage(); - fxBibDistPrintWriteHtml($pdf, $strHtml); + fxBibDistPrintWriteIntroFlyer($pdf, $strHtml); if ($strClef === 'bib_dist_print_qr') { fxBibDistPrintDrawEventQr($pdf, $int_eve_id); } @@ -9782,7 +10057,10 @@ function fxBibOutputDistPrintIntroPages($pdf, $int_eve_id, $strLangue = 'fr') { $pdf->blnIntroMode = false; $pdf->documentTitle = $strDefaultDocTitle; + $pdf->documentSubtitle = ''; $pdf->eprTitle = ''; + $pdf->SetMargins(10, 12, 10); + $pdf->SetAutoPageBreak(true, 16); } /** MSIN-4433 — Génère et envoie le PDF (format lettre). */ @@ -9827,8 +10105,9 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = public $pageText = 'Page %s / %s'; public $eventTitle = ''; public $documentTitle = ''; + public $documentSubtitle = ''; public $eprTitle = ''; - /** MSIN-4471 — Pages intro : pas de sous-titre épreuve. */ + /** MSIN-4471 — Pages intro : bandeau flyer, pas de sous-titre épreuve. */ public $blnIntroMode = false; /** MSIN-4471 — Accès public aux marges (protégées dans FPDF 1.82). */ @@ -9846,12 +10125,44 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = } function Header() { + if ($this->blnIntroMode) { + $fltW = $this->GetPageWidth(); + // Bandeau flyer (bleu MS1 + filet or). + $this->SetFillColor(47, 95, 208); + $this->Rect(0, 0, $fltW, 32, 'F'); + $this->SetFillColor(255, 193, 7); + $this->Rect(0, 32, $fltW, 2, 'F'); + + $fltTextX = 12; + $strLogo = function_exists('fxBibDistPrintMs1LogoPath') ? fxBibDistPrintMs1LogoPath() : ''; + if ($strLogo !== '') { + $fltLogoW = 34; + $this->Image($strLogo, 10, 9, $fltLogoW); + $fltTextX = 10 + $fltLogoW + 5; + } + + $this->SetTextColor(255, 255, 255); + $this->SetXY($fltTextX, 6); + $this->SetFont('Arial', 'B', 14); + $this->Cell($fltW - $fltTextX - 10, 7, fxBibDistPrintPdfText($this->eventTitle), 0, 2, 'L'); + $this->SetFont('Arial', 'B', 12); + $this->Cell($fltW - $fltTextX - 10, 6, fxBibDistPrintPdfText($this->documentTitle), 0, 2, 'L'); + if (trim((string)$this->documentSubtitle) !== '') { + $this->SetFont('Arial', 'I', 9); + $this->SetTextColor(220, 230, 255); + $this->Cell($fltW - $fltTextX - 10, 5, fxBibDistPrintPdfText($this->documentSubtitle), 0, 2, 'L'); + } + $this->SetTextColor(0, 0, 0); + $this->SetY(38); + return; + } + $this->SetFont('Arial', 'B', 14); $this->Cell(0, 8, fxBibDistPrintPdfText($this->eventTitle), 0, 1, 'C'); - $this->SetFont('Arial', $this->blnIntroMode ? 'B' : '', $this->blnIntroMode ? 11 : 10); + $this->SetFont('Arial', '', 10); $this->Cell(0, 6, fxBibDistPrintPdfText($this->documentTitle), 0, 1, 'C'); $this->Ln(2); - if (!$this->blnIntroMode && $this->eprTitle !== '') { + if ($this->eprTitle !== '') { $this->SetFont('Arial', 'B', 11); $this->Cell(0, 7, fxBibDistPrintPdfText($this->eprTitle), 0, 1, 'L'); $this->Ln(1); @@ -9859,12 +10170,32 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = } function Footer() { + $strLogo = function_exists('fxBibDistPrintMs1LogoPath') ? fxBibDistPrintMs1LogoPath() : ''; + $fltLogoW = 20; + $fltLogoReserve = ($strLogo !== '') ? ($fltLogoW + 6) : 0; + $fltPageW = $this->GetPageWidth(); + + if ($strLogo !== '') { + // Petit logo bas droite (toutes les pages). + $this->Image( + $strLogo, + $fltPageW - $this->rMargin - $fltLogoW, + $this->GetPageHeight() - 11, + $fltLogoW + ); + } + $this->SetY(-12); $this->SetFont('Arial', 'I', 7); - $this->Cell(0, 4, fxBibDistPrintPdfText($this->footerText), 0, 0, 'L'); - $this->SetX($this->lMargin); + $this->SetTextColor(90, 90, 90); + $fltTextW = $fltPageW - $this->lMargin - $this->rMargin - $fltLogoReserve - 22; + if ($fltTextW < 40) { + $fltTextW = 40; + } + $this->Cell($fltTextW, 4, fxBibDistPrintPdfText($this->footerText), 0, 0, 'L'); $strPage = sprintf($this->pageText, $this->PageNo(), '{nb}'); - $this->Cell(0, 4, fxBibDistPrintPdfText($strPage), 0, 0, 'R'); + $this->Cell(22, 4, fxBibDistPrintPdfText($strPage), 0, 0, 'R'); + $this->SetTextColor(0, 0, 0); } } } @@ -9875,15 +10206,16 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = $pdf->eventTitle = fxBibDistPrintTruncate($strEventTitle, 80); $pdf->documentTitle = fxBibTexte('bib_v4_dist_print_title', 0); $pdf->SetMargins(10, 12, 10); - $pdf->SetAutoPageBreak(true, 14); + $pdf->SetAutoPageBreak(true, 16); $pdf->AliasNbPages(); // MSIN-4471 — Pages d'explication (doc) avant les tableaux d'épreuves. fxBibOutputDistPrintIntroPages($pdf, $int_eve_id, $strLangue); - // MSIN-4471 — Feuille bénévole : case remise + dossard gros + nom/prénom + ~20–25 lignes/page. + // MSIN-4471 — Feuille bénévole : recherche par nom, puis dossard à remettre. + // Ordre : ☐ | Nom, Prénom | Dossard | Sexe | questions $fltPageW = $pdf->GetPageWidth() - 20; - $fltColCheck = 9; + $fltColCheck = 10; $fltColBib = 28; $fltColSexe = 12; $fltFixedW = $fltColCheck + $fltColBib + $fltColSexe; @@ -9947,9 +10279,10 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = $fnDrawTableHeader = function () use ($pdf, $fltColCheck, $fltColBib, $fltNameW, $fltColSexe, $fltQEach, $tabQueCols, $intNbQ, $fltHeadH) { $pdf->SetFont('Arial', 'B', 10); $pdf->SetFillColor(220, 220, 220); + // Case remise | Nom (recherche) | Dossard | Sexe | … $pdf->Cell($fltColCheck, $fltHeadH, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_check', 0)), 1, 0, 'C', true); - $pdf->Cell($fltColBib, $fltHeadH, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_bib', 0)), 1, 0, 'C', true); $pdf->Cell($fltNameW, $fltHeadH, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_nom_prenom', 0)), 1, 0, 'L', true); + $pdf->Cell($fltColBib, $fltHeadH, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_bib', 0)), 1, 0, 'C', true); $pdf->Cell($fltColSexe, $fltHeadH, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_sexe', 0)), 1, $intNbQ === 0 ? 1 : 0, 'C', true); foreach ($tabQueCols as $i => $col) { $blnLast = ($i === $intNbQ - 1); @@ -9987,14 +10320,14 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = $pdf->SetFont('Arial', '', 11); $pdf->Cell($fltColCheck, $fltRowH, '', 1, 0, 'C', $blnFill); - // Dossard — signal principal. + // Nom, Prénom — colonne de recherche principale. + $pdf->SetFont('Arial', 'B', 11); + $pdf->Cell($fltNameW, $fltRowH, fxBibDistPrintPdfText(fxBibDistPrintTruncate($strNomPrenom, 42)), 1, 0, 'L', $blnFill); + + // Dossard — numéro à remettre. $pdf->SetFont('Arial', 'B', 14); $pdf->Cell($fltColBib, $fltRowH, fxBibDistPrintPdfText((string)(int)($row['no_bib'] ?? 0)), 1, 0, 'C', $blnFill); - // Nom, Prénom. - $pdf->SetFont('Arial', '', 11); - $pdf->Cell($fltNameW, $fltRowH, fxBibDistPrintPdfText(fxBibDistPrintTruncate($strNomPrenom, 42)), 1, 0, 'L', $blnFill); - $pdf->SetFont('Arial', '', 11); $pdf->Cell($fltColSexe, $fltRowH, fxBibDistPrintPdfText(fxBibDistPrintSexeLabel($row['par_sexe'] ?? '', $strLangue)), 1, $intNbQ === 0 ? 1 : 0, 'C', $blnFill); diff --git a/sql/MSIN-4471-bib-dist-print-layout.sql b/sql/MSIN-4471-bib-dist-print-layout.sql index 4191867..2c27232 100644 --- a/sql/MSIN-4471-bib-dist-print-layout.sql +++ b/sql/MSIN-4471-bib-dist-print-layout.sql @@ -1,31 +1,32 @@ -- MSIN-4471 — Libellés feuille bénévole PDF distribution (nom+prénom, case remise) -- Prérequis : clés bib_v4_dist_print_* (MSIN-4433) --- Idempotent : INSERT si absent ; UPDATE libellé max questions si présent +-- Idempotent : INSERT si absent ; UPDATE si déjà présent avec texte vide SET NAMES utf8mb4; -INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_section, info_tri, info_actif, info_type, info_css, info_js, info_creation) -SELECT 'bib_v4_dist_print_col_nom_prenom', 'fr', 'Nom, Prénom', '', 'compte.php', '', 0, 1, '', '', '', NOW() +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_dist_print_col_nom_prenom', 'fr', 'Nom, Prénom', '', 'compte.php', 'MSIN-4471', 0, 1, '', '', '', NOW() FROM DUAL WHERE NOT EXISTS ( SELECT 1 FROM info WHERE info_clef = 'bib_v4_dist_print_col_nom_prenom' AND info_langue = 'fr' AND info_prg = 'compte.php' ); -INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_section, info_tri, info_actif, info_type, info_css, info_js, info_creation) -SELECT 'bib_v4_dist_print_col_nom_prenom', 'en', 'Last name, First name', '', 'compte.php', '', 0, 1, '', '', '', NOW() +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_dist_print_col_nom_prenom', 'en', 'Last name, First name', '', 'compte.php', 'MSIN-4471', 0, 1, '', '', '', NOW() FROM DUAL WHERE NOT EXISTS ( SELECT 1 FROM info WHERE info_clef = 'bib_v4_dist_print_col_nom_prenom' AND info_langue = 'en' AND info_prg = 'compte.php' ); -INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_section, info_tri, info_actif, info_type, info_css, info_js, info_creation) -SELECT 'bib_v4_dist_print_col_check', 'fr', '', '', 'compte.php', '', 0, 1, '', '', '', NOW() +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_dist_print_col_check', 'fr', 'OK', '', 'compte.php', 'MSIN-4471', 0, 1, '', '', '', NOW() FROM DUAL WHERE NOT EXISTS ( SELECT 1 FROM info WHERE info_clef = 'bib_v4_dist_print_col_check' AND info_langue = 'fr' AND info_prg = 'compte.php' ); -INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_section, info_tri, info_actif, info_type, info_css, info_js, info_creation) -SELECT 'bib_v4_dist_print_col_check', 'en', '', '', 'compte.php', '', 0, 1, '', '', '', NOW() +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_dist_print_col_check', 'en', 'OK', '', 'compte.php', 'MSIN-4471', 0, 1, '', '', '', NOW() FROM DUAL WHERE NOT EXISTS ( SELECT 1 FROM info WHERE info_clef = 'bib_v4_dist_print_col_check' AND info_langue = 'en' AND info_prg = 'compte.php' ); --- Le message max questions utilise %d via PHP (fxBibDistPrintMaxQuestions = 3) — pas de texte figé ici. +UPDATE info SET info_texte = 'OK', info_description = 'MSIN-4471' +WHERE info_clef = 'bib_v4_dist_print_col_check' AND info_prg = 'compte.php' AND (info_texte = '' OR info_texte IS NULL);