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

تمهيد compat-legacy واكتشافه في NextPDF

توفّر nextpdf/compat-legacy الواجهة NextPDF\Compat\Tcpdf\TCPDF، وهي واجهة متوافقة مع ⁨TCPDF⁩ تفوّض العمل إلى محرّك ⁨NextPDF.⁩ هذه طبقة توافق، وليست بديلًا جاهزًا للاستبدال المباشر. تفوّض مباشرةً 94 من نحو 120 طريقة من طرائق ⁨TCPDF 6.x⁩ التي جرى استقصاؤها. أما الطرائق المتبقية فلها فروق سلوكية موثّقة؛ راجع /⁨integrations/tcpdf-compat/method-coverage/.⁩

لا يوجد ربط عام أثناء التحميل التلقائي. لا يؤدّي استدعاء الحزمة عبر ⁨require⁩ إلى إنشاء فئة عامة \TCPDF افتراضيًا. فعّل الأسماء البديلة العامة صراحةً إذا احتجت إليها، أو استورد فئة المُهايئ في كل ملف على حدة، وهو الخيار الأفضل أثناء الترحيل.

الواجهة فئة قياسية مُحمَّلة تلقائيًا وفق توصية ⁨PHP⁩ القياسية رقم 4 (⁨PSR-4⁩):

العنصرالقيمة
فئة الواجهةNextPDF\Compat\Tcpdf\TCPDF
بادئة ⁨PSR-4⁩تُربط NextPDF\Compat\Tcpdf\ بالمسار src/Compat/Tcpdf/
العقد المشتركNextPDF\Compat\Contracts\CompatAdapterInterface
مخرج اضطراريتُعيد TCPDF::getDocument() كائن NextPDF\Core\Document المُغلَّف

الفئة عمدًا ليست final. كثيرًا ما يشتقّ مستخدمو ⁨TCPDF⁩ القديمة فئات فرعية من TCPDF لتجاوز Header() وFooter()، ويحافظ المُهايئ على نقطة التوسعة هذه. داخليًا، تعمل الفئة كواجهة. فهي تركّب 25 سمة أحادية المسؤولية، وتفوّض جميع عمليات تنسيق ملفات ⁨PDF⁩ إلى كائن Document يُنشأ عند بناء الواجهة.

Composer autoload

Class referenced: new TCPDF or new global TCPDF

Constructor runs

LegacyDefaults::register defines K_/PDF_ constants if absent

ConstructorBridge::build maps orientation/unit/format to Document

Document, UnitConverter, PageSize stored on the facade

Creator/Author seeded from PDF_CREATOR / PDF_AUTHOR

Diagram

الإنشاء هو خطوة “التمهيد” الوحيدة. الحزمة نفسها لا تسجّل أي حاوية خدمات ولا تنفّذ أي تمهيد لإطار عمل. تأتي تكاملات إطار العمل كطبقة رقيقة؛ راجع /⁨integrations/tcpdf-compat/integration/.⁩

LegacyDefaults::register() عملية متكرّرة الأثر (⁨idempotent⁩): فهي تعرّف الثابت فقط عندما لا يكون معرَّفًا مسبقًا. تكون للثوابت المعرَّفة في التطبيق الأولوية دائمًا إذا عرّفتها قبل أول إنشاء؛ راجع /⁨integrations/tcpdf-compat/configuration/⁩ § ترتيب حلّ الإعدادات.

الأسماء البديلة العامة للفئات الاختيارية

قسم بعنوان «الأسماء البديلة العامة للفئات الاختيارية»

إذا كانت شيفرتك تستدعي new \TCPDF(...) في مساحة الأسماء العامة ولم يتسنّ لك بعد تغيير مواضع الاستدعاء هذه، فسجّل الأسماء البديلة العامة مرة واحدة أثناء تمهيد التطبيق:

examples/boot-aliases.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\LegacyBootstrap;
LegacyBootstrap::enableAliases();
// Global names now resolve to the adapter:
$pdf = new \TCPDF('P', 'mm', 'A4');

تسجّل enableAliases() كلًّا من \TCPDF و\TCPDF_STATIC و\TCPDF_FONTS و\TCPDF_COLORS و\TCPDF_IMAGES. ويؤكّد tests/Unit/Compat/Tcpdf/LegacyBootstrapTest.php هذا السلوك:

  • إنها متكرّرة الأثر: فاستدعاؤها مرتين لا يطرح استثناءً ولا يسجّل إلا مرة واحدة.
  • تُبلغ LegacyBootstrap::isRegistered() عمّا إذا كانت قد نُفّذت.
  • بعد التسجيل، تُنشئ new \TCPDF() كائنًا من المُهايئ.

تجنّب التعارض مع تثبيت ⁨TCPDF⁩ فعلي

قسم بعنوان «تجنّب التعارض مع تثبيت ⁨TCPDF⁩ فعلي»

هذه هي أهم قاعدة في هذه الصفحة.

تسجّل enableAliases() اسمًا بديلًا فقط إذا لم تكن هناك فئة بهذا الاسم موجودة بالفعل (class_exists($alias, autoload: false)). لذلك:

  • إذا كانت tecnickcom/tcpdf مثبَّتة وحُمِّلت فئة \TCPDF الخاصة بها أولًا، فسيُتجاوز الاسم البديل بصمت، وستظل شيفرتك تستخدم ⁨TCPDF⁩ القديمة بدلًا من المُهايئ.
  • تشغيل كلتا المكتبتين مع تفعيل الأسماء البديلة العامة في العملية نفسها غير مدعوم، وينتج عنه سلوك غامض.

أثناء الترحيل، فضّل الاستيراد الصريح في كل ملف (use NextPDF\Compat\Tcpdf\TCPDF;). فهذه الاستيرادات سهلة البحث وغير ملتبسة. أزل tecnickcom/tcpdf بمجرّد اجتياز تدقيق الوضع الصارم؛ راجع /⁨integrations/tcpdf-compat/migration/⁩ المرحلة 5. إذا حُلّت \TCPDF إلى الفئة الخطأ، فستجد التشخيص في /⁨integrations/tcpdf-compat/troubleshooting/.⁩

لا تتضمّن الحزمة روابط حاوية لإطار العمل. إذا ربطت الواجهة في حاوية، فاربط مصنعًا يُعيد كائن NextPDF\Compat\Tcpdf\TCPDF جديدًا لكل مستند. حالة المستند خاصة بكل كائن، ويجب ألّا تُشارَك بين مستندات غير مترابطة؛ راجع /⁨integrations/tcpdf-compat/production-usage/⁩ § التزامن. يعرض /⁨integrations/tcpdf-compat/integration/⁩ ربطًا نموذجيًا.

عند الإنشاء، يحلّ المُهايئ الإعدادات بهذا الترتيب: وسائط المُنشئ أولًا، ثم أي ثوابت قديمة معرَّفة في التطبيق إن وُجدت، ثم قيم LegacyDefaults الافتراضية الخاصة بـ ⁨TCPDF 6.2.13⁩ لأي ثابت لم يُعرَّف بعد. للاطّلاع على التفاصيل الكاملة وكائن AdaptationConfig الحديث، راجع /⁨integrations/tcpdf-compat/configuration/.⁩

للتأكّد من أن الواجهة موصولة وأن الربط بالمحرّك يُحَلّ، أنشئ مُهايئًا، وأنتج ملف ⁨PDF⁩ من صفحة واحدة، وتحقّق من البادئة %PDF. تؤكّد اختبارات إخراج الحزمة السطح نفسه. يوجد التحقّق القابل للتشغيل في /⁨integrations/tcpdf-compat/install/⁩ § التحقّق من التثبيت.

لاكتشاف تعارض مع ⁨TCPDF⁩ فعلي قبل تفعيل الأسماء البديلة، تحقّق مما إذا كانت فئة عامة \TCPDF موجودة بالفعل في الموضع الذي تنوي فيه استدعاء enableAliases(). إذا وُجدت، فسيُتجاوز الاسم البديل. حُلّ التعارض بالاستيراد الصريح، أو أزل ⁨TCPDF⁩ الفعلي قبل أن تعتمد على المُهايئ.

تغطية واجهة ⁨TCPDF⁩ البرمجية

قسم بعنوان «تغطية واجهة ⁨TCPDF⁩ البرمجية»

مصفوفة التغطية المرجعية المُتحقَّق منها بالاختبارات هي الملف الموجود داخل المستودع docs/TCPDF_COVERAGE.md. أما الملخّص المُوجَّه للقارئ، بما في ذلك قائمتا الطرائق المُتجاهَلة بصمت وغير المُنفَّذة، فهو /⁨integrations/tcpdf-compat/method-coverage/.⁩ لا تدّعي هذه الحزمة أنها “بديل جاهز للاستبدال المباشر” أو “متوافقة مع ⁨TCPDF⁩ بنسبة 100%”؛ بل هي بديل متوافق مع ⁨TCPDF⁩ بسطح توافق معروف ومُختبَر وفروق سلوكية موثّقة.

  • docs/TCPDF_COVERAGE.md — مصدر التغطية المرجعي (داخل المستودع)
  • /⁨integrations/tcpdf-compat/integration/⁩ — وصل الواجهة داخل ⁨application/framework⁩
  • /⁨integrations/tcpdf-compat/method-coverage/⁩ — سلوك كل طريقة وثغراتها
  • /⁨integrations/tcpdf-compat/migration/⁩ — استراتيجية ترحيل متدرّجة
  • /⁨integrations/tcpdf-compat/troubleshooting/⁩ — تشخيص تعارض ⁨alias/real-TCPDF⁩
  • tests/Unit/Compat/Tcpdf/LegacyBootstrapTest.php — مرجع سلوك الأسماء البديلة