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

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

استخدم هذه الوصفة لإضافة ثلاثة عناصر تفاعلية: رابط داخلي ينقلك إلى صفحة أخرى، ورابط خارجي يفتح محدد موقع المورد الموحد (⁨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⁩) الخاصة بالقارئ، لذا حدّد طول محتوى الملاحظة الخاضع لتحكم المستخدم ونقّه. لا يحدث أي تحليل للمدخلات ولا أي وصول إلى الشبكة في هذه الوصفة.

البيانالمواصفةالبند⁨reference_id⁩
تعليق الرابط هو رابط نص تشعبي إلى وجهة أو إجراء.⁨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.⁩