Aggiungere collegamenti e annotazioni di testo
In breve
Sezione intitolata “In breve”Questa ricetta aggiunge tre elementi interattivi: un collegamento interno che rimanda a un’altra pagina, un collegamento esterno che apre un URL e un’annotazione di testo, detta anche nota adesiva. Segue examples/17-links.php e examples/29-annotations.php.
Nel modello ISO 32000-2, un collegamento cliccabile è un’annotazione di collegamento, cioè un collegamento ipertestuale a una destinazione o a un’azione. Una nota adesiva è un’annotazione di testo: mostra un’icona quando è chiusa e un popup quando è aperta.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Non è richiesta alcuna estensione facoltativa. L’API per collegamenti e annotazioni è stabile fin dalla versione 1.0.0 e funziona nell’intera matrice di backport 8.1–8.4.
Panoramica concettuale
Sezione intitolata “Panoramica concettuale”I collegamenti interni usano uno schema a tre chiamate che supporta i riferimenti in avanti:
addLink()riserva un identificatore di collegamento (un int).link($x, $y, $w, $h, $id)posiziona un rettangolo cliccabile associato a quell’ID.setLink($id, $pageIndex, $y)associa l’ID a una pagina di destinazione (a base zero) e a Y.
Per collegarsi a una pagina che non esiste ancora, chiamare il passaggio 3 dopo il passaggio 2. La destinazione usa una forma di destinazione esplicita. ISO 32000-2 §12.3.2.2 definisce [page /XYZ left top zoom], in cui un componente null mantiene il valore corrente del lettore.
Per un collegamento esterno, passare una stringa URL a link() anziché un int. NextPDF emette quindi un’azione URI il cui URI è una stringa ASCII UTF-8 obbligatoria. Per praticità, write($height, $text, $link) disegna testo in linea con un URL associato e annotation($x, $y, $w, $h, $text) posiziona una nota adesiva di sottotipo Text. ISO 32000-2 richiede SubtypeLink per un’annotazione di collegamento e definisce l’icona e il comportamento del popup dell’annotazione di testo.
Superficie dell’API
Sezione intitolata “Superficie dell’API”La superficie dell’API viene generata automaticamente da PHPDoc. Questa ricetta si basa sui metodi seguenti:
addLink(): int— riserva un identificatore di collegamento interno.setLink(int $linkId, int $pageIndex = -1, float $y = 0): static— associa un ID a una pagina di destinazione (a base zero) e a Y.link(float $x, float $y, float $w, float $h, string|int $link): static— rettangolo cliccabile; un ID int è interno, una stringa è un URL esterno.write(float $height, string $text, string $link = ''): static— testo in linea con un URL facoltativo.annotation(float $x, float $y, float $w, float $h, string $text, string $subtype = 'Text'): static— annotazione con nota adesiva.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$jump = $doc->addLink(); // 1. reserve an id (forward reference)
$doc->addPage();$doc->setFont('helvetica', 'B', 12);$x = $doc->getX();$y = $doc->getY();$doc->cell(60, 10, 'Go to page 2', newLine: true);$doc->link($x, $y, 60, 10, $jump); // 2. clickable rectangle -> id
$doc->link($doc->getX(), $doc->getY(), 80, 10, 'https://nextpdf.dev'); // external
$doc->addPage();$doc->setLink($jump, pageIndex: 1, y: 0); // 3. bind id to page 2 (index 1)$doc->cell(0, 10, 'Destination (page 2).', newLine: true);$doc->annotation(x: 180, y: 20, w: 10, h: 10, text: 'A reviewer note.');
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/links.pdf');Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo è l’esempio completo pronto per l’harness. Rispetta NEXTPDF_COOKBOOK_OUTPUT e non introduce entropia propria.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Links and Annotations');
// Reserve the internal-link id before its destination page exists.$linkToPage3 = $doc->addLink();
// Page 1 — source of the internal and external links.$doc->addPage();$doc->setFont('helvetica', 'B', 20);$doc->cell(0, 14, 'Links and Annotations', newLine: true);$doc->ln(6);
$doc->setFont('helvetica', 'B', 12);$doc->setTextColor(0, 51, 153);$linkX = $doc->getX();$linkY = $doc->getY();$doc->cell(60, 10, 'Go to Page 3', newLine: true);$doc->link($linkX, $linkY, 60, 10, $linkToPage3); // internal: int id$doc->setTextColor(0);$doc->ln(6);
$doc->setFont('helvetica', 'B', 12);$doc->setTextColor(0, 102, 204);$doc->write(10, 'Visit https://nextpdf.dev', link: 'https://nextpdf.dev');$doc->setTextColor(0);$doc->ln(6);
$urlX = $doc->getX();$urlY = $doc->getY();$doc->cell(80, 10, 'NextPDF on GitHub', newLine: true);$doc->link($urlX, $urlY, 80, 10, 'https://github.com/nextpdf-labs/nextpdf');
// Page 2 — intermediate.$doc->addPage();$doc->setFont('helvetica', '', 11);$doc->multiCell(0, 7, 'Internal links can jump across pages; this page is ' . 'skipped by the link on page 1.');
// Page 3 — destination + a sticky note.$doc->addPage();$doc->setLink($linkToPage3, pageIndex: 2, y: 0); // bind id to page 3 (index 2)$doc->setFont('helvetica', 'B', 18);$doc->cell(0, 14, 'Page 3 — Link Target', newLine: true);$doc->ln(4);$doc->setFont('helvetica', '', 11);$doc->multiCell(0, 7, 'You arrived via the internal link on page 1.');$doc->annotation( x: 185, y: 40, w: 10, h: 10, text: 'Sticky note: appears as an icon; click to read this text.',);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/links.pdf';$doc->save($out);
echo "Created links.pdf\n";Casi limite e insidie
Sezione intitolata “Casi limite e insidie”pageIndexè a base zero.setLink($id, pageIndex: 2, …)punta alla terza pagina. Un errore di off-by-one qui è l’errore più comune.- String vs. int in
link(). Un int è un ID di destinazione interna restituito daaddLink(). Una stringa è un URL esterno. Passare il tipo errato produce il tipo di collegamento sbagliato senza generare alcun errore. - Associare ogni ID riservato. Un ID di
addLink()che non viene mai associato tramitesetLink()non ha alcuna destinazione. Il rettangolo è cliccabile ma inerte. Associarlo prima disave(). - L’area cliccabile è il rettangolo, non il testo.
link()richiede valori espliciti dix, y, w, h. Dimensionarlo in modo che copra il testo visibile. Il motore non misura i glifi automaticamente. - I collegamenti esterni non vengono convalidati. NextPDF memorizza l’URI letteralmente. Non verifica che la destinazione sia risolvibile o sicura. È il lettore a risolverla.
Prestazioni
Sezione intitolata “Prestazioni”Ogni collegamento o annotazione aggiunge un dizionario di annotazione alla pagina. Il costo è O(1) per elemento. Anche centinaia di elementi per pagina restano ampiamente entro il budget di 2000 ms / 64 MB.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Le destinazioni dei collegamenti esterni vengono memorizzate letteralmente e risolte dal lettore, non dalla libreria. Considerare gli URL forniti dall’utente come non attendibili. Inserire lo schema in allowlist, in genere https. Rifiutare javascript: e file: prima di passarli a link(). Il testo dell’annotazione viene mostrato nell’interfaccia del lettore, pertanto è necessario limitarne la lunghezza e sanitizzare il contenuto delle note controllato dall’utente. In questa ricetta non avviene alcun parsing di input né accesso alla rete.
Conformità
Sezione intitolata “Conformità”| Dichiarazione | Specifica | Clausola | reference_id |
|---|---|---|---|
| Un’annotazione di collegamento è un collegamento ipertestuale a una destinazione o a un’azione. | ISO 32000-2 | §12.5.6.5 | |
Subtype è Link per un’annotazione di collegamento. | ISO 32000-2 | §12.5.6.5 | |
L’URI di un’azione URI è una stringa ASCII UTF-8 obbligatoria. | ISO 32000-2 | §12.6.4.8 | |
| Un’annotazione di testo è una nota adesiva (chiusa = icona, aperta = popup). | ISO 32000-2 | §12.5.6.4 | |
Destinazione esplicita [page /XYZ left top zoom]; null mantiene il valore corrente. | ISO 32000-2 | §12.3.2.2 |
Profilo di riproducibilità — strutturale. Gli atomi /ID del trailer e gli atomi di data variano a ogni salvataggio. L’harness rimuove tali atomi e quindi confronta la struttura normalizzata con qpdf. Questa ricetta descrive come NextPDF produce la struttura. Non formula una dichiarazione generale di conformità a ISO 32000-2.
Contesto commerciale
Sezione intitolata “Contesto commerciale”Non applicabile. I collegamenti e le annotazioni di testo sono funzionalità di Core senza vincoli Premium.