From e85f25c21da2ba1d219e9aabc9d4d68af118fa0f Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 21 Jul 2026 17:30:02 -0400 Subject: [PATCH] =?UTF-8?q?MSIN-4470=20=E2=80=94=20Add=20page=20numbering?= =?UTF-8?q?=20functionality=20to=20PDF=20generation=20for=20race=20bibs.?= =?UTF-8?q?=20Introduce=20UTF-8=20to=20Windows-1252=20text=20conversion=20?= =?UTF-8?q?for=20FPDF=20compatibility.=20Update=20footer=20and=20header=20?= =?UTF-8?q?handling=20in=20PDF=20output.=20Increment=20version=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/inc_fx_promoteur.php | 78 ++++++++++++++----- ...IN-4470-corrections-interface-dossards.sql | 46 +++++++++++ 2 files changed, 103 insertions(+), 21 deletions(-) diff --git a/php/inc_fx_promoteur.php b/php/inc_fx_promoteur.php index 0ba7f50..8fcd2c3 100644 --- a/php/inc_fx_promoteur.php +++ b/php/inc_fx_promoteur.php @@ -3710,6 +3710,7 @@ function fxBibStaticFallback($clef) { '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'], 'bib_v4_dist_print_footer' => ['fr' => 'Imprimé le %s — %s', 'en' => 'Printed on %s — %s'], + 'bib_v4_dist_print_page' => ['fr' => 'Page %s / %s', 'en' => 'Page %s / %s'], ]; return $tab[$clef][$lng] ?? ''; @@ -9492,6 +9493,18 @@ function fxBibDistPrintTruncate($str, $intMax = 28) { return substr($str, 0, max(1, $intMax - 1)) . '…'; } +/** MSIN-4470 — Convertit l'UTF-8 vers l'encodage Windows-1252 attendu par les polices FPDF. */ +function fxBibDistPrintPdfText($str) { + $str = (string)$str; + if (function_exists('iconv')) { + $strConverted = @iconv('UTF-8', 'Windows-1252//TRANSLIT', $str); + if ($strConverted !== false) { + return $strConverted; + } + } + return utf8_decode($str); +} + /** MSIN-4433 — Génère et envoie le PDF (format lettre). */ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = '') { global $objDatabase; @@ -9531,29 +9544,47 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = if (!class_exists('BibDistPrintPdf', false)) { class BibDistPrintPdf extends FPDF { public $footerText = ''; + public $pageText = 'Page %s / %s'; + public $eventTitle = ''; + public $documentTitle = ''; + public $eprTitle = ''; + + function Header() { + $this->SetFont('Arial', 'B', 14); + $this->Cell(0, 8, fxBibDistPrintPdfText($this->eventTitle), 0, 1, 'C'); + $this->SetFont('Arial', '', 10); + $this->Cell(0, 6, fxBibDistPrintPdfText($this->documentTitle), 0, 1, 'C'); + $this->Ln(2); + if ($this->eprTitle !== '') { + $this->SetFont('Arial', 'B', 11); + $this->Cell(0, 7, fxBibDistPrintPdfText($this->eprTitle), 0, 1, 'L'); + $this->Ln(1); + } + } function Footer() { $this->SetY(-12); $this->SetFont('Arial', 'I', 7); - $this->Cell(0, 4, utf8_decode($this->footerText), 0, 0, 'L'); - $this->Cell(0, 4, utf8_decode('p. ' . $this->PageNo()), 0, 0, 'R'); + $this->Cell(0, 4, fxBibDistPrintPdfText($this->footerText), 0, 0, 'L'); + $this->SetX($this->lMargin); + $strPage = sprintf($this->pageText, $this->PageNo(), '{nb}'); + $this->Cell(0, 4, fxBibDistPrintPdfText($strPage), 0, 0, 'R'); } } } $pdf = new BibDistPrintPdf('P', 'mm', 'letter'); $pdf->footerText = $strFooter; + $pdf->pageText = fxBibTexte('bib_v4_dist_print_page', 0); + $pdf->eventTitle = fxBibDistPrintTruncate($strEventTitle, 80); + $pdf->documentTitle = fxBibTexte('bib_v4_dist_print_title', 0); $pdf->SetMargins(10, 12, 10); $pdf->SetAutoPageBreak(true, 14); - $pdf->AddPage(); - $pdf->SetFont('Arial', 'B', 14); - $pdf->Cell(0, 8, utf8_decode(fxBibDistPrintTruncate($strEventTitle, 80)), 0, 1, 'C'); - $pdf->SetFont('Arial', '', 10); - $pdf->Cell(0, 6, utf8_decode(fxBibTexte('bib_v4_dist_print_title', 0)), 0, 1, 'C'); - $pdf->Ln(4); + $pdf->AliasNbPages(); $fltPageW = $pdf->GetPageWidth() - 20; $fltFixedW = 18 + 42 + 42 + 12; + $blnHasPrintedEpreuve = false; foreach ($tabPanel['epreuves'] as $tabEpr) { $epr_id = (int)($tabEpr['epr_id'] ?? 0); @@ -9591,21 +9622,22 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = $fltQTotal = max(0, $fltPageW - $fltFixedW); $fltQEach = ($intNbQ > 0) ? ($fltQTotal / $intNbQ) : 0; - $pdf->SetFont('Arial', 'B', 11); - $pdf->Cell(0, 7, utf8_decode(fxBibDistPrintTruncate($tabEpr['epr_label'] ?? '', 90)), 0, 1, 'L'); - $pdf->Ln(1); + // MSIN-4470 — Chaque épreuve commence sur une page neuve; Header répète les titres. + $pdf->eprTitle = fxBibDistPrintTruncate($tabEpr['epr_label'] ?? '', 90); + $pdf->AddPage(); + $blnHasPrintedEpreuve = true; $tabAnswers = fxBibGetDistPrintQuestionAnswers($epr_id, $tabSelectedQue, $tabParticipants, $strLangue); $pdf->SetFont('Arial', 'B', 8); $pdf->SetFillColor(230, 230, 230); - $pdf->Cell(18, 6, utf8_decode(fxBibTexte('bib_v4_dist_print_col_bib', 0)), 1, 0, 'C', true); - $pdf->Cell(42, 6, utf8_decode(fxBibTexte('bib_v4_dist_print_col_nom', 0)), 1, 0, 'L', true); - $pdf->Cell(42, 6, utf8_decode(fxBibTexte('bib_v4_dist_print_col_prenom', 0)), 1, 0, 'L', true); - $pdf->Cell(12, 6, utf8_decode(fxBibTexte('bib_v4_dist_print_col_sexe', 0)), 1, 0, 'C', true); + $pdf->Cell(18, 6, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_bib', 0)), 1, 0, 'C', true); + $pdf->Cell(42, 6, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_nom', 0)), 1, 0, 'L', true); + $pdf->Cell(42, 6, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_prenom', 0)), 1, 0, 'L', true); + $pdf->Cell(12, 6, fxBibDistPrintPdfText(fxBibTexte('bib_v4_dist_print_col_sexe', 0)), 1, 0, 'C', true); foreach ($tabQueCols as $i => $col) { $blnLast = ($i === $intNbQ - 1); - $pdf->Cell($fltQEach, 6, utf8_decode(fxBibDistPrintTruncate($col['label'], 22)), 1, $blnLast ? 1 : 0, 'L', true); + $pdf->Cell($fltQEach, 6, fxBibDistPrintPdfText(fxBibDistPrintTruncate($col['label'], 22)), 1, $blnLast ? 1 : 0, 'L', true); } if ($intNbQ === 0) { $pdf->Ln(); @@ -9614,15 +9646,15 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = $pdf->SetFont('Arial', '', 8); foreach ($tabParticipants as $row) { $strKey = fxBibDistPrintAnswerKey($row); - $pdf->Cell(18, 5, utf8_decode((string)(int)($row['no_bib'] ?? 0)), 1, 0, 'C'); - $pdf->Cell(42, 5, utf8_decode(fxBibDistPrintTruncate($row['par_nom'] ?? '', 24)), 1, 0, 'L'); - $pdf->Cell(42, 5, utf8_decode(fxBibDistPrintTruncate($row['par_prenom'] ?? '', 24)), 1, 0, 'L'); - $pdf->Cell(12, 5, utf8_decode(fxBibDistPrintSexeLabel($row['par_sexe'] ?? '', $strLangue)), 1, 0, 'C'); + $pdf->Cell(18, 5, fxBibDistPrintPdfText((string)(int)($row['no_bib'] ?? 0)), 1, 0, 'C'); + $pdf->Cell(42, 5, fxBibDistPrintPdfText(fxBibDistPrintTruncate($row['par_nom'] ?? '', 24)), 1, 0, 'L'); + $pdf->Cell(42, 5, fxBibDistPrintPdfText(fxBibDistPrintTruncate($row['par_prenom'] ?? '', 24)), 1, 0, 'L'); + $pdf->Cell(12, 5, fxBibDistPrintPdfText(fxBibDistPrintSexeLabel($row['par_sexe'] ?? '', $strLangue)), 1, 0, 'C'); foreach ($tabQueCols as $i => $col) { $intQueId = (int)$col['que_id']; $strAns = $tabAnswers[$strKey][$intQueId] ?? ''; $blnLast = ($i === $intNbQ - 1); - $pdf->Cell($fltQEach, 5, utf8_decode(fxBibDistPrintTruncate($strAns, 24)), 1, $blnLast ? 1 : 0, 'L'); + $pdf->Cell($fltQEach, 5, fxBibDistPrintPdfText(fxBibDistPrintTruncate($strAns, 24)), 1, $blnLast ? 1 : 0, 'L'); } if ($intNbQ === 0) { $pdf->Ln(); @@ -9632,6 +9664,10 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy = $pdf->Ln(5); } + if (!$blnHasPrintedEpreuve) { + $pdf->AddPage(); + } + $strFilename = 'distribution-dossards-' . $int_eve_id . '.pdf'; $pdf->Output('I', $strFilename); } diff --git a/sql/MSIN-4470-corrections-interface-dossards.sql b/sql/MSIN-4470-corrections-interface-dossards.sql index 2e71615..152dd05 100644 --- a/sql/MSIN-4470-corrections-interface-dossards.sql +++ b/sql/MSIN-4470-corrections-interface-dossards.sql @@ -61,3 +61,49 @@ WHERE NOT EXISTS ( AND current_info.info_langue = src.info_langue AND current_info.info_prg = 'compte.php' ); + +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 + src.info_clef, + src.info_langue, + src.info_texte, + '', + 'compte.php', + 'MSIN-4470', + 0, + 1, + '', + '', + '', + NOW() +FROM ( + SELECT + 'bib_v4_dist_print_page' AS info_clef, + 'fr' AS info_langue, + 'Page %s / %s' AS info_texte + UNION ALL + SELECT + 'bib_v4_dist_print_page', + 'en', + 'Page %s / %s' +) src +WHERE NOT EXISTS ( + SELECT 1 + FROM info current_info + WHERE current_info.info_clef = src.info_clef + AND current_info.info_langue = src.info_langue + AND current_info.info_prg = 'compte.php' +);