تخطَّ إلى المحتوى
getnextpdf.com

إضافة الروابط والتعليقات النصية

استخدم هذه الوصفة لإضافة ثلاثة عناصر تفاعلية: رابط داخلي ينقلك إلى صفحة أخرى، ورابط خارجي يفتح محدد موقع المورد الموحد (⁨URL⁩)، وتعليق نصي يُعرف أيضًا باسم ملاحظة لاصقة. وهي تستند إلى examples/17-links.php وexamples/29-annotations.php.

الرابط القابل للنقر هو تعليق رابط وفق ⁨ISO 32000-2⁩: رابط نص تشعبي إلى وجهة أو إجراء. أما الملاحظة اللاصقة فهي تعليق نصي يظهر على شكل أيقونة عند الإغلاق، وعلى شكل نافذة منبثقة عند الفتح.

Terminal window
composer require nextpdf/core:^3

لا يلزم أي امتداد اختياري. واجهة برمجة التطبيقات (⁨API⁩) الخاصة بالروابط والتعليقات مستقرة منذ ⁨1.0.0⁩، وتعمل على مصفوفة النقل الخلفي ⁨8.1⁩–8.4.

تستخدم الروابط الداخلية نمطًا مكوّنًا من ثلاثة استدعاءات يدعم المراجع الأمامية:

  1. addLink() يحجز معرّف رابط (عدد صحيح ⁨int⁩).
  2. link($x, $y, $w, $h, $id) يضع مستطيلًا قابلًا للنقر مرتبطًا بذلك المعرّف.
  3. setLink($id, $pageIndex, $y) يربط المعرّف بصفحة وجهة (يبدأ ترقيمها من الصفر) وبالإحداثي ⁨Y.⁩

استدعِ الخطوة 3 بعد الخطوة 2 عند الربط بصفحة لم تُنشأ بعد. تستخدم الوجهة صيغة وجهة صريحة. يعرّف ⁨ISO 32000-2⁩ §12.3.2.2 الصيغة [page /XYZ left top zoom]، حيث يحتفظ المكوّن الفارغ (⁨null⁩) بالقيمة الحالية لدى القارئ.

لإنشاء رابط خارجي، مرّر سلسلة نصية لمحدد ⁨URL⁩ إلى link() بدلًا من عدد صحيح ⁨int.⁩ عندئذٍ يُصدر ⁨NextPDF⁩ إجراء معرّف المورد الموحد (⁨URI⁩)، ويكون URI الخاص به سلسلة ⁨ASCII⁩ مطلوبة بترميز ⁨UTF-8.⁩ وكاختصار، ترسم write($height, $text, $link) نصًا مضمّنًا مع محدد ⁨URL⁩ مرفق، وتضع annotation($x, $y, $w, $h, $text) ملاحظة لاصقة من النوع الفرعي Text. يتطلب ⁨ISO 32000-2⁩ القيمة SubtypeLink لتعليق الرابط، ويعرّف سلوك أيقونة التعليق النصي والنافذة المنبثقة.

تُولَّد واجهة ⁨API⁩ من ⁨PHPDoc.⁩ وتعتمد هذه الوصفة على الطرق التالية:

  • addLink(): int — يحجز معرّف رابط داخلي.
  • setLink(int $linkId, int $pageIndex = -1, float $y = 0): static — يربط معرّفًا بصفحة وجهة (يبدأ ترقيمها من الصفر) وبالإحداثي ⁨Y.⁩
  • link(float $x, float $y, float $w, float $h, string|int $link): static — ينشئ مستطيلًا قابلًا للنقر؛ يكون المعرّف من نوع ⁨int⁩ داخليًا، وتكون السلسلة النصية محدد ⁨URL⁩ خارجيًا.
  • write(float $height, string $text, string $link = ''): static — يكتب نصًا مضمّنًا مع محدد ⁨URL⁩ اختياري.
  • annotation(float $x, float $y, float $w, float $h, string $text, string $subtype = 'Text'): static — يضيف تعليقًا على شكل ملاحظة لاصقة.
<?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');

هذا هو المثال الكامل الجاهز لإطار الاختبار. وهو يراعي NEXTPDF_COOKBOOK_OUTPUT ولا يضيف أي عشوائية من تلقاء نفسه.

<?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";
  • pageIndex يبدأ ترقيمه من الصفر. يستهدف setLink($id, pageIndex: 2, …) الصفحة الثالثة. وأخطاء الانحراف بمقدار واحد هنا هي الأكثر شيوعًا.
  • السلسلة النصية مقابل العدد الصحيح ⁨int⁩ في link(). العدد الصحيح ⁨int⁩ هو معرّف وجهة داخلية من addLink(). أما السلسلة النصية فهي محدد ⁨URL⁩ خارجي. إذا مرّرت النوع الخاطئ، فستحصل على النوع الخاطئ من الروابط دون ظهور أي خطأ.
  • اربط كل معرّف محجوز. أي معرّف من addLink() لا تربطه أبدًا باستخدام setLink() لن تكون له وجهة. سيبقى المستطيل قابلًا للنقر لكنه خامل. اربطه قبل save().
  • المنطقة القابلة للنقر هي المستطيل وليست النص. تأخذ link() القيم x, y, w, h صراحةً. حدّد أبعاده بحيث يغطي النص المرئي. فالمحرك لا يقيس المحارف نيابةً عنك.
  • الروابط الخارجية لا يجري التحقق منها. يخزّن ⁨NextPDF⁩ معرّف ⁨URI⁩ حرفيًا. ولا يتحقق من أن الهدف قابل للوصول أو آمن؛ فالقارئ هو من يحلّه.

يضيف كل رابط أو تعليق قاموس تعليق واحدًا إلى الصفحة. والتكلفة هي ⁨O⁩(1) لكل عنصر. ويبقى وجود المئات في كل صفحة ضمن ميزانية 2000 ⁨ms⁩ / 64 ⁨MB⁩ بهامش مريح.

تُخزَّن أهداف الروابط الخارجية حرفيًا، ويحلّها القارئ لا المكتبة. تعامل مع محددات ⁨URL⁩ التي يوفّرها المستخدم على أنها غير موثوقة. أدرج المخطط في قائمة السماح، ويكون عادةً https. ارفض javascript: وfile: قبل تمريرهما إلى link(). يظهر نص التعليق في واجهة المستخدم (⁨UI⁩) الخاصة بالقارئ، لذا حدّد طول محتوى الملاحظة الخاضع لتحكم المستخدم ونقّه. لا يحدث أي تحليل للمدخلات ولا أي وصول إلى الشبكة في هذه الوصفة.

البيانالمواصفةالبند
تعليق الرابط هو رابط نص تشعبي إلى وجهة أو إجراء.⁨ISO 32000-2⁩§12.5.6.5
تكون Subtype هي Link لتعليق الرابط.⁨ISO 32000-2⁩§12.5.6.5
يكون URI الخاص بإجراء ⁨URI⁩ سلسلة ⁨ASCII⁩ مطلوبة بترميز ⁨UTF-8.⁩⁨ISO 32000-2⁩§12.6.4.8
التعليق النصي هو ملاحظة لاصقة (مغلق = أيقونة، مفتوح = نافذة منبثقة).⁨ISO 32000-2⁩§12.5.6.4
وجهة صريحة [page /XYZ left top zoom]؛ يحتفظ ⁨null⁩ بالقيمة الحالية.⁨ISO 32000-2⁩§12.3.2.2

ملف قابلية إعادة الإنتاج — بنيوي. تتغير ذرّات /ID في المُذيَّل والتاريخ في كل عملية حفظ. يزيل إطار الاختبار تلك الذرّات، ثم يقارن البنية المُطبَّعة بواسطة ⁨qpdf.⁩ تصف هذه الوصفة كيف يُنتج ⁨NextPDF⁩ هذه البنية. وهي لا تؤكد المطابقة لـ ⁨ISO 32000-2⁩ بوصفها ادعاءً شاملًا.

غير منطبق. الروابط والتعليقات النصية هي قدرات في ⁨Core⁩ دون أي بوابة ⁨Premium.⁩