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

تغطية دوال TCPDF في طبقة توافق NextPDF compat-legacy

nextpdf/compat-legacy هو طبقة توافق، وليس نسخةً متفرّعة من ⁨TCPDF⁩ ولا نسخةً تضمن السلوك نفسه. فهو يكشف أسماء دوال ⁨TCPDF 6.x⁩ العامة وترتيب معاملاتها وقيمها الافتراضية فوق محرّك ⁨NextPDF⁩ الأساسي. وتُربَط معظم الاستدعاءات مباشرةً بعملية Document في ⁨NextPDF.⁩ أمّا القليل المحدَّد منها فيقبل معاملاتٍ قديمة لا يحترمها ⁨NextPDF⁩ أو لا أثر لها.

تلخّص هذه الصفحة تدقيق الدوال دالةً بدالة للقرّاء. أمّا مصفوفة التغطية المرجعية المتحقَّق منها بالاختبارات فموجودة في المستودع ضمن docs/TCPDF_COVERAGE.md. وإذا اختلفت هذه الصفحة عن المصفوفة الموجودة في المستودع، فمصفوفة المستودع هي المرجِع لأنها مثبتة بمجموعة الاختبارات.

استخدم هذه الصفحة للإجابة عن سؤال واحد قبل الترحيل: لكل دالة ⁨TCPDF⁩ تستدعيها قاعدة شفرتك، ماذا يفعل المحوّل فعليًّا؟

شمل التدقيق نحو 120 دالة عامة في ⁨TCPDF 6.x.⁩ وصُنِّفت كل دالة في فئة واحدة بالضبط من أربع فئات.

الفئةالعددماذا يعني ذلك لك
مطابِقة — مفوَّضة بالكامل94يُربَط الاستدعاء مباشرةً بدالة Document في ⁨NextPDF.⁩ ويكون السلوك متوافقًا للمعاملات الموثَّقة.
تجاهُل صامت — جزئية15تُنفَّذ الدالة وتُنتِج مخرجات، لكن معاملًا واحدًا أو أكثر من معاملات ⁨TCPDF⁩ لا يكون له أثر. وهذا فرق سلوكي موثَّق.
غير منفَّذة — جسم لا يفعل شيئًا4الدالة موجودة لأجل توافق الشفرة المصدرية لكنها لا تفعل شيئًا.
غير منطبِقة7ليس لدالة ⁨TCPDF⁩ أثر في مخرجات ⁨PDF⁩؛ مُستبعَدة عن قصد.
دوال انحراف الواجهة الحديثة المضافة17دوال ⁨Document⁩ من ⁨NextPDF v5.1⁩+ مكشوفة على المحوّل كي تُصرَّف الشفرة التي تخلط بين الواجهات. وليس لهذه الدوال نظيرٌ في ⁨TCPDF 6.x.⁩

تأتي هذه الأرقام من docs/TCPDF_COVERAGE.md §Summary. وتتحقّق مجموعة الاختبارات من المصفوفة عبر tests/Unit/Compat/Tcpdf/TcpdfApiDriftTest.php وtests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php.

ملاحظة بشأن الصياغة. لا تدّعي هذه الحزمة أنها “بديل جاهز للاستبدال ” ولا أنها “متوافقة 100% مع ⁨TCPDF⁩”. فهي تغطّي 94 من دوال ⁨TCPDF⁩ المشمولة بالمسح، والبالغ عددها نحو 120 دالة، عبر التفويض المباشر. أمّا الدوال المتبقّية فلها فروق سلوكية موثَّقة موضَّحة أدناه. والوصف الدقيق هو بديل متوافق مع ⁨TCPDF⁩ بسطح توافق *معروف ومختبَر *.

بُني المحوّل من 25 سمة (⁨trait⁩) ذات مسؤولية واحدة (src/Compat/Tcpdf/Concerns/) تكشف 273 دالة عامة في المجموع، إلى جانب عدد قليل من دوال دورة الحياة ودوال مَخرَج الطوارئ على صنف TCPDF نفسه. تَعُدّ فئات التغطية أعلاه دوال سطح واجهة ⁨TCPDF 6.x⁩ المتمايزة (نحو 120)، لا إجمالي عدد دوال المحوّل العامة. فالرقمان يقيسان أمرين مختلفين: تغطية سطح الواجهة وحجم التنفيذ. وإذا أورد README.md الخاص بالحزمة عددًا أصغر من السمات أو الدوال، فاعتبِر docs/TCPDF_COVERAGE.md وهذه الصفحة هما المرجِع. فملخّص ⁨README⁩ يسبق سمة AdaptsDriftV51.

1. الدوال المطابِقة — تفويض متوافق

قسم بعنوان «1. الدوال المطابِقة — تفويض متوافق»

تُربَط أربعٌ وتسعون دالة مباشرةً بنسخة NextPDF\Core\Document الأساسية. وتُربَط أسماء ⁨TCPDF⁩ بنمط ⁨PascalCase⁩ بأسماء ⁨NextPDF⁩ بنمط ⁨camelCase⁩ حيث يستخدم المحرّك ⁨camelCase.⁩ ويقبل المحوّل الصيغتين دعمًا للتوافق الأمامي والخلفي.

مجموعات تمثيلية (الجدول الكامل: docs/TCPDF_COVERAGE.md §1):

مجال ⁨TCPDF⁩أمثلة على الدوالسمة المحوّل
دورة الحياةOutput(), Close(), getPDFData()AdaptsLifecycle
الصفحاتAddPage(), getNumPages(), deletePage()AdaptsPageManagement
النصCell(), MultiCell(), Write(), Text(), Ln()AdaptsTextOutput
الخطوطSetFont(), SetFontSize(), AddFont()AdaptsFonts
الألوانSetTextColor(), SetDrawColor(), SetFillColor()AdaptsColors
الرسمLine(), Rect(), Circle(), Polygon(), Arrow()AdaptsDrawing
التحويلاتRotate(), Scale(), Translate(), Skew(), Mirror*()AdaptsTransforms
التنقّلAddLink(), Annotation(), addTOC()AdaptsNavigation

بالنسبة لهذه الدوال، يكون السلوك المرصود متوافقًا مع ⁨TCPDF 6.x⁩ للمعاملات التي يوثّقها ⁨NextPDF.⁩ ولا يؤكّد المحوّل تطابُق مخرجات ⁨PDF⁩ على مستوى البايت. فالمحرّك الأساسي تنفيذٌ مستقل لـ ⁨PDF 2.0⁩، ولذلك قد تختلف البايتات حتى عند تكافؤ النتيجة المرئية. وإذا كانت اختباراتك تؤكّد بايتات ⁨PDF⁩ بدقة بدلًا من المحتوى المعروض، فتوقَّع إعادة ضبط تلك التأكيدات. انظر /⁨integrations/tcpdf-compat/migration/⁩ للاطّلاع على إستراتيجية إعادة الضبط الموصى بها.

2. الدوال المتجاهِلة بصمت — فروق سلوكية موثَّقة

قسم بعنوان «2. الدوال المتجاهِلة بصمت — فروق سلوكية موثَّقة»

تُنفَّذ هذه الدوال الخمس عشرة وتُنتِج مخرجات، لكن يُقبَل معامل ⁨TCPDF⁩ واحد على الأقل لأجل توافق الشفرة المصدرية ثم يُتجاهَل. اقرأ هذا القسم قبل الترحيل. فهذه الاستدعاءات لا تفشل؛ لكنها تنفّذ بصمت أقل ممّا ينفّذه ⁨TCPDF⁩ الأصلي.

دالة ⁨TCPDF⁩المعاملات المتجاهَلةالبديل المتوافق
Image()⁨type⁩, ⁨link⁩, ⁨align⁩, ⁨resize⁩, ⁨dpi⁩, ⁨palign⁩, ⁨ismask⁩, ⁨imgmask⁩, ⁨border⁩, ⁨fitbox⁩, ⁨hidden⁩, ⁨fitonpage⁩, ⁨alt⁩, ⁨altimgs⁩تأخذ دالة image() في ⁨NextPDF⁩ المعاملات ⁨file⁩ و⁨x⁩ و⁨y⁩ و⁨width⁩ و⁨height.⁩ وللحصول على صورة قابلة للنقر، ارسم الصورة ثم أضِف Document::link() فوق المستطيل نفسه. أمّا إخفاء الصورة (⁨masking⁩) والصور البديلة فغير مدعومَين.
writeHTML()⁨ln⁩, ⁨fill⁩, ⁨reseth⁩, ⁨cell⁩, ⁨align⁩دالة writeHtml() في ⁨NextPDF⁩ مخصَّصة للمحتوى فقط. للتحكّم في التخطيط، غلِّف ⁨HTML⁩ داخل كتلة محدَّدة الموضع عبر الواجهة الحديثة.
writeHTMLCell()⁨border⁩ (الصيغة النصية)، ⁨ln⁩، ⁨fill⁩، ⁨reseth⁩، ⁨autopadding⁩تُحترَم العرض والارتفاع والموضع والحدّ المنطقي (⁨boolean⁩)؛ أمّا تخطيط الخلية الأكثر تفصيلًا فلا يقابله ربط.
ImageEps()⁨link⁩, ⁨useBoundingBox⁩, ⁨align⁩, ⁨palign⁩, ⁨border⁩, ⁨fitonpage⁩, ⁨fixoutvals⁩الموضع والحجم فقط.
ImageSVG()⁨link⁩, ⁨align⁩, ⁨palign⁩, ⁨border⁩, ⁨fitonpage⁩الموضع والحجم فقط.
SetProtection()⁨mode⁩ (غير صفري)، ⁨pubkeys⁩ (غير فارغ)يستخدم ⁨NextPDF⁩ دائمًا ⁨AES-256⁩ للمعالِج القياسي. وللتشفير المعتمِد على الشهادات، استخدم الدالة الحديثة setPublicKeyEncryption() المكشوفة على المحوّل (انظر /⁨integrations/tcpdf-compat/security-and-operations/⁩).
Bookmark()⁨style⁩, ⁨color⁩, ⁨x⁩, ⁨isNamedDest⁩تُحترَم العنوان والمستوى والموضع الرأسي (⁨y⁩).
setDestination()⁨page⁩, ⁨x⁩يُحترَم الاسم والموضع الرأسي (⁨y⁩).
Link()⁨spaces⁩هذا تتبُّع داخلي للمسافات في ⁨TCPDF⁩؛ ولا نظير له في المحرّك.
Annotation()مفاتيح الخيارات عدا ⁨Subtype⁩، ⁨spaces⁩يُحترَم النوع والموضع والنص.
SetLineStyle()تفاصيل نمط التقطيع (⁨dash⁩) عدا العرضتُربَط خصائص الخط الأساسية.
setAlpha()ربط جزئي لأنماط المزج (⁨blend-mode⁩)لا نظير لبعض أسماء أنماط المزج في المحرّك.
Polycurve()قائمة المعاملات الكاملةلا يفعل شيئًا في الوضع الافتراضي؛ لا نظير له في المحرّك.
PieSectorXY()قائمة المعاملات الكاملةربط جزئي (تختلف الخطوط من المركز إلى المحيط).
RoundedRectXY()نصف قطر لكل زاوية على حدةنصف قطر زاوية موحَّد فقط.

تعتمد طريقة إظهار المحوّل لهذه الفروق على الوضع الصارم (انظر /⁨integrations/tcpdf-compat/configuration/⁩). فمع إيقاف الوضع الصارم، وهو الإعداد الافتراضي المتوافق خلفيًّا، تتدهور هذه الاستدعاءات بصمت. ومع تشغيل الوضع الصارم، يطرح كل استدعاء يتجاهل معاملًا الاستثناء TcpdfNotImplementedException مع القائمة الدقيقة للمعاملات المتجاهَلة وتلميح ترحيل. والوضع الصارم أداة تدقيق، وليس إعدادًا للإنتاج.

يتّبع تصميم الوضع الصارم المبدأ القائل بأن المُستدعِي يجب أن يكون قادرًا على ملاحظة أن نيّته لم تُحترَم. ⁨OWASP ASVS 5.0⁩ البند §16.5.3 ينصّ على أن التطبيقات ينبغي أن تفشل بسلاسة وأمان وأن تمنع حالات الفشل المفتوح (⁨fail-open⁩). والفقدان الصامت للمعامل هو مَزلَق في تجربة المطوّر لا ثغرة أمنية، لكن ينطبق المبدأ نفسه: الفشل الصريح. وملخّص البند المثبَّت موجود في البيانات الأمامية للصفحة citations.

3. الدوال غير المنفَّذة — أجسام لا تفعل شيئًا

قسم بعنوان «3. الدوال غير المنفَّذة — أجسام لا تفعل شيئًا»

توجد أربع دوال كي تُصرَّف الشفرة المصدرية القديمة، لكن أجسامها لا تفعل شيئًا. ومع تشغيل الوضع الصارم، تطرح ثلاث منها TcpdfNotImplementedException. أمّا الرابعة (Open()) فهي دالة آمنة ومتعمدة لا تفعل شيئًا ولا تطرح أبدًا، لأنك تستطيع دائمًا إزالتها بأمان من الشفرة القديمة.

دالة ⁨TCPDF⁩السلوكالبديل
setSignature()لا يفعل شيئًا (لا يخزّن شيئًا قابلًا للاستخدام). ويطرح استثناءً في الوضع الصارم.يتطلّب التوقيع الرقمي إصدار ⁨NextPDF⁩ تجاريًّا. استخدم واجهة التوقيع الحديثة مع كائن القيمة CertificateInfo؛ انظر /⁨integrations/tcpdf-compat/security-and-operations/.⁩
addEmptySignatureAppearance()لا يفعل شيئًا. ويطرح استثناءً في الوضع الصارم.بوّابة الإصدار التجاري نفسها كما في setSignature().
endPage()لا يفعل شيئًا. ويطرح استثناءً في الوضع الصارم.يدير ⁨NextPDF⁩ دورة حياة الصفحة تلقائيًّا. أزِل الاستدعاء.
Open()دالة آمنة لا تفعل شيئًا. ولا تطرح أبدًا.يفتح ⁨NextPDF⁩ المستند تلقائيًّا. وإزالة الاستدعاء آمنة دائمًا.

التوقيع غير متاح في المحرّك الأساسي عبر هذا المحوّل. ويكشف المحوّل نقطة دخول توقيع حديثة تفوّض إلى المحرّك. ودعم التوقيع الأساسي محصور بإصدار تجاري. ولا يقدّم هذا التوثيق أي ادّعاء بشأن ملفّات التوقيع ذات التحقّق طويل الأمد أو ذات الطابع الزمني لأي إصدار. انظر /⁨integrations/tcpdf-compat/security-and-operations/⁩ للاطّلاع على البيان الدقيق المتحفِّظ.

سبع دوال من ⁨TCPDF⁩ لا أثر لها في مخرجات ⁨PDF⁩، وهي مُستبعَدة عن قصد. ويمكنك استدعاؤها بأمان.

دالة ⁨TCPDF⁩سبب الاستبعاد
setDocCreationTimestamp() / setDocModificationTimestamp()تُحفَظ الحالة على المحوّل لكنها غير موصولة ببيانات ⁨XMP⁩ الوصفية للمستند، وغير مرئية في المخرجات.
setSRGBmode()إدارة الألوان في ⁨NextPDF⁩ مستقلّة عن هذه الراية.
setPDFVersion()يختار ⁨NextPDF⁩ إصدار ⁨PDF⁩ من ملف ⁨conformance/output⁩ الخاص به؛ ولا يوجد ضابط (⁨setter⁩) مباشر. ويُصدِر المحوّل إشعارًا ويتابع.
setDocInfoUnicode()يكون ⁨NextPDF⁩ دائمًا بترميز ⁨Unicode⁩؛ والراية لا تفعل شيئًا بحكم التصميم.
setDefaultMonospacedFont()لا نظير له في المحرّك؛ ويُطبَّق تنسيق ⁨HTML/CSS⁩ بدلًا منه.
setFontSubsetting()يُنشِئ ⁨NextPDF⁩ دائمًا مجموعة جزئية من الخطوط المضمَّنة؛ فالراية مفعَّلة دائمًا فعليًّا.

إصدار ⁨PDF⁩ يثبّته المحرّك. وتُكتَب المخرجات بصيغة ⁨PDF 2.0⁩ (⁨ISO 32000-2⁩). يحدّد ⁨ISO 32000-2⁩ §7.5.2 أن الكاتب المطابِق يُعرِّف إصدار المستند — في ترويسة الملف أو في مدخل Version في الفهرس — بأنه 2.0. كما يحدّد أن حفظ الملف لا يخفّض إصدار الملف. وهذا يطابق سلوك المحوّل: لا تستطيع استدعاءات مثل setPDFVersion('1.4') أن تستهدِف إصدار ⁨PDF⁩ أقدم نزولًا عبر هذا المحوّل. وملخّص البند المثبَّت موجود في البيانات الأمامية للصفحة citations.

5. دوال انحراف الواجهة الحديثة

قسم بعنوان «5. دوال انحراف الواجهة الحديثة»

سبع عشرة دالة من نواة ⁨NextPDF v5.1⁩+ مكشوفة على المحوّل (السمة AdaptsDriftV51) كي تُصرَّف الشفرة التي تمزج واجهة ⁨TCPDF⁩ بالواجهة الحديثة. وليس لهذه نظيرٌ في ⁨TCPDF 6.x⁩. أمثلة: getWarnings()، hasWarnings()، embedFileFromString()، enableBiDi()، beginTag() / endTag()، enableLinearization()، useAesGcm()، useDocumentMac()، setConformanceMode(). عامِل هذه الدوال على أنها من الواجهة الحديثة، لا جزءًا من عقد التوافق مع ⁨TCPDF.⁩

6. إرشادات الإهمال والاستبدال

قسم بعنوان «6. إرشادات الإهمال والاستبدال»
إذا كانت شفرتك تستدعي…الحالةافعل هذا بدلًا منه
Error()تغيّر السلوك (مُحصَّن)يستبدل المحوّل die() الخاصة بـ ⁨TCPDF⁩ باستثناء RuntimeException مطروح. غلِّف الاستدعاءات الخطِرة بـ try/catch؛ ولا تعتمد على إنهاء العملية.
setPDFVersion()غير منطبِقةأزِلها. فالمخرجات دائمًا ⁨PDF 2.0.⁩
setUserRights()مُهمَلة في ⁨PDF 2.0⁩أزِلها. فالاستدعاء يُصدِر إشعار E_USER_DEPRECATED ويُتجاهَل.
setSignature()غير منفَّذة في النواةرحِّل إلى واجهة التوقيع الحديثة على إصدار تجاري.
Image(...) مع معاملات إضافيةتجاهُل صامتاختصِرها إلى ⁨file⁩ و⁨x⁩ و⁨y⁩ و⁨w⁩ و⁨h⁩؛ وأضِف Document::link() للصور القابلة للنقر.
endPage() / Open()غير منفَّذة / لا تفعل شيئًاأزِلها.
  1. ثبِّت الحزمة وشغِّل مجموعة اختباراتك القائمة على المحوّل دون أي تغييرات في الشفرة. انظر /⁨integrations/tcpdf-compat/install/⁩ و/⁨integrations/tcpdf-compat/quickstart/.⁩
  2. فعِّل الوضع الصارم في تشغيل تدقيق مخصَّص (لا في الإنتاج): $pdf->setStrictMode(true);. واجمع كل TcpdfNotImplementedException. فكلٌّ منها يسمّي المعاملات المتجاهَلة بدقة مع تلميح ترحيل.
  3. لكل موضع طرح، اختر إمّا إسقاط المعامل المتجاهَل أو ترحيل ذلك الاستدعاء إلى الواجهة الحديثة عبر $pdf->getDocument().
  4. أعِد ضبط أي اختبار يؤكّد بايتات ⁨PDF⁩ بدقة؛ وأكِّد بدلًا من ذلك المحتوى المعروض أو الخصائص البنيوية.
  5. أوقِف الوضع الصارم وانشُر مسار الشفرة المدقَّق. واحتفِظ بمهمّة ⁨CI⁩ دورية للوضع الصارم لالتقاط الانحدارات عند إعادة هيكلة الشفرة.

الإجراء الكامل مع الشفرة: /⁨integrations/tcpdf-compat/migration/.⁩

  • docs/TCPDF_COVERAGE.md — مصفوفة التغطية المرجعية المتحقَّق منها بالاختبارات (في المستودع)
  • /⁨integrations/tcpdf-compat/migration/⁩ — إستراتيجية الترحيل الشاملة من ⁨TCPDF⁩ إلى ⁨NextPDF⁩
  • /⁨integrations/tcpdf-compat/configuration/⁩ — الوضع الصارم وإعداد المحوّل
  • /⁨integrations/tcpdf-compat/security-and-operations/⁩ — وضعية التشفير والتوقيع
  • /⁨integrations/tcpdf-compat/integration/⁩ — توصيل المحوّل داخل تطبيق
  • /⁨integrations/tcpdf-compat/boot-and-discovery/⁩ — تسجيل اسم الصنف البديل (⁨class-alias⁩) وكشف الواجهة (⁨facade⁩)