MSIN-4471 — Refactor PDF generation for improved layout and pagination handling. Adjust header and footer dimensions based on subtitle presence, and implement logic to correctly count and display intro pages. Update SQL documentation to enhance clarity in participant instructions. Increment version code.

This commit is contained in:
2026-07-22 08:32:28 -04:00
parent db5b1b9da3
commit fd6ec9b876
2 changed files with 58 additions and 23 deletions

View File

@ -10076,10 +10076,11 @@ function fxBibOutputDistPrintIntroPages($pdf, $int_eve_id, $strLangue = 'fr') {
$pdf->documentSubtitle = '';
$strDefaultDocTitle = fxBibTexte('bib_v4_dist_print_title', 0);
// Marges flyer : place pour bandeau + logo pied de page.
$pdf->SetMargins(12, 40, 12);
// Marges flyer : place pour bandeau (sous-titre majuscule) + logo pied de page.
$pdf->SetMargins(12, 46, 12);
$pdf->SetAutoPageBreak(true, 18);
$intPageBeforeIntro = (int)$pdf->PageNo();
foreach (fxBibDistPrintIntroPageClefs() as $strClef) {
$row = function_exists('fxDocGetPageRow') ? fxDocGetPageRow($strClef, 0) : array();
$strTitre = trim((string)($row['doc_titre'] ?? ''));
@ -10101,6 +10102,7 @@ function fxBibOutputDistPrintIntroPages($pdf, $int_eve_id, $strLangue = 'fr') {
fxBibDistPrintWriteIntroFlyer($pdf, $strHtml);
}
$pdf->intIntroPageCount = max(0, (int)$pdf->PageNo() - $intPageBeforeIntro);
$pdf->blnIntroMode = false;
$pdf->documentTitle = $strDefaultDocTitle;
@ -10156,6 +10158,8 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy =
public $eprTitle = '';
/** MSIN-4471 — Pages intro : bandeau flyer, pas de sous-titre épreuve. */
public $blnIntroMode = false;
/** MSIN-4471 — Nb de pages intro (pagination listes démarre à 1). */
public $intIntroPageCount = 0;
/** MSIN-4471 — Accès public aux marges (protégées dans FPDF 1.82). */
function GetLeftMargin() {
@ -10174,33 +10178,41 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy =
function Header() {
if ($this->blnIntroMode) {
$fltW = $this->GetPageWidth();
$strSous = trim((string)$this->documentSubtitle);
$blnHasSous = ($strSous !== '');
$fltBandH = $blnHasSous ? 38 : 30;
// Bandeau flyer (bleu MS1 + filet or).
$this->SetFillColor(47, 95, 208);
$this->Rect(0, 0, $fltW, 32, 'F');
$this->Rect(0, 0, $fltW, $fltBandH, 'F');
$this->SetFillColor(255, 193, 7);
$this->Rect(0, 32, $fltW, 2, 'F');
$this->Rect(0, $fltBandH, $fltW, 2, 'F');
$fltTextX = 12;
$strLogo = function_exists('fxBibDistPrintMs1LogoPath') ? fxBibDistPrintMs1LogoPath() : '';
if ($strLogo !== '') {
$fltLogoW = 34;
$this->Image($strLogo, 10, 9, $fltLogoW);
$this->Image($strLogo, 10, 8, $fltLogoW);
$fltTextX = 10 + $fltLogoW + 5;
}
$fltTextW = $fltW - $fltTextX - 10;
$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->SetXY($fltTextX, 5);
$this->SetFont('Arial', 'B', 13);
$this->Cell($fltTextW, 6, fxBibDistPrintPdfText($this->eventTitle), 0, 2, 'L');
$this->SetFont('Arial', 'B', 11);
$this->Cell($fltTextW, 5.5, fxBibDistPrintPdfText($this->documentTitle), 0, 2, 'L');
if ($blnHasSous) {
$strSousUp = function_exists('mb_strtoupper')
? mb_strtoupper($strSous, 'UTF-8')
: strtoupper($strSous);
$this->SetFont('Arial', 'B', 11);
$this->SetTextColor(255, 255, 255);
$this->MultiCell($fltTextW, 5, fxBibDistPrintPdfText($strSousUp), 0, 'L');
}
$this->SetTextColor(0, 0, 0);
$this->SetY(38);
$this->SetY($fltBandH + 6);
return;
}
@ -10224,13 +10236,16 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy =
$fltLogoH = $fltLogoW * (101 / 355); // ~6.3 mm (ratio logo MS1)
$fltGap = 4;
$fltPageNumW = 32;
$blnShowPage = !$this->blnIntroMode;
$fltLogoX = $fltPageW - $this->rMargin - $fltLogoW;
$fltLogoY = $fltPageH - 9.5;
$fltPageNumX = ($strLogo !== '')
$fltPageNumX = ($strLogo !== '' && $blnShowPage)
? ($fltLogoX - $fltGap - $fltPageNumW)
: ($fltPageW - $this->rMargin - $fltPageNumW);
$fltTextW = max(30, $fltPageNumX - $this->lMargin - 2);
: (($strLogo !== '')
? ($fltLogoX - $fltGap)
: ($fltPageW - $this->rMargin - ($blnShowPage ? $fltPageNumW : 0)));
$fltTextW = max(30, ($blnShowPage ? $fltPageNumX : $fltLogoX - $fltGap) - $this->lMargin - 2);
// Logo : fond noir pour garder le contraste (logo blanc sur noir).
if ($strLogo !== '') {
@ -10245,11 +10260,31 @@ function fxBibOutputDistPrintPdf($int_eve_id, $strLangue = 'fr', $strPrintedBy =
$this->SetX($this->lMargin);
$this->Cell($fltTextW, 4, fxBibDistPrintPdfText($this->footerText), 0, 0, 'L');
$strPage = sprintf($this->pageText, $this->PageNo(), '{nb}');
$this->SetXY($fltPageNumX, -11);
$this->Cell($fltPageNumW, 4, fxBibDistPrintPdfText($strPage), 0, 0, 'R');
// Pagination : absente sur les pages intro ; page 1 = 1re page de listes.
if ($blnShowPage) {
$intCur = max(1, $this->PageNo() - (int)$this->intIntroPageCount);
$strPage = sprintf($this->pageText, $intCur, '{nb}');
$this->SetXY($fltPageNumX, -11);
$this->Cell($fltPageNumW, 4, fxBibDistPrintPdfText($strPage), 0, 0, 'R');
}
$this->SetTextColor(0, 0, 0);
}
/**
* MSIN-4471 — {nb} = pages de listes seulement (hors intro).
*/
protected function _putpage($n) {
if (!empty($this->AliasNbPages) && (int)$this->intIntroPageCount > 0) {
$intNbList = max(0, $this->page - (int)$this->intIntroPageCount);
$this->pages[$n] = str_replace($this->AliasNbPages, (string)$intNbList, $this->pages[$n]);
$strSaved = $this->AliasNbPages;
$this->AliasNbPages = '';
parent::_putpage($n);
$this->AliasNbPages = $strSaved;
return;
}
parent::_putpage($n);
}
}
}

View File

@ -19,7 +19,7 @@ VALUES ('bib_v4_dist_print_doc', 'bib_dist_print', 'compte.php', 1, NOW());
-- FR
-- ---------------------------------------------------------------------------
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
('bib_dist_print', 'bib_dist_print_reco', 'fr', 'Conseils à la distribution', 'Pour une remise de dossards sans erreur',
('bib_dist_print', 'bib_dist_print_reco', 'fr', 'Conseils à la distribution', 'Pour une remise de dossards sans erreur — Responsable de la distribution des dossards',
'<article class="ms1-doc-article"><p><em>À lire avant de commencer.</em> Quelques secondes à chaque remise évitent les échanges, les erreurs de chronométrage et les résultats incorrects.</p><h3>1. Familles et groupes — plusieurs dossards</h3><p>Lorsque vous remettez plusieurs dossards à une même famille ou à un groupe, assurez-vous que le prénom figure sur chaque dossard. S''il n''y est pas déjà, <strong>écrivez-le au verso</strong>. Ainsi, chacun part avec le bon numéro : un échange entre proches fausse le chronométrage et les résultats.</p><h3>2. Ne pas céder son dossard</h3><p>Un dossard inscrit à un nom <strong>ne doit pas</strong> être remis à une autre personne. Si un échange a déjà eu lieu, <strong>avisez immédiatement les organisateurs</strong> afin qu''ils corrigent la base de données avant la course.</p><h3>3. Dossard bien visible à l''avant</h3><p>Rappelez au participant d''épingler son dossard <strong>bien visible à l''avant du torse</strong>. C''est essentiel pour un chronométrage fiable et un bon temps officiel.</p><h3>4. Vérifier ses infos avant la course (code QR)</h3><p>Invitez les participants à scanner le code QR de l''événement pour consulter les résultats en ligne <strong>avant le départ</strong>. Ils pourront confirmer que leur nom, leur âge et leur numéro de dossard sont correctement associés à leur inscription.</p></article>',
'compte.php', 10, 1, NOW()),
('bib_dist_print', 'bib_dist_print_table', 'fr', 'Votre dossard', 'À placer sur la table — pour les participants',
@ -33,7 +33,7 @@ INSERT INTO `doc_page` (`doc_mod_clef`, `doc_page_clef`, `doc_langue`, `doc_titr
-- EN
-- ---------------------------------------------------------------------------
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
('bib_dist_print', 'bib_dist_print_reco', 'en', 'Distribution tips', 'For a smooth, error-free bib handout',
('bib_dist_print', 'bib_dist_print_reco', 'en', 'Distribution tips', 'For a smooth, error-free bib handout — Bib distribution lead',
'<article class="ms1-doc-article"><p><em>Read before you start.</em> A few seconds at each handout prevent swaps, timing errors, and incorrect results.</p><h3>1. Families and groups — multiple bibs</h3><p>When handing out several bibs to the same family or group, make sure each bib shows a first name. If it is not already there, <strong>write it on the back</strong>. This way everyone leaves with the right number: a swap between relatives will skew timing and results.</p><h3>2. Do not give away your bib</h3><p>A bib registered under one name <strong>must not</strong> be given to someone else. If a swap has already happened, <strong>notify the organizers immediately</strong> so they can correct the database before the race.</p><h3>3. Bib clearly visible on the front</h3><p>Remind the participant to pin the bib <strong>clearly visible on the front of the torso</strong>. This is essential for reliable timing and an accurate official time.</p><h3>4. Check details before the race (QR code)</h3><p>Invite participants to scan the event QR code and view results online <strong>before the start</strong>. They can confirm that their name, age, and bib number are correctly linked to their registration.</p></article>',
'compte.php', 10, 1, NOW()),
('bib_dist_print', 'bib_dist_print_table', 'en', 'Your bib', 'Place on the table — for participants',