Skip to content

Transactions (TransactionManager)

Les transactions permettent de prendre un snapshot de l'état du document, rendre du contenu de manière spéculative, puis décider de conserver ou rejeter le résultat. C'est le mécanisme principal pour la logique de mise en page "try-fit".

Vue d'ensemble de l'API

MéthodeDescriptionRetourne
startTransaction()Prendre un snapshot de l'état actuel du documentstatic
commitTransaction()Rejeter le snapshot et conserver tous les changementsstatic
rollbackTransaction()Restaurer le document au snapshotstatic

Les trois méthodes retournent static pour le chaînage fluent.

Comment ça fonctionne

Lorsque vous appelez startTransaction(), le TransactionManager stocke une copie complète de l'état actuel du document — position curseur, nombre de pages, buffers de contenu et compteurs internes. Vous rendez ensuite le contenu normalement.

  • Commit rejette le snapshot stocké. Le contenu rendu reste dans le document.
  • Rollback remplace l'état actuel par le snapshot stocké. Tout rendu depuis startTransaction() est rejeté.

Exemple de base

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('Helvetica', '', 12);

// Essayer d'adapter un bloc sur la page actuelle
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->multiCell(0, 6, $longText);

if ($pdf->getPage() > $startPage) {
    // Le contenu a débordé sur la page suivante — rollback et essayer différemment
    $pdf->rollbackTransaction();
    $pdf->addPage();
    $pdf->multiCell(0, 6, $longText);
} else {
    // Le contenu tient — le conserver
    $pdf->commitTransaction();
}

Cas d'usage

Adapter le contenu dans un espace restant

Le cas d'usage le plus courant est de vérifier si le contenu tient sur la page actuelle avant de le valider :

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('Helvetica', '', 10);

foreach ($sections as $section) {
    $pdf->startTransaction();
    $startPage = $pdf->getPage();

    $pdf->setFont('Helvetica', 'B', 14)
        ->cell(0, 8, $section['title'], newLine: true)
        ->setFont('Helvetica', '', 10)
        ->multiCell(0, 5, $section['body']);

    if ($pdf->getPage() > $startPage) {
        $pdf->rollbackTransaction();
        $pdf->addPage();
        $pdf->setFont('Helvetica', 'B', 14)
            ->cell(0, 8, $section['title'], newLine: true)
            ->setFont('Helvetica', '', 10)
            ->multiCell(0, 5, $section['body']);
    } else {
        $pdf->commitTransaction();
    }
}

Mesurer la hauteur du contenu

Utiliser une transaction pour mesurer combien d'espace vertical le contenu consommera sans le placer réellement :

php
$pdf->startTransaction();
$startY = $pdf->getY();
$pdf->multiCell(0, 5, $text);
$endY = $pdf->getY();
$height = $endY - $startY;
$pdf->rollbackTransaction();

// Maintenant utiliser $height pour les décisions de mise en page

Contraintes importantes

Pas d'imbrication

Les transactions imbriquées ne sont pas supportées. Appeler startTransaction() alors qu'une transaction est déjà active lèvera une exception. Toujours commit ou rollback avant de démarrer une nouvelle transaction.

Impact sur les performances

Une transaction stocke un snapshot complet de l'état du document. Pour les documents avec de nombreuses pages et de gros buffers de contenu, cela peut temporairement doubler l'utilisation mémoire. Gardez les blocs de transaction aussi petits que possible — snapshot, rendu, décision, puis commit ou rollback immédiatement.

Bonnes pratiques

  • Gardez le code entre startTransaction() et commitTransaction() / rollbackTransaction() minimal.
  • Assurez-vous toujours que chaque startTransaction() est apparié avec exactement un commitTransaction() ou rollbackTransaction().
  • N'effectuez pas d'I/O fichier ou envoi de sortie dans un bloc de transaction — seules les mutations de document peuvent être rollback.
  • Préférez mesurer de petites sections plutôt qu'envelopper toute la génération de document dans une transaction.

Distribué sous licence LGPL-3.0-or-later.