مباشر · الحالة OK
الوثائق · OW Consent v1.4.3

OW Consent
الوثائق

إدارة الموافقة في ووردبريس التي تحجب أدوات التتبّع قبل النقرة، لا بعدها.

v1.4.3GPL-2.0-or-laterالوثائق

OW Consent — التوثيق

إدارة الموافقة الكاملة في ووردبريس: لافتة متعدّدة الولايات القضائية، وحجب لأدوات التتبّع، وماسح، ووثائق قانونية، وسجلّ إثبات، وبوّابة لحقوق أصحاب البيانات. المؤلّف: OptionWeb — Julien Daniel صفحة الإضافة: https://optionweb.dev/ar/addons/ow-consent/ الترخيص: GPL-2.0-or-later الإصدار الذي يغطّيه هذا المستند: 1.4.3


جدول المحتويات

  1. نظرة عامة
  2. التثبيت
  3. البدء السريع
  4. ملفّات الامتثال الأحد عشر
  5. فئات ملفّات تعريف الارتباط
  6. اللافتة
  7. الحجب التلقائي
  8. ماسح أدوات التتبّع
  9. مولّد الوثائق القانونية
  10. سجلّ الموافقات
  11. بوّابة الحقوق (DSAR)
  12. انسحاب CCPA «Do Not Sell or Share»
  13. Google Consent Mode v2
  14. IAB TCF v2.2
  15. Global Privacy Control
  16. الكشف الإقليمي
  17. التكامل مع OW Forms
  18. الزرّ العائم
  19. الرموز المختصرة
  20. واجهة REST البرمجية
  21. مرجع الإعدادات
  22. استكشاف الأعطال
  23. الأسئلة الشائعة

نظرة عامة

OW Consent حزمة لإدارة الموافقة في ووردبريس. تغطّي السلسلة كاملة: عرض الاختيار، وتطبيقه فعليًا على أدوات التتبّع، والاحتفاظ بإثباته، ونشر الوثائق التي تشرحه، واستقبال طلبات أصحاب البيانات.

تُسلَّم معها أحد عشر ملفّ امتثال — من اللائحة العامة لحماية البيانات (GDPR) إلى قانون خصوصية المستهلك في كاليفورنيا (CCPA)، مرورًا بالقانون 25 في كيبك، والقانون البرازيلي LGPD، والقانون الهندي DPDP. والملفّ النشط يقرّر نموذج الموافقة (موافقة مسبقة أم انسحاب)، والقيم الافتراضية لـ Google Consent Mode، ونصّ الوثائق المولَّدة، والحقوق المنشورة، وسلطة الرقابة المذكورة.

كل شيء يبقى داخل موقعكم. لا تتّصل الإضافة إلا بخدمة خارجية واحدة، وهي قائمة المزوّدين العالمية التابعة لـ IAB Europe، وذلك فقط إذا فعّلتم وحدة TCF، وهي معطَّلة افتراضيًا. لا قياس عن بُعد، ولا حساب، ولا اشتراك.

متوافق مع تخزين مؤقت كامل للصفحات، بحكم البناء

هذه هي النقطة المعمارية التي تحكم كل ما عداها. لا شيء ممّا يعرضه الخادم يتوقّف على ملفّ تعريف ارتباط الموافقة. شيفرة HTML واحدة لجميع الزوّار: أدوات التتبّع يُعاد كتابتها وسومًا خاملة للجميع، ومُشغِّل جافاسكربت هو الذي يُطلقها داخل المتصفّح، فئةً فئة، بقراءة ملفّ تعريف الارتباط قبل أول رسم للصفحة.

والنتيجة العملية: لا يستطيع LiteSpeed Cache أو WP Rocket أو Varnish أو أي شبكة توصيل محتوى أن يقدّم اختيارات زائرٍ إلى زائر آخر. أما الاستجابات الشخصية فعلًا — صفحة تأكيد الهوية في طلب حقوق، واستجابات REST التي تحوي بيانات الزائر — فتُوسَم صراحةً بأنها غير قابلة للتخزين المؤقت. كما لا يُطبَع أي رمز nonce داخل شيفرة قابلة للتخزين: تجلب اللافتة رمزًا طازجًا من نقطة نهاية no-store قبل كل كتابة مباشرةً.

ما يُسلَّم معها

  • لافتة موافقة: أربعة مواضع، وسمة فاتحة / داكنة / تلقائية، و«رفض الكل» بالوضوح نفسه الذي عليه «قبول الكل»، ولوحة تفضيلات يمكن استخدامها بلوحة المفاتيح، وقابلة للترجمة بالكامل.
  • حجب تلقائي لأدوات التتبّع: السكربتات، والمقاطع المضمّنة، والإطارات، والبكسلات، وتلميحات الموارد (preconnect وdns-prefetch وpreload)، وأوراق أنماط التحليلات والتسويق، ووسائط الأطراف الثالثة، انطلاقًا من 175 بصمة مُضمَّنة وقابلة للتعديل.
  • ماسح أدوات التتبّع: مسح لصفحاتكم أنتم عبر WP-Cron، وقراءة لترويسات Set-Cookie، ومِجَسّ متصفّح مقصور على المديرين، ولوحة تقول دائمًا ما غطّاه المسح فعليًا.
  • مولّد وثائق قانونية: سياسة الخصوصية وسياسة ملفّات تعريف الارتباط للملفّات الأحد عشر، بلغة الولاية القضائية؛ والبيانات القانونية والشروط العامة بالفرنسية.
  • سجلّ الموافقات: كل إجراء يُضاف إلى جدول مُتسلسِل بخوارزمية HMAC، مع الملفّ السارية أحكامه، وبصمة الوثائق المنشورة، وبصمة اللافتة التي عُرضت فعلًا.
  • بوّابة الحقوق (DSAR): نموذج عبر رمز مختصر، وتحقّق بالبريد الإلكتروني، ومهلة المادة 12.3 التي تنطلق عند تأكيد الهوية، وارتباط بأداتَي التصدير والمحو الأصليتين في ووردبريس.
  • Google Consent Mode v2 وIAB TCF v2.2 وGlobal Privacy Control والكشف الإقليمي والتكامل مع OW Forms: كلٌّ منها يُفعَّل باستقلال عن غيره.
  • واجهة REST برمجية كاملة تحت النطاق owc/v1.

ما لا تفعله — اقرؤوه قبل الالتزام

في موضوع قانوني، الوعد المبالَغ فيه يعرّضكم للخطر بقدر ما يعرّض الناشر. وهذه هي الحدود، كما هي مكتوبة في الشيفرة.

  • الوثائق المولَّدة نماذج، لا استشارة قانونية. تنتهي كل وثيقة بتنبيه يقول ذلك، وهذا التنبيه مفعَّل افتراضيًا. اعرضوا وثائقكم على مختصّ قبل نشرها.
  • وحدة TCF ليست منصّة CMP مسجَّلة لدى IAB Europe. تتطلّب رقم CMP ID عليكم الحصول عليه بأنفسكم، ولا تتيح أي اختيار على مستوى المزوّد، وللمزوّدين حقّ رفض إشارتها. فإن كان دخل الإعلانات عبر TCF يهمّكم، استعملوا منصّة CMP معتمدة.
  • السجلّ غير قابل للتزوير بشرط. السلسلة ليست إثباتًا إلا إذا عاش مفتاح توقيعها خارج قاعدة البيانات. والإضافة تكتشف الحالة المعاكسة، وتُبلغ عنها بنفسها، وتقولها لكم في لوحة التحكّم بدل أن تدّعي العكس.
  • الماسح لا ينفّذ أي جافاسكربت. يرى ما تحويه شيفرة HTML وما تضعه ترويسات Set-Cookie لديكم؛ أما ما يحقنه مدير الوسوم أثناء التشغيل فلا يراه إلا مِجَسّ مقصور على المديرين المسجَّلين.
  • الحجب الافتراضي ليس «كل ما هو طرف ثالث». السكربت الخارجي المجهول مسموح افتراضيًا؛ والإطارات المجهولة هي المحجوبة افتراضيًا. والحجب يقوم على كتالوج البصمات، ويمكنكم إثراؤه.
  • بلا جافاسكربت، لا يمكن تسجيل أي اختيار. يرى الزائر كتلة <noscript> ولا يُحمَّل شيء غير ضروري، لكن لا يُسجَّل شيء أيضًا.
  • لا تفصيل ولايةً بولاية في الولايات المتحدة ولا مقاطعةً بمقاطعة في كندا داخل الكشف الإقليمي: تتلقّى الأراضي الأمريكية كلها الملفّ ccpa، وتتلقّى كندا كلها quebec.
  • البيانات القانونية والشروط العامة موجودة بالفرنسية فقط. ولأي ولاية قضائية لغتها المستهدفة غير الفرنسية، يرفض المولّد إنتاج هاتين الوثيقتين بدل نشر نصّ غير ملائم.
  • لا دور مخصَّص: تتطلّب إدارة الإضافة كلها صلاحية manage_options.

هذه القائمة خيار مُعلن، لا خارطة طريق مخفيّة. وفي الامتثال، أداةٌ تعلن ثغراتها خير من أداة تخفيها.


التثبيت

من ملفّ ZIP

  1. نزّلوا ow-consent-1.4.3.zip من https://optionweb.dev/ar/addons/ow-consent/
  2. الإضافات ثم «أضف جديدًا» ثم «رفع إضافة»
  3. اختاروا الملفّ، وانقروا تثبيت، ثم تفعيل

عبر FTP

فُكّوا ضغط الأرشيف وضعوا المجلّد ow-consent في /wp-content/plugins/، ثم فعّلوا الإضافة من الإضافات.

المتطلّبات

  • ووردبريس 6.2 أو أحدث — وهذا رفض للإقلاع، لا توصية (انظروا أدناه)
  • PHP 7.4 أو أحدث
  • MySQL 5.7+ / MariaDB 10.2+
  • WP-Cron يعمل إذا كنتم تستخدمون الماسح، أو حفظ السجلّ، أو تذكيرات مواعيد DSAR، أو وحدة TCF

الحاجز الواقي عند ووردبريس 6.2. منذ الإصدار 1.3.0، يُربَط كل معرّف جدول بالعلامة %i في wpdb::prepare()، وهي علامة لا يفهمها ووردبريس إلا ابتداءً من 6.2. وعلى نواة أقدم، ستُعيد prepare() سلسلة فارغة، فيُختزل كتالوج أدوات التتبّع بصمت إلى مجموعة فارغة، وتستمرّ اللافتة في وعد الزائر بحجب لن يحدث. لذلك ترفض الإضافة الإقلاع وتعرض رسالة خطأ تقول صراحةً إن شيئًا لا يُحجب وإن أي موافقة لا تُسجَّل. وترويسة Requires at least تمنع أصلًا التفعيل دون 6.2، لكنها لا تغطّي تخفيض النواة تحت تثبيت قيد الخدمة، ولا نسخةً وُضعت عبر FTP.

ما يُثبَّت

عند التفعيل، ينشئ OW Consent أربعة جداول:

الجدولالمحتوى
{prefix}owc_ledgerسجلّ الموافقات، مُتسلسِل بالبصمات
{prefix}owc_dsarطلبات ممارسة الحقوق
{prefix}owc_scannerنتائج ماسح أدوات التتبّع
{prefix}owc_scriptsكتالوج البصمات الذي يستعمله الحجب

وثمة جدول خامس، {prefix}owc_form_links، يُنشَأ على حدة بواسطة التكامل مع OW Forms إذا كانت الإضافة الشقيقة نشطة (انظروا التكامل مع OW Forms).

كما يضيف التفعيل:

  • الخيار owc_settings، ويُزرَع فارغًا — عن قصد: ما دمتم لم تحفظوا شيئًا، تأتي كل النصوص من القيم الإنجليزية الافتراضية مترجَمةً لحظيًا إلى لغة الموقع، بدل تجميد لغة الشخص الذي فعّل الإضافة داخل قاعدة البيانات؛
  • الخيار owc_version؛
  • كتالوج أدوات التتبّع المُضمَّن (data/tracker-catalog.json)، يُدرَج على دفعات من 100 بأسلوب INSERT IGNORE، مع راية زرع خاصة بكل إصدار (owc_catalog_seeded_1.4.3
  • المهمّة اليومية owc_daily_maintenance، المجدولة بعد ساعة من التفعيل.

وثمة خمسة أحداث cron أخرى تُسلَّح من الوحدات التي تستعملها. وأحداث cron الستّة للإضافة هي: owc_scanner_run وowc_scanner_run_batch وowc_ledger_retention وowc_tcf_refresh_gvl وowc_run_upgrade وowc_daily_maintenance.

في وضع الشبكة (multisite)، تُنشَأ الجداول لكل موقع، ولا تُشارَك أبدًا (wp_2_owc_ledger وهكذا). والتفعيل على مستوى الشبكة يمرّ على كل المواقع فقط إذا كانت الشبكة تضمّ 200 موقع كحدّ أقصى؛ وفوق ذلك، يُهيَّأ كل موقع تكاسليًا عند أول طلب له. أما موقع فرعي أُنشئ بعد تفعيل شبكي فيُهيَّأ عبر الخطّاف wp_initialize_site.

ما يجب تعريفه في wp-config.php

لا شيء من هذه الثوابت إلزامي، لكن اثنين منها يغيّران القيمة الإثباتية لما تنتجه الإضافة.

// موصى به: يُخرِج مفتاح توقيع السجلّ من قاعدة البيانات.
define( 'OWC_LEDGER_KEY', 'سلسلة عشوائية طويلة، خاصة بهذا الموقع' );

// موصى به: أملاح ووردبريس القياسية. بدونها يخزّنها ووردبريس في قاعدة البيانات،
// ويُبلغ السجلّ بنفسه أنه لم يعد غير قابل للتزوير.
define( 'AUTH_KEY',  '…' );
define( 'AUTH_SALT', '…' );

// إذا كان الموقع خلف شبكة توصيل محتوى أو موزّع حِمل أو وكيل عكسي.
// بدون هذا الثابت تُتجاهَل CF-Connecting-IP و X-Forwarded-For و X-Real-IP
// ولا يُستعمل سوى REMOTE_ADDR — ما يعطي كل زوّاركم الهوية نفسها
// عند تحديد معدّل الطلبات.
define( 'OWC_TRUSTED_PROXY', '198.51.100.0/24, 2001:db8::/32' );
// `OWC_TRUSTED_PROXIES` مقبول كاسم بديل؛ وتصلح سلسلة نصية أو مصفوفة.

// للكشف الإقليمي فقط: يعلن أي ترويسات البلد جديرة بالثقة.
define( 'OWC_GEO_TRUSTED_HEADERS', 'cloudflare' ); // 'cloudflare'|'cloudfront'|'proxy'|'all'
define( 'OWC_BEHIND_CLOUDFLARE', true );
define( 'OWC_BEHIND_CLOUDFRONT', true );

ويُستعمل OWC_LEDGER_KEY أيضًا لاشتقاق مفتاح ملفّ تعريف ارتباط الكشف الإقليمي. وإذا لم يُعرَّف، يرتدّ مفتاح السجلّ إلى wp_salt('auth').

من له حقّ الوصول

تتطلّب إدارة الإضافة كلها، وكل مسارات REST الإدارية، صلاحية manage_options. ولا يوجد دور مخصَّص ولا صلاحية أدقّ: فتحُ شاشة الإضافة لشخصٍ ما يعني منحه إعدادات الموقع.

مسار الترقية

لا تُرحّل الإضافة مخطّطها أبدًا أثناء الطلب على صفحة مجهولة الزائر. وعندما يتغيّر الإصدار، يُكتب owc_version وراية owc_pending_upgrade فورًا، ثم:

  • تُنفَّذ الترحيلة مباشرةً إذا كان الطلب طلبًا إداريًا خارج AJAX، أو تنفيذًا لـ cron، أو أمرًا من WP-CLI؛
  • وإلا فيُجدوَل حدث owc_run_upgrade بعد خمس ثوانٍ.

ويُعامَل admin-ajax.php معاملة الطلب المجهول: فهو نقطة دخول عمومية. وتُنفَّذ الترحيلة تحت قفل (owc_upgrade_lock، يُسرَق بعد 300 ثانية)، وشبكةُ أمان على admin_init تلتقط المواقع التي عُطِّل فيها WP-Cron. وعلى إصدار مطابق، تكون التكلفة الإجمالية استدعاء get_option() واحدًا.

التعطيل والحذف

التعطيل يحفظ كل البيانات ولا يمحو سوى أحداث cron الستّة. وفي التعطيل الشبكي، يُمرّ على كل المواقع على دفعات من 200 — خلافًا للتفعيل — لأن مهمّة cron تُركت مسلَّحة لن تختفي أبدًا.

حذف الإضافة يُشغّل uninstall.php، الذي يعمل على مرحلتين:

  1. دائمًا، أيًّا كان إعدادكم: تُمحى مهامّ cron الستّ ويُحذف الجدول {prefix}owc_dsar مع عوابره الخاصة بتحديد معدّل الطلبات. وهو الجدول الوحيد الذي يحوي بيانات شخصية تعرّف أطرافًا أخرى تعريفًا مباشرًا (بريد إلكتروني، اسم، نصّ حرّ)؛ وبعد رحيل الإضافة لا يبقى ما يحدّ مدة حفظه، ولا شاشة تتيح الردّ عليه أو تصديره أو محوه. صدّروا الطلبات التي عليكم الاحتفاظ بها قبل حذف الإضافة.
  2. فقط إذا كان delete_data_on_uninstall مفعَّلًا صراحةً: حذف الجداول owc_ledger وowc_dsar وowc_scanner وowc_scripts وowc_form_links، والخيارات المسمّاة، وكل الخيارات ذات السابقة owc_ (بما فيها العوابر)، وحقول usermeta ذات السابقة owc_. وفي وضع الشبكة، تتبع خيارات الشبكة قرار الموقع الرئيسي.

هذا الإعداد معطَّل افتراضيًا: فإثبات الموافقة، الذي تفرضه المادة 7.1 من اللائحة العامة لحماية البيانات، يبقى بعد حذف الإضافة.


البدء السريع

بعد التفعيل، افتحوا مدخل OW Consent في الشريط الجانبي للوحة التحكّم. تتّسع الإضافة كلها لهذه الشاشة الواحدة، في عشرة تبويبات: Dashboard وBanner وCompliance وLegal identity وCategories وPolicies وScanner وTracker catalogue وAudit ledger وDSAR requests.

الحفظ لا يخصّ إلا التبويب المفتوح. وهذا مقصود: فلكل قيمة منطقية حقلٌ خفيّ توأم، وغيابُ مفتاح من النموذج يعني «هذا الحقل في تبويب آخر»، لا «غير مؤشَّر». ولولا ذلك لكان حفظ تبويبٍ واحد يمحو إعدادات كل التبويبات الأخرى.

1. اختاروا ملفّ الامتثال

تبويب Compliance. الملفّ يقرّر نموذج الموافقة، والقيم الافتراضية لـ Consent Mode، والوثائق المولَّدة، والحقوق المنشورة. والافتراضي: gdpr.

وcompliance_strict مفعَّل افتراضيًا: وهو ما يوسّع الحجب إلى ما هو أبعد من السكربتات المسجَّلة في ووردبريس وحدها. اتركوه نشطًا إن أردتم معالجة الإطارات والبكسلات والسكربتات المكتوبة مباشرةً داخل قالبكم.

2. املؤوا الهوية القانونية

تبويب Legal identity. هذه الحقول هي المادة الخام للوثائق المولَّدة، والتوليد يُرفض ما دام حقلٌ إلزامي فارغًا — مع قائمة المفاتيح الناقصة، لا إخفاق صامت.

الحدّ الأدنى لكل الوثائق: legal_company_name وlegal_company_email. ولكل شيء عدا سياسة ملفّات تعريف الارتباط، أضيفوا العنوان والبلد. وللبيانات القانونية، أضيفوا كذلك الهاتف ومدير النشر وبيانات المُستضيف كاملة؛ وفي فرنسا وبلجيكا ولوكسمبورغ يصبح الشكل القانوني ورقم التسجيل إلزاميين أيضًا.

اتركوا legal_dpa_authority فارغًا: فسلطة الرقابة تُشتقّ من بلدكم ومن ملفّكم. وملؤه يدويًا على موقع متعدّد الولايات القضائية يعني تسمية الجهة الرقابية الخطأ.

3. راجعوا فئاتكم

تبويب Categories. الفئات الستّ متاحة افتراضيًا. عطّلوا ما لا يستعمله موقعكم: فغيابُ فئة عن الواجهة ليس مكسبًا في الامتثال، بل هو موردٌ محجوب إلى الأبد بلا مفتاح يُطلقه — وعندها يحوّله الحجب إلى marketing.

واتركوا التسميات فارغة ما دامت تناسبكم: فهي عندئذٍ تتبع لغة الموقع. وما إن تخصّصوا نصًّا، يتوقّف ذلك النصّ عن تتبّع اللغة.

4. اضبطوا اللافتة

تبويب Banner. الموضع، والسمة، والأزرار، والتسميات، ومدة التجديد.

ونقطتان لا تفوّتوهما: اتركوا banner_reject_all مفعَّلًا («الرفض» يجب أن يكون بالبساطة والوضوح نفسيهما اللذين عليهما «القبول»)، واتركوا علامة الإغلاق معطَّلة — فهي غائبة افتراضيًا لأن الإغلاق دون اختيار يعادل رفضًا ضمنيًا. وإذا فعّلتموها، فإن النقر عليها ينفّذ مسار «رفض الكل» كاملًا، لا إغلاقًا صامتًا.

5. ولّدوا وثائقكم

تبويب Policies. أربع وثائق: سياسة ملفّات تعريف الارتباط، وسياسة الخصوصية، والبيانات القانونية، والشروط العامة. وتصير كلٌّ منها صفحة ووردبريس ذات إصدارات، يُعاد حقن رابطها في الإعدادات.

ولّدوا أولًا في وضع المعاينة، وراجعوا، ثم انشروا. واعرضوها على مختصّ: فشريط التنبيه أسفل كل وثيقة ليس زينة.

6. افتحوا بوّابة الحقوق

أنشئوا صفحة والصقوا فيها [owc_dsar_form]. واملؤوا dsar_email في تبويب DSAR requests: فهو عنوان التواصل المنشور تحت النموذج والمُستقبِل للإشعارات. وبدونه ترتدّ الإضافة إلى legal_dpo_email، ثم إلى admin_email — لكن admin_email لا يُنشر أبدًا على صفحة عمومية.

7. تحقّقوا قبل الفتح للجمهور

تُجري لوحة المعلومات خمسة عشر فحصًا للامتثال، وتميّز الأخطاء عن التحذيرات: لافتة معطَّلة، و«رفض الكل» غائب، وعلامة إغلاق مفعَّلة، وهوية قانونية ناقصة، وبوّابة حقوق مغلقة، وسجلّ معطَّل، ولا سياسة مرتبطة، وسلطة رقابة تناقض الملفّ النشط (مع زرّ «Fix this» يعيد ضبطها)، وموقع لا يعمل على HTTPS، وأدوات تتبّع غير مصنَّفة، وطلبات DSAR تجاوزت المهلة، وقواعد كتالوج لا يمكن أن تنطبق.

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


ملفّات الامتثال الأحد عشر

ملفّ الامتثال ليس تجميليًا. فهو يقود النموذج القانوني، والواجهة، والإشارات التقنية، ومحتوى الوثائق المنشورة.

القائمة

الملفّالنظام المستهدفالنموذج
gdprGDPR + ePrivacy (الاتحاد الأوروبي / المنطقة الاقتصادية الأوروبية)موافقة مسبقة
uk_pecrUK GDPR + PECR (المملكة المتحدة)موافقة مسبقة
ch_nfadpقانون حماية البيانات السويسري الجديدموافقة مسبقة
quebecالقانون 25 (كيبك)موافقة مسبقة
lgpdLGPD (البرازيل)موافقة مسبقة
popiaPOPIA (جنوب أفريقيا)موافقة مسبقة
piplPIPL (الصين)موافقة مسبقة
dpdpقانون DPDP لعام 2023 (الهند)موافقة مسبقة
ccpaCCPA / CPRA (كاليفورنيا)انسحاب
us_genericقوانين الولايات الأمريكية العامةانسحاب
auPrivacy Act (أستراليا)انسحاب

الإعداد: compliance_profile، والافتراضي gdpr.

الموافقة المسبقة (opt-in) تعني أنه قبل أي اختيار، لا تُمنح إلا الفئات الإلزامية. والانسحاب (opt-out) يعني أن كل شيء ممنوح حتى الرفض. والملفّات الثلاثة القائمة على الانسحاب هي ccpa وus_generic وau. ويطبّق مُشغِّل جافاسكربت القاعدة نفسها التي تطبّقها PHP بالضبط، حتى لا يبلّغ الخادم والمتصفّح عن حالتين مختلفتين.

ما يغيّره الملفّ فعليًا

ما يتغيّرالتفصيل
نموذج الموافقةموافقة مسبقة، باستثناء ccpa وus_generic وau
القيم الافتراضية لـ Consent Modeتنتقل الإشارات السبع إلى granted تحت ملفّ قائم على الانسحاب
إلزامية رابط «Do Not Sell or Share»ccpa وus_generic فقط
إلزامية GPC قانونًاccpa وus_generic فقط — وأستراليا مستثناة صراحةً: نظام انسحاب، لكنه لا يعترف بـ GPC
نطاق «تنطبق GDPR» لأغراض TCF27 دولة في الاتحاد الأوروبي + IS و LI و NO + GB + CH، أي 31 رمزًا
لغة الوثيقة المولَّدةquebec تعطي الفرنسية؛ lgpd تعطي البرتغالية؛ gdpr ببلد FR أو BE أو LU تعطي الفرنسية؛ وما عدا ذلك يعطي الإنجليزية
سلطة الرقابة المذكورةجدول لكل ملفّ، مُنقّح حسب البلد في حالة GDPR
قائمة الحقوق المنشورةقائمة محرَّرة لكل ملفّ، مع ذكر المادة
متن «نظام ملفّات تعريف الارتباط» في الوثيقة الإنجليزيةنصّ ونطاق نقل وضمانات مختلفة لكل ملفّ

الوثائق المولَّدة حسب الملفّ

سياسة الخصوصية وسياسة ملفّات تعريف الارتباط موجودتان للملفّات الأحد عشر جميعًا. وتُحَلّ القوالب بهذا الترتيب، والأول الموجود يفوز: <type>_<profil>_<langue>، ثم <type>_<profil>، ثم <type>_<langue>، ثم <type>.

والمتون الإنجليزية لسياسة ملفّات تعريف الارتباط واعية بالملفّ: القاعدة السارية، ونطاق النقل، والضمانات، وتسمية اللوحة تختلف بين gdpr وuk_pecr وch_nfadp وau وpipl وdpdp وccpa وus_generic، مع الاستشهادات المقابلة (المادة 5(3) من التوجيه 2002/58، وPECR reg. 6، والمادة 45c(b) من قانون الاتصالات والمادة 19/6(7)(b) من قانون حماية البيانات السويسري الجديد، وAPP 8، والمادة 24 من PIPL، والأقسام 5 و6 و7 و9(3) و16 من قانون DPDP لعام 2023، و§1798.121 وCal. Code Regs. tit. 11 §7025، وVCDPA/CPA/CTDPA/UCPA/TDPSA).

سلطة الرقابة المذكورة

الملفّالسلطة المُسمّاة
gdpr، بلد FRCNIL
gdpr، بلد BEAPD-GBA
gdpr، بلد LUCNPD
gdpr، بلد DEBfDI
gdpr، بلد آخر في المنطقة الاقتصادية الأوروبيةصيغة عامة («سلطة الرقابة المختصّة»)
uk_pecrICO
ch_nfadpPFPDT / FDPIC
quebecCommission d'accès à l'information
lgpdANPD
ccpaCalifornia Privacy Protection Agency
popiaInformation Regulator (South Africa)
piplCyberspace Administration of China
dpdpData Protection Board of India
auOAIC
us_genericالنائب العام لولايتكم

وإذا عدّلتم legal_dpa_authority، فإن ما أدخلتموه يتقدّم على هذا الاشتقاق.

حدود التغطية القضائية

  • أربع دول فقط في المنطقة الاقتصادية الأوروبية لها سلطة مُسمّاة (FR وBE وLU وDE). أما موقع خاضع لـ GDPR في إسبانيا أو إيطاليا أو هولندا فينشر صيغة عامة.
  • لا تفصيل ولايةً بولاية في الولايات المتحدة. الملفّ us_generic موجود ويحمل نصوصه الخاصة VCDPA/CPA/CTDPA/UCPA/TDPSA، لكن لا كشف تلقائي يسنده: يُختار يدويًا.
  • لا تفصيل حسب المقاطعة في كندا.
  • ثلاث لغات وثائق فقط: الفرنسية والإنجليزية والبرتغالية. ولا تمرّ المتون بآلية الترجمة في ووردبريس — وهذا مقصود: فالوثيقة القانونية يجب أن تكون أحادية اللغة، ولغتها تتبع الولاية القضائية، لا لغة المدير.
  • البيانات القانونية والشروط العامة: قوالب فرنسية فقط. يرفض المولّد الأمر رفضًا قاطعًا لأي لغة مستهدفة أخرى، إلا إذا وفّرتم متنكم الخاص عبر المرشّح owc_policy_template.

فئات ملفّات تعريف الارتباط

القائمة المرجعية

ستّ فئات، بترتيب العرض هذا، وnecessary دائمًا في المقدّمة:

المعرّفالتسمية المُضمَّنةالوصف المُضمَّن
necessaryNecessaryStrictly required for the site to function (cart, login, language preferences). Cannot be disabled.
functionalFunctionalEnhance the experience (chat, embedded videos, maps). Without them some features may not work.
analyticsStatisticsHelp us understand how you use the site (anonymously). No personal data is shared for commercial purposes.
marketingMarketingEnable us to show you ads and content tailored to your interests on other sites.
preferencesPreferencesRemember your interface choices (layout, saved filters).
socialSocial & embedsAllow embedded social content (YouTube, Instagram, X) to load.

القيم أعلاه هي القيم الإنجليزية الافتراضية القابلة للتخزين. وعلى موقع عربي، يرى الزائر الترجمة — انظروا آلية الترجمة أدناه.

الإتاحة

الإعداد cat_<slug>_available، واحد لكل فئة. والستّ متاحة افتراضيًا. والمفتاح القديم cat_<slug>_enabled لا يزال يُقرأ كخيار احتياطي، بلا ترحيل.

وpreferences وsocial تُسلَّم متاحتين لأن كتالوج الزرع يصنّف YouTube وSpotify وSoundCloud وInstagram وX وFacebook ضمن social: فبغياب الفئة عن الواجهة، ستبقى هذه التضمينات محجوبة نهائيًا بلا وسيلة للموافقة عليها.

وnecessary إلزامية: لا يمكن تعطيلها (المادة 5.3 من ePrivacy). ولذلك لا مفتاح إتاحة لها في لوحة التحكّم، بل تسمية ووصف فقط.

آلية الترجمة

الإعدادان cat_<slug>_label وcat_<slug>_desc. تُعاد القيمة المخزَّنة حرفيًا فقط إذا كانت غير فارغة ومختلفة عن القيمة الإنجليزية الافتراضية؛ وإلا فالترجمة هي التي تخرج.

والنتيجة التي ينبغي معرفتها: ما دمتم لم تخصّصوا شيئًا، فتغيير لغة الموقع يغيّر لغة الفئات. وما إن تُدخلوا نصّكم الخاص، يتجمّد ذلك النصّ في اللغة التي كتبتموه بها. والقاعدة نفسها تسري على نصوص اللافتة.

والوصف المترجَم لـ necessary مبنيّ من سلسلتين: الثانية تسمّي ملفّات تعريف الارتباط الخاصة بالإضافة نفسها، owc_consent (حتى 13 شهرًا) وowc_geo (24 ساعة، ولا يُكتب إلا عند تفعيل الكشف الإقليمي).

المطابقة مع Google Consent Mode v2 — مُلزِمة

هذه هي مصدر الحقيقة الوحيد في الإضافة: فاللافتة والحجب والإقلاع يقرؤون هذا الجدول جميعًا، ولذلك لا يمكن أن يتباعدوا.

الفئةإشارات Consent Mode v2
necessarysecurity_storage، functionality_storage
functionalfunctionality_storage، personalization_storage
analyticsanalytics_storage
marketingad_storage، ad_user_data، ad_personalization
preferencespersonalization_storage
socialad_storage، ad_user_data

فارقٌ مهمّ: إذا كان موقعكم يعرض الفئة functional، فإن functionality_storage يُسحب من قائمة necessary. وإلا لكان ممنوحًا قبل أي موافقة، مع أنه ينتمي إلى فئة اختيارية.

المطابقة مع TCF — وصفية فقط

تقابل functional قيمةَ functional، وanalytics قيمةَ measurement، وmarketing قيمةَ advertising، وpreferences قيمةَ personalization، وsocial قيمةَ social_media.

هذه تسميات عرض لا غير. أما المطابقة المُلزِمة في TCF فهي جدول المعرّفات الرقمية لأغراض IAB، الموصوف في قسم IAB TCF v2.2. لا تبنوا أبدًا سلوك TCF على هذه التسميات الخمس.

ماذا يحدث إذا اختفت فئة

إذا كانت قاعدة في الكتالوج تشير إلى فئة لم يعد موقعكم يعرضها — كأن تكونوا عطّلتم social مثلًا — فإن الحجب يحوّل المورد إلى marketing، أو إلى أول فئة اختيارية متاحة إن تعذّر ذلك. فبدون هذا التسوية، سيبقى المورد محجوبًا إلى الأبد بلا أي مفتاح يُطلقه.


اللافتة

متى تظهر

تُعرض اللافتة على wp_footer بالأولوية 5، وتُدرَج مواردها على wp_enqueue_scripts. وتنسحب فورًا إذا تحقّق أحد هذه الشروط: سياق إداري، أو تغذية RSS، أو robots.txt، أو banner_enabled معطَّل. وتنسحب كذلك إذا لم يُطلَق wp_head قطّ — فالقالب الذي لا يستدعي wp_head() سيحصل عندئذٍ على شيفرة خاملة وبلا أنماط.

وشيفرة HTML واحدة لجميع الزوّار. تُعرض كل خانات اللوحة في وضع OFF من جهة الخادم، ثم تُروى من جهة العميل انطلاقًا من ملفّ تعريف الارتباط. وجافاسكربت هو الذي يضع <html data-owc="given|none"> بشكل متزامن، قبل أول رسم؛ ولا تعرض أوراق الأنماط اللافتة إلا على data-owc="none".

ونتيجة ينبغي معرفتها: الزائر الذي لا جافاسكربت لديه لا يرى اللافتة أبدًا، ولذلك لا يُحبَس أبدًا خلف نافذة لا يستطيع إغلاقها. وهو يرى بدلًا منها كتلة <noscript> تشرح أن تفضيلاته لا يمكن تسجيلها وأن أي ملفّ تعريف ارتباط غير ضروري لا يُحمَّل ما دام لم يُتَّخذ اختيار.

المواضع والسمة

الإعدادالقيمالافتراضي
banner_positionbottom-bar، bottom-card، center-modal، top-barbottom-bar
banner_styleauto، light، darkauto

وcenter-modal وحده يحصل على role="dialog" وaria-modal="true" وخلفية معتمة وحصر للتركيز ومفتاح Escape. أما المواضع الثلاثة الأخرى فهي role="region": ولا يُعترَض Escape فيها البتّة (يحتفظ القالب بمعالجته الخاصة) ولا يُسلَب التركيز عند أول رسم، لأن ذلك يدفع مستخدم لوحة المفاتيح إلى ما بعد كل روابط التخطّي.

وتُطبَّق اللوحة الداكنة تحت prefers-color-scheme: dark مع احتياطات كي لا تُطمس سمة تعلن light صراحةً. ويستطيع قالب الموقع قيادة اللوحة عبر متغيّرات CSS: --owc-paper-tint و--owc-ink و--owc-smoke و--owc-fog و--owc-ui و--owc-accent و--owc-accent-strong و--owc-accent-darker.

وتفاصيل التنفيذ: z-index بقيمة 99998 للافتة و99997 للخلفية، ودعم env(safe-area-inset-*) لحوافّ iOS، وإزاحة تلقائية أسفل شريط إدارة ووردبريس في الموضع العلوي.

الأزرار

الإعدادالافتراضيالأثر
banner_accept_alltrueيعرض «قبول الكل»
banner_reject_alltrueيعرض «رفض الكل»
banner_preferencestrueيعرض «تخصيص»
banner_close_xfalseيعرض علامة الإغلاق
banner_show_logotrueيعرض شعار الموقع

و«قبول الكل» و«رفض الكل» يتقاسمان فئة التنسيق نفسها: الخلفية نفسها، والإطار نفسه، وسماكة الخطّ نفسها، والحشو نفسه. وهذا هو الجواب على متطلّب CNIL / EDPB (الإرشادات 03/2022): الرفض يجب أن يكون بالبساطة والوضوح نفسيهما اللذين عليهما القبول.

علامة الإغلاق

هي معطَّلة افتراضيًا، لأن علامة الإغلاق تعادل رفضًا ضمنيًا. وثمة ثلاثة سلوكيات ينبغي معرفتها:

  1. حين يكون banner_close_x معطَّلًا، تكون العلامة موجودة في الشيفرة لكنها تحمل السمة hidden، وتزيلها أوراق الأنماط تمامًا: فلا هي مرئية، ولا قابلة للتركيز، ولا معلنة لقارئات الشاشة.
  2. وحين تكون مفعَّلة، فإن النقر عليها ينفّذ مسار «رفض الكل» كاملًا، لا إغلاقًا صامتًا.
  3. ويكشفها المُشغِّل ويعيد تسميتها في حالة واحدة فقط: حين يتعذّر تسجيل الرفض تمامًا. عندئذٍ لا ترفض شيئًا، بل تُنحّي الإشعار — وهذا الإغلاق لا يُحتسب اختيارًا. فالزائر الذي يرفض الخادم قراره لا يُترك أمام لافتة لا يستطيع إغلاقها.

الطبقة الأولى

  • العنوان (text_title) والرسالة (text_message). والرسالة هي الحقل الوحيد ذو HTML الغنيّ في الإضافة؛ وتُعرض عبر wp_kses محدود بـ <a href target rel>.
  • رابط سياسة الخصوصية: link_privacy_policy، مع ارتداد إلى صفحة السياسة المعلنة في ووردبريس إذا كان الإعداد فارغًا.
  • رابط سياسة ملفّات تعريف الارتباط: link_cookie_policy، بلا ارتداد.
  • اسم المتحكّم في البيانات: legal_company_name، وإلا فاسم الموقع، ويُعرض بصيغة «المتحكّم في البيانات: …» (المادة 13(1)(a)).
  • الشعار: الشعار المخصَّص للقالب بحجم medium، وإلا فأيقونة الموقع.

لوحة التفضيلات

سطر لكل فئة متاحة، داخل role="group" مُسمّى.

  • الفئة الإلزامية تعرض شارة نصّية «Always active»، بلا مفتاح.
  • والفئة الاختيارية تعرض <button role="switch"> مع aria-checked وaria-labelledby وaria-describedby. وتُحمَل الحالة عبر aria-checked، وموضع المؤشّر، وكلمة مرئية On/Off — لا باللون وحده أبدًا.
  • هدف اللمس مُوسَّع إلى 44 بكسل على الشاشات الصغيرة (WCAG 2.2 AA، المعيار 2.5.8).
  • وشريط إجراءات اللوحة sticky في الأسفل، حتى يبقى «حفظ اختياراتي» في المتناول بينما تنزلق القائمة.

وإذا كانت وحدة TCF نشطة، ظهرت كتلتان إضافيتان: أغراض TCF التي يمكن بلوغها والميزات الخاصة المعلَنة. انظروا IAB TCF v2.2.

تجديد الموافقة

الإعدادالافتراضيالحدود
consent_renewal_months12من 0 إلى 13
consent_policy_hash_checktrue

القيمة 0 لا تعني «لا تسأل مجدّدًا أبدًا». فهي تُحوَّل إلى 13 شهرًا، و13 شهرًا هو السقف الصلب (قرار CNIL رقم 2020-091). ولذلك تقع المدة الفعلية دائمًا بين شهر و13 شهرًا، وهي القيمة نفسها التي تحكم مدة ملفّ تعريف الارتباط، وفحص انتهاء الصلاحية من جهة الخادم، والمدة المنشورة في الوثائق المولَّدة. أما الثابت OWC_COOKIE_TTL الظاهر في الشيفرة المصدرية فليس سوى قيمة احتياطية.

وconsent_policy_hash_check يطلب الموافقة من جديد عند تغيّر وثائقكم: فملفّ تعريف الارتباط يحمل بصمة صفحات السياسات المرتبطة، وأي اختلاف يعيد فتح اللافتة. وتساوي البصمة السلسلة الفارغة حين لا تكون أي صفحة مرتبطة — وهذا ما يتيح التمييز بين «مجهول» و«متغيّر»، وعدم مساءلة موقع كامل بناءً على مقارنة فارغة.

النصوص

سبعة مواضع، كلها فارغة افتراضيًا ومترجَمة تلقائيًا بالتالي: text_title وtext_message وtext_accept_all وtext_reject_all وtext_preferences وtext_save، وfloating_button_label للزرّ العائم.

وفي لوحة التحكّم، يعرض كل حقل قيمته الافتراضية المترجَمة كنصّ إرشادي: فتركه فارغًا يبقي على القيمة الافتراضية التي تتبع لغة الزائر.

ويتيح المرشّح owc_banner_texts استبدال هذه النصوص برمجيًا. وتُقبل مواضع إضافية؛ أما القيم غير القياسية أو الفارغة فتُستبعَد حتى لا يستطيع نداء أخرق أن يُفرغ اللافتة.

كيف يُسجَّل الاختيار فعليًا

مُشغِّل جافاسكربت مكتوب بـ ES5 الصارم — بلا دوال سهمية وبلا قوالب نصية — ليعمل في المتصفّحات المدمجة داخل التطبيقات وفي WebViews القديمة. وتستحقّ متتالية الكتابة لديه أن تُعرف، لأنها هي التي تفسّر معظم رسائل الخطأ.

  1. إعادة تثبيت الأصل (origin). تأتي روابط REST من إعدادات ووردبريس. فإذا كان زوّاركم يتصفّحون على مضيف آخر (www مقابل النطاق الجذر، أو اسم بديل، أو نطاق معاينة، أو وكيل يعيد كتابة Host)، صار هذا الرابط عابرًا للأصل ورفض المتصفّح تخزين Set-Cookie بينما يردّ ووردبريس بالرمز 200. لذلك يعيد المُشغِّل تثبيت المسار الذي وفّرته PHP على الأصل الذي جرى تصفّحه فعلًا.
  2. رمز nonce. يُجلب طازجًا من GET /owc/v1/nonce قبل الكتابة مباشرةً، ولا يُدرَج أبدًا في شيفرة قابلة للتخزين المؤقت، ويُرسَل في الترويسة X-OWC-Nonce. والجلب محدود بأربع ثوانٍ، ورمزٌ غائب أو فارغ أو تعذّر بلوغه لا يمنع الكتابة أبدًا ولا يُبلَّغ به الزائر.
  3. page_url صريح في جسم الطلب، حتى لا يعتمد سطر السجلّ على ترويسة Referer التي قد تحذفها إضافةٌ أو وسم meta-referrer أو وكيل.
  4. حارس ضدّ التعليق مدّته 15 ثانية بواسطة AbortController: يُلغى الطلب، لا يُتجاهَل فحسب، حتى لا يكتب طلب POST متأخّر سطرًا ثانيًا.
  5. تعريف النجاح. يُعدّ الطلب ناجحًا إذا، وفقط إذا: كانت الاستجابة ok، وكان الجسم JSON قابلًا للتحليل، وكان json.ok === true، وأمكن إعادة قراءة ملفّ تعريف الارتباط داخل المتصفّح. فصفحة من الذاكرة المؤقتة، أو تحدٍّ على الحافة، أو جدار حماية تطبيقات يردّ 200 — كلّ ذلك لا يُحتسب.
  6. وإذا ردّ الخادم بـ cookie_set: false، كتب المُشغِّل ملفّ تعريف الارتباط بنفسه بالمعاملات المُعادة، ثم أعاد القراءة. ويبقى الإخفاق إخفاقًا: لا شيء يُنشر، ولا شيء يُطلَق.
  7. إعادة إرسال واحدة لا غير، وفقط على رمز 403 يكون رمزه owc_bad_nonce أو rest_cookie_invalid_nonce أو rest_nonce_invalid، وفقط إذا كان الرمز المُحصَّل مختلفًا فعلًا.
  8. وما ينشره المُشغِّل هو ما خزّنه الخادم: فالفئات التي رفضها الخادم تُطرح من الحالة المحلية.

وما دام طلب POST لم ينجح، فلا شيء يُكشف، ولا شيء يُطلَق، ولا تُرسَل أي إشارة granted إلى Consent Mode.

تصنيف الأخطاء

يميّز المُشغِّل تسعة أسباب، لكلٍّ منها رسالته المرئية: network وrefused وratelimit وunexpected وtimeout وbrowser وconfig وcookie وowc_cookie_not_persisted. وتُوضع حالة HTTP ورمز الخادم على العنصر (data-owc-status وdata-owc-code) وتُسجَّل مرة واحدة عبر console.warn — ولا تُعرض أبدًا كنصّ مرئي. ولذلك تسمّي لقطةُ شاشة من الدعم السببَ دون الحاجة إلى تتبّع للشبكة.

واجهة جافاسكربت للافتة

window.OWCBanner.show();              // يفتح في وضع اللافتة
window.OWCBanner.hide();              // يُغلق
window.OWCBanner.openPreferences();   // يفتح لوحة التفضيلات
window.OWCBanner.openDnsmpi();        // يفتح اللوحة مع marketing وsocial
                                      // وpreferences على OFF سلفًا (مدخل CCPA)
window.OWCBanner.reset();             // يمحو ملفّ تعريف الارتباط من جهة العميل،
                                      // ويرسل سحبًا، ثم يعيد تحميل الصفحة
window.OWCBanner.acceptCategory( 'social' );  // يعيد وعدًا يُحلّ إلى true
                                              // فقط إذا خزّن الخادم القيمة فعلًا

ويُطبَع إقلاع أخفّ داخل <head> بالأولوية 1، ويعرض window.OWConsent: .config و.categories و.geo و.profile و.optOut و.state و.has(cat) و.refresh() و.paint() و.gcmSignals(state). وإعداداته قابلة للترشيح عبر owc_bootstrap_config — لكن كل ما فيه عموميّ ومُشترَك عبر الذاكرة المؤقتة: لا تضعوا فيه أبدًا بيانات خاصة بزائر.

فتح اللوحة من صفحاتكم

ثلاث طرق، كلها متكافئة:

  • جزء الرابط #owc-preferences (أو #owc-dnsmpi)، ويُؤخذ في الحسبان عند التحميل وعند hashchange؛
  • أي عنصر يحمل الفئة owc-open-preferences أو السمة data-owc-open؛
  • السمة data-owc-dnsmpi="1" لفرض سلوك «Do Not Sell».

ويُبثّ الحدث owc:consent-changed عند كل تغيير، مع الحمولة المُرسَلة في تفاصيله. ويستمع إليه الإقلاع، والزرّ العائم، ومُشغِّل CCPA، ووحدة TCF؛ ويمكنكم أنتم أيضًا أن تستمعوا إليه.

حدود اللافتة

  • كل شيء يتوقّف على wp_head() وwp_footer(): فالقالب الذي لا يستدعيهما لا يحصل على شيء.
  • وبدون window.fetch وwindow.Promise تستحيل أي كتابة ويُعرض الخطأ browser.
  • ويمكن أن تُسجَّل موافقة من جهة الخادم دون أن تُحفَظ من جهة المتصفّح (عنوان الموقع مختلف عن المضيف المتصفَّح، أو التخزين محجوب، أو مخزن ملفّات تعريف الارتباط ممتلئ). ويكتشف المُشغِّل هذه الحالة، ويرفض احتسابها نجاحًا، ويعرض رسالة مخصَّصة، ويبلّغ الخادمَ بالأمر عند الكتابة التالية.
  • وليس للافتة رمز مختصر: فهي تظهر في كل مكان أو لا تظهر أبدًا.

الحجب التلقائي

هذه هي الوحدة التي تحوّل الاختيار إلى أثر حقيقي. تعيد كتابة الوسوم الحاملة لأدوات التتبّع قبل أي موافقة، وللجميع، وتترك للمُشغِّل مهمّة إطلاقها داخل المتصفّح.

وضعان، وإعداد واحد

compliance_strict، مفعَّل افتراضيًا.

  • معطَّل (الوضع المرن): لا يُربط سوى المرشّح script_loader_tag. أي أن السكربتات المسجَّلة عبر wp_enqueue_script() وحدها هي التي يُعاد كتابتها. أما <script> مكتوب مباشرةً في القالب، أو تضمين، أو إطار، أو بكسل <img>: فلا يُمسّ شيء منها.
  • مفعَّل (الوضع الصارم): إضافةً إلى المرشّح، يلتقط عازلُ إخراج المستندَ كاملًا، وتُعالَج كذلك الشيفرة المعروضة عبر واجهة REST. وفي لوحة التحكّم، إذا كان الطلب من admin-ajax.php، غطّى عازلٌ منفصل الاستجاباتِ التي تخدم الواجهة الأمامية أيضًا («تحميل المزيد»، والأرشيفات المفلترة) — لكن فقط إذا كان المعالج نفسه قد أعلن Content-Type: text/html.

ما لا يُعزَل أبدًا

ينسحب العازل الصارم فورًا في حالات: لوحة التحكّم، وطلبات AJAX، والتغذيات، وrobots.txt، وردود التتبّع (trackbacks)، وcron، وأيقونات الموقع، وطلبات REST، وطلبات JSON، ومعاينة أداة التخصيص، وخرائط الموقع، ونقاط الدخول wp-login.php وwp-register.php وwp-signup.php وxmlrpc.php وwp-cron.php وwp-trackback.php — وتُختبَر على اسم السكربت بالضبط، لا كسلسلة فرعية داخل الرابط. وينسحب كذلك لطلبات الماسح، التي تحتاج إلى شيفرة HTML الخام.

المراحل الخمس

تجري إعادة الكتابة بتعابير نمطية مُعايَرة، لا بمحلّل DOM أبدًا. وثلاثة حواجز واقية تؤطّر العملية كلها: أي مستند يتجاوز 8 ميغابايت يُعاد كما هو، وأي إخفاق في محرّك PCRE يُعيد المستند كما هو، وإذا صارت النتيجة أقلّ من نصف الحجم الأصلي أُعيد الأصل. أي أن نمط الإخفاق في الحجب هو «صفحة تُقدَّم بلا حجب»، لا «صفحة مكسورة» أبدًا.

المرحلة 0 — الإخفاء. تُستبدَل تعليقات HTML ووسوم <style> و<textarea> بعلامات مبنية على محارف تحكّم، حتى لا ينطبق أي نمط لاحق على ما بداخلها.

المرحلة 1 — <script>. القرار، بالترتيب:

  1. مُعالَج سلفًا ← يُترك كما هو؛
  2. سكربت من الإضافة نفسها ← يُترك كما هو؛
  3. type="text/plain" أو نوع غير جافاسكربت (ld+json، importmap، x-template) ← يُترك كما هو؛
  4. يُبحث عن الرابط في src وdata-src وdata-rocket-src وdata-lazy-src وdata-litespeed-src وdata-cfsrc — أي أن سمات إضافات الأداء مغطّاة؛
  5. مضيف داخل القائمة البيضاء ← يُترك كما هو؛ ومورد داخلي لا يشبه أداة تتبّع ← يُترك كما هو؛
  6. مطابقة مع الكتالوج على صيغة مضيف + مسار؛ ورابط data: أو javascript: يُفكّ ترميزه ويُحكَم عليه كمتن مضمّن؛
  7. القاعدة المصنَّفة necessary لا تُحجب أبدًا (Stripe.js، وreCAPTCHA، وTurnstile، وcdnjs…): فحجبها لا يكسب أي امتثال ويكسر المقطع الذي يستدعيها؛
  8. لا مطابقة ← blocker_unknown_script_policy، والافتراضي allow؛
  9. وإلا فإعادة كتابة إلى type="text/plain" مع data-owc-cat وdata-owc-vendor وdata-owc-src، ومع data-owc-type إذا كان النوع الأصلي خاصًّا (module مثلًا) حتى لا يتدهور السكربت المُستعاد.

وتُقارَن المتون المضمّنة أولًا بقواعد الكتالوج من نوع inline_signature، ثم بأربع عشرة بصمة مثبَّتة في الشيفرة: fbq(، و_fbq.push، وgtag(، وdataLayer.push(، وga('…، و_gaq.push، و_paq.push، وhjid، وclarity(، وttq.load|track|page، وsnaptr(، وtwq(، وlintrk(، وpintrk(. وثمة استثناء صريح: نداء gtag('consent', …) وحده، أي إعلان Consent Mode افتراضي بلا أي علامة أخرى، يبقى منفَّذًا.

المرحلة 2 — <iframe>. سمات الروابط نفسها، إضافةً إلى data-original وdata-srcset. مورد داخلي أو قائمة بيضاء ← يُترك كما هو. وnecessary ← يُترك كما هو، وإلا لصار نموذجٌ فيه captcha غير قابل للإرسال. وبلا مطابقة ← blocker_unknown_iframe_policy، والافتراضي block. ويصير الإطار المحجوب src="about:blank" ويُغلَّف ببديل بصريّ يحوي زرّ «قبول <المزوّد>» الذي يُطلق الفئة المقابلة.

المرحلة 3 — <img>، بكسلات التتبّع فقط. قاعدة مهمّة: سطر كتالوج وحده لا يكفي أبدًا لتحييد صورة. فإذا طابقت الصورة الكتالوج لكن فئتها ليست analytics ولا marketing — كشبكة توصيل صور، أو خدمة صور رمزية، أو مستضيف خطوط — تُركت كما هي، وإلا لحُذفت وسائط الموقع بدل أداة تتبّع. ولا يستطيع الحجب إلا عبر استدلال الوسم: إحدى عشرة نقطة جمع معروفة (facebook.com/tr، وpx.ads.linkedin.com، وct.pinterest.com، وbat.bing.com، وanalytics.twitter.com، وt.co/i/adsct، وtr.snapchat.com، وanalytics.tiktok.com، وgoogle-analytics.com/collect، وgoogleads.g.doubleclick.net، وpixel.quantserve.com)، أو صورة خارجية بحجم 1×1 بكسل. وعندئذٍ يُستبدَل src بصورة GIF شفّافة، وتُحذف كل السمات الحاملة للروابط حتى لا يعيد مُحمِّل تكاسليّ الرابطَ الأصلي.

المرحلة 4 — <link>. مشروطة بـ blocker_block_resource_hints، والافتراضي true. ولا تعالج سوى المضيفين الموجودين سلفًا في الكتالوج، ولا مضيفًا مجهولًا أبدًا.

  • تلميحات الموارد (preconnect، وdns-prefetch، وprefetch، وprerender، وpreload، وmodulepreload) المتّجهة إلى طرف ثالث مُفهرَس تُحذف، لا تُؤجَّل: فالتلميح يفتح اتصال TCP+TLS ويكشف عنوان IP للزائر وبصمة TLS الخاصة به، ولا يبقى بعده ما يُستعاد.
  • وورقة الأنماط المصنَّفة analytics أو marketing تُحيَّد.
  • وGoogle Fonts وسائر مستضيفي الخطوط المصنَّفين functional لا يُمَسّون أبدًا: فتحييدهم يعطي نصًّا بخطّ احتياطي في الموقع كله، بلا أي مكسب في الامتثال.

المرحلة 5 — <object> و<embed> و<source> و<video> و<audio>. لا حجب افتراضيًا أبدًا: ولا يُعالَج سوى طرف ثالث مُفهرَس سلفًا. وتُزال السمتان autoplay وpreload.

ما يُحتسب «طرفًا داخليًا» (first party)

رابط الموقع، ورابط ووردبريس، ورابط المحتوى، ورابط ملفّات includes، ونظائرها الشبكية في وضع الشبكة، وقاعدة مجلّد الرفع. ويُحذف www. عند المقارنة. وكل مسار يبدأ بـ /wp-content/ أو /wp-includes/ يُعدّ داخليًا أيًّا كان المضيف، لتغطية إعادات الكتابة عبر شبكات التوصيل. أما المخطّطات غير HTTP (data:، وblob:، وjavascript:) فلا تُعدّ داخلية أبدًا.

وثمة استثناء مضادّ: أي رابط يحوي gtag أو gtm.js أو analytics أو pixel أو fbevents أو hotjar أو matomo أو piwik أو clarity يُعالَج حتى على مضيف الموقع نفسه. وهذا ما يلتقط GTM أو Matomo مستضافًا ذاتيًا، والوكلاء الداخليين.

مُشغِّل الإطلاق

يُطبَع داخل <head> بالأولوية 2. ولا تحوي إعداداته بصيغة JSON سوى اسم ملفّ تعريف الارتباط وقائمة المضيفين المراقَبين — لا شيء يتوقّف على الزائر.

  • قراءة الحالة: يُفكّ ترميز ملفّ تعريف الارتباط owc_consent حتى الاستقرار، بحدّ أقصى ثلاث مرات، لأن ملفّات تعريف الارتباط المكتوبة قبل الإصدار 1.4.3 كانت مُرمَّزة مرتين.
  • حارس السكربتات المحقونة ديناميكيًا: يُغلَّف كلٌّ من الضابط HTMLScriptElement.prototype.src وsetAttribute. فمُحمِّل داخلي يُسنِد s.src = 'https://www.googletagmanager.com/gtm.js?id=…' يُعترَض ويُختم العنصر قبل تنفيذه. والقائمة المراقَبة تضمّ عشرين مضيفًا: googletagmanager.com، google-analytics.com، googleadservices.com، googlesyndication.com، doubleclick.net، connect.facebook.net، static.hotjar.com، script.hotjar.com، clarity.ms، cdn.matomo.cloud، analytics.tiktok.com، snap.licdn.com، sc-static.net، static.ads-twitter.com، bat.bing.com، s.pinimg.com، cdn.segment.com، js.hs-scripts.com، cdn.amplitude.com، cdn.mxpnl.com. وكل ما ليس فيها يمرّ دون أن يُمَسّ. أما مضيفو قائمتكم البيضاء فيُزالون من هذه القائمة قبل طباعتها.
  • إعادة الحقن بترتيب المستند. السكربت الخارجي المُستعاد يوقف الطابور حتى onload أو onerror الخاص به، بمهلة قصوى خمس ثوانٍ حتى لا يوقف مزوّدٌ لا يمكن بلوغه بقيةَ الطابور. ولا تُطبَّق السمة async إلا إذا كانت موجودة أصلًا — فبدون ذلك سيُفرَض الوضع اللاتزامني على سكربت أُنشئ بـ createElement وسيُنفَّذ مقطع الإعداد قبل مكتبته. وللسكربت المضمّن المُستعاد، يُحوَّل document.write مؤقتًا كي لا يمحو المستند.
  • سحب الموافقة: إذا انتقلت فئة مطبَّقة سلفًا إلى false صراحةً، أعاد المُشغِّل تحميل الصفحة. فالسكربت الذي نُفِّذ لا يمكن إلغاء تحميله (المادة 7.3 من GDPR). أما فئة غائبة ببساطة عن الحمولة فليست سحبًا.
  • ويعيد MutationObserver مسحَ الشيفرة المحقونة بعد التحميل (AJAX، والأقسام التكاسلية).
  • والنقر على زرّ تضمين محجوب يستدعي OWCBanner.acceptCategory()؛ فإن لم تكن واجهة اللافتة موجودة، أُطلق التضمين محليًا، بلا حفظ أي شيء.

كتالوج البصمات

الجدول {prefix}owc_scripts. والملفّ المُضمَّن، data/tracker-catalog.json، يحوي 175 سطرًا تغطّي 71 مزوّدًا متمايزًا:

التوزيعالتفصيل
حسب الهدف110 نمط رابط، و65 اسم ملفّ تعريف ارتباط
حسب النوع172 مقطع نصّي، و3 تعابير نمطية
حسب الفئةnecessary 55، marketing 37، functional 37، analytics 36، social 10

الأعمدة: pattern، وpattern_type (host، regex، inline_signature)، وmatch_target (url أو cookie)، وname، وvendor، وcategory، وprivacy_policy_url، وgcm_signal، وtcf_vendor_id، وretention_days.

وثمة سلوكان ينبغي معرفتهما:

  • الأسطر التي match_target = 'cookie' لا يستعملها الحجب أبدًا. فهي تخدم جدول ملفّات تعريف الارتباط في الوثائق المولَّدة فقط. ومقارنتها كسلسلة فرعية داخل رابط هي بالضبط ما كان يكسر جافاسكربت المواقع.
  • ونمطٌ من النوع host يستهدف رابطًا، وطولُه أقلّ من ستّة محارف وبلا نقطة، يُرفض: فـ «fr» أو «IDE» ستطابق «frame.js» و«provider.js».

ويُخزَّن الكتالوج مؤقتًا في ذاكرة الكائنات (ساعة واحدة) وفي عابر (12 ساعة). ولا تُخزَّن نتيجة فارغة أبدًا. وكل عملية كتابة تُطلق الإجراء owc_catalog_updated الذي يُفرغ هذه الذواكر.

ويتيح تبويب Tracker catalogue إضافة القواعد وتعديلها وحذفها والبحث فيها، مع مرشّح «القواعد التي لا يمكن أن تنطبق فقط»: نمط فارغ أو غير مرئي، أو تعبير نمطي لا يُترجَم أو يتراجع تراجعًا كارثيًا، أو نمط أقصر من اللازم وبلا نقطة لاستهداف رابط، أو فئة لم تعد موجودة. ويجري هذا التشخيص في PHP، لأن محرّك PCRE وحده يستطيع أن يقول إن تعبيرًا ما يُترجَم أم لا.

إعدادات الحجب

الإعدادالافتراضيالقيم
compliance_stricttrueقيمة منطقية
blocker_unknown_script_policyallowallow، block
blocker_unknown_iframe_policyblockallow، block
blocker_block_resource_hintstrueقيمة منطقية
blocker_allowlist''مضيف واحد في كل سطر

نقاط التوسّع

// مضيفون لا يُحجبون أبدًا، إضافةً إلى blocker_allowlist.
add_filter( 'owc_blocker_allowlist', function ( array $hosts ) {
    $hosts[] = 'cdn.mon-partenaire.example';
    return $hosts;
} );

// أسطر الكتالوج قبل التحقّق منها.
add_filter( 'owc_scripts_catalog', function ( array $rows ) {
    $rows[] = array(
        'pattern'      => 'tracker.example.com',
        'pattern_type' => 'host',
        'match_target' => 'url',
        'name'         => 'مثال',
        'vendor'       => 'شركة المثال',
        'category'     => 'analytics',
    );
    return $rows;
} );

وتطبّق الدالة العمومية OWC_Blocker::block_html_fragment( $html ) الحجبَ على مقطع لم يمرّ عبر عازل الإخراج.

حدود الحجب

  1. بلا compliance_strict، لا تُعالَج سوى السكربتات التي أدرجها ووردبريس.
  2. السكربت الخارجي المجهول مسموح افتراضيًا. والحجب الفعلي يقوم على الكتالوج والبصمات المضمّنة — فأثروهما.
  3. حارس السكربتات المحقونة بجافاسكربت لا يغطّي سوى عشرين مضيفًا؛ وأداةُ تتبّع خارج القائمة يحقنها كود داخلي تمرّ.
  4. أوراق الأنماط المصنَّفة functional (خطوط الويب) تُترك تمرّ عن قصد.
  5. أداة تتبّع مُفهرَسة داخل <img> لكن مصنَّفة بغير analytics أو marketing لا تُحيَّد.
  6. الوسائط (object، وembed، وsource، وvideo، وaudio) لا تُحجب افتراضيًا أبدًا: ولا يُعالَج سوى طرف ثالث مُفهرَس سلفًا.
  7. أي مستند يتجاوز 8 ميغابايت، أو إخفاق في PCRE، أو فقدان أكثر من 50 % من المحتوى يعطي صفحة تُقدَّم بلا أي حجب، وبصمت.
  8. سحب الموافقة يستدعي إعادة تحميل كاملة للصفحة.

ماسح أدوات التتبّع

يجرد الماسح ما تُحمّله صفحاتكم فعلًا. وهو معطَّل افتراضيًا: فعّلوه من تبويب Scanner.

ثلاثة مصادر للكشف

تحتفظ كل نتيجة بمصدرها وبمعلومة «هل يستطيع الحجب أن يطالها».

1. شيفرة HTML المُقدَّمة. يجلب الماسح عيّنة من روابط موقعكم أنتم ويقرأ الشيفرة: <script src> و<script data-owc-src> — أي أن السكربتات المحجوبة سلفًا تُرى رغم ذلك — والبصمات المضمّنة، و<iframe>، وأوراق الأنماط الخارجية، والصور التي يحوي رابطها 1x1 أو pixel أو track أو beacon أو impression. ولا يُنفَّذ أي جافاسكربت: فما يحقنه مدير الوسوم أثناء التشغيل غير مرئي لهذه المرحلة.

2. ترويسات Set-Cookie. هي ملفّات تعريف الارتباط الوحيدة التي يستطيع المسح من الخادم أن يثبتها، بما فيها ملفّات HttpOnly التي لن يراها مِجَسّ متصفّح أبدًا. وتُوسَم بأنها غير قابلة للحجب: فلا شيء في الحجب من جهة العميل يستطيع إيقاف ملفّ تعريف ارتباط أصدره الخادم. أما ملفّات تعريف الارتباط الخاصة بالإضافة نفسها فتُتجاهَل.

3. مِجَسّ المتصفّح. يُطبَع في التذييل فقط لمستخدم مسجَّل يملك manage_options، وفقط إذا كان الماسح مفعَّلًا. يلتقط document.cookie عند التحميل، ويراقب تغيّرات DOM — وهذا ما يلتقط ما يحقنه مدير الوسوم — ويستعلم عن document.cookie كل 5 ثوانٍ بحثًا عن ملفّات تعريف الارتباط المكتوبة من جهة العميل، ويُرسل ملاحظاته كل ثانيتين وعند beforeunload. والاستجابة الحاملة للمِجَسّ تُوسَم بأنها غير قابلة للتخزين المؤقت.

حدّ معترَف به في الشيفرة: المدير قد قَبِل كل شيء عادةً. ولذلك يصف المِجَسّ الحالة بعد الموافقة، لا الحالة قبلها.

المسح

يُبنى طابور الروابط لتغطية قوالب لا صفحات: الروابط الجوهرية أولًا (الصفحة الرئيسية، والصفحة الرئيسية الثابتة، وصفحة المقالات، وصفحات السياسات الأربع المرتبطة)، ثم تناوب دوريّ بين العائلات — حتى 30 صفحة، و15 مقالًا، و5 لكل نوع محتوى عمومي مخصَّص، و3 تصنيفات، و3 وسوم. فبلا هذا التناوب، كانت ثلاثون صفحة شبه متطابقة تلتهم الميزانية كلها ولا تُبلَغ قوالب WooCommerce أبدًا.

ويتيح المرشّح owc_scanner_urls إضافة روابط، لكن النتيجة تُقيَّد من جديد بمضيف الموقع: فالماسح لا يخرج من نطاقكم أبدًا.

ويُجرى كل طلب مع تتبّع يدوي لإعادات التوجيه (قفزتان كحدّ أقصى، وكل قفزة تُختبَر من جديد أمام مضيف الموقع)، واستجابة محدودة بميغابايتين، وترويسة Cache-Control: no-cache, no-store، ومعامل رابط فريد كي لا تُقرأ صفحة من الذاكرة المؤقتة، ووكيل مستخدم OW-Consent-Scanner/<version>. والاستجابة غير HTML تُحتسب متجاوَزة، لا مُخفِقة.

ويُرسَل سرّ تجاوز في الترويسة X-OWC-Scanner كي ينسحب الحجب ويُظهر شيفرة HTML الخام. ويُقارَن في زمن ثابت، وتُختبَر الترويسة أولًا كي لا يُطلق زائرٌ عادي حتى قراءة الخيار.

الميزانية والقفل والاستئناف

القيدالقيمة
الروابط في كل تنفيذscanner_max_urls، الافتراضي 25، الحدود من 1 إلى 500
المهلة لكل طلبscanner_timeout، الافتراضي 8 ثوانٍ، الحدود من 1 إلى 60
ميزانية الوقت لكل دفعةmax_execution_time − 10 s، وإلا 45 ثانية، محدودة بين 5 و60 ثانية
قفل التنفيذ15 دقيقة
عمر الطابور6 ساعات

وإذا نفدت الميزانية، جُدوِل استئناف بعد دقيقة وتابع المسح من حيث توقّف. وإطلاق ثانٍ أثناء مسح جارٍ يردّ «ثمة مسح قيد التنفيذ». وقطعٌ للدائرة: إذا أخفقت ثلاثة طلبات دون أن تُقرأ أي صفحة، توقّف المسح بدل أن يحرق مهلته على اثنين وعشرين رابطًا آخر — وهذه هي الحالة النمطية لموقع محجوب فيه الاتصال الحلقي (loopback) عبر HTTP.

البصمات المضمّنة المعروفة

ثلاث وعشرون علامة، مجمّعة في إحدى وعشرين تسمية: gtag('config'، وgtag('event'، وgtag('js'، وgtm.start، وga('create'، وga('send'، وfbq('init'، وfbq('track'، و_paq.push، و(h.hj=h.hj، وclarity('init'، وclarity.ms/tag، وmixpanel.init، وamplitude.init، وamplitude.getInstance، و_linkedin_partner_id، وsnaptr('init'، وttq.load، وpintrk("load"، وpintrk('load'، وrdt('init'، وcriteo_q.push، و_etmc.push.

ومفتاح إزالة التكرار هو البصمة، لا بصمة المتن أبدًا: فمقطع gtag أو Pixel حقيقي يحوي قيمًا خاصة بالصفحة، ما يعطي سطرًا لكل صفحة.

حلقة التغذية الراجعة: نتيجة ← كتالوج ← حجب

هذه هي النقطة التي تجعل الماسح مفيدًا. تصنيفُ أداة تتبّع يكتب قاعدة في كتالوج الحجب. فالنقر على فئة نتيجةٍ ما يفعل ثلاثة أشياء: يكتب الفئة على السطر، ويحفظ قراركم اليدوي، وينشئ القاعدة المقابلة. وفي نهاية كل مسح كامل، تُجرى العملية نفسها جملةً لما لا يعرف الكتالوج تصنيفه سلفًا.

قواعد التحويل:

  • النتيجة من نوع cookie تصير قاعدة match_target = cookie على اسم ملفّ تعريف الارتباط؛
  • والنتيجة من نوع inline_script لا تكتب قاعدة إلا إذا عُثر على العلامة الأصلية. وبدونها لا تُكتب أي قاعدة: فقاعدة مبنيّة على التسمية «Google gtag (config)» ستكون ميّتة إلى الأبد وستطابق اسم النتيجة، ما يجعلها تبدو «مغطّاة» إلى الأبد؛
  • وإلا فقاعدة host على النطاق، تُرفض إن كان النطاق فارغًا.

وتُخزَّن قراراتكم اليدوية على حدة (500 كحدّ أقصى) ويُعاد تطبيقها عند كل ملاحظة جديدة، لأن راية «مؤكَّد» تعني أيضًا «انطبقت قاعدة كتالوج» ولذلك لا تستطيع وحدها حمل معلومة «المدير حسم الأمر». وإعادة التصنيف إلى «غير مصنَّف» تحذف المدخل: فهو تراجع حقيقي.

ويُقارَن الكتالوج بالنمط الأطول أولًا، حتى لا تطمس قاعدة واسعة (google-analytics.com) القاعدةَ الأدقّ التي كتبتموها (www.google-analytics.com).

الجدولة والتنبيهات ومدة الحفظ

يقبل scanner_frequency القيم hourly وtwicedaily وdaily وweekly — لكن لوحة التحكّم لا تعرض سوى التكرارات التي يعرفها تثبيتكم فعلًا. والافتراضي: weekly. وتعطيلُ الماسح يلغي جدولة الحدثين.

ورسالتان بريديتان متمايزتان، ولا تُرسلان معًا أبدًا:

  1. أدوات تتبّع غير مصنَّفة — تُرسَل فقط لمعرّفات جديدة فعلًا، بذاكرة محدودة بـ 500 مدخل.
  2. «تعذّر على المسح قراءة هذا الموقع» — محدودة برسالة واحدة أسبوعيًا لكل بصمة خطأ. وهذا هو نمط الإخفاق الأخطر، لأن مسحًا لا يقرأ شيئًا لا ينتج أي نتيجة، ومن ثمّ لا ينتج أي تنبيه من النوع الأول.

المُستقبِل: scanner_alert_email، وإلا فعنوان إدارة الموقع.

مدة الحفظ: 90 يومًا. تُحذف النتائج التي لم تُشاهَد منذ 90 يومًا، ما إن تُقرأ صفحة واحدة على الأقل — لا عند انتهاء مسح فحسب.

لوحة التغطية

هذه أهمّ أجزاء تبويب Scanner، وهي تغذّي أيضًا بطاقة التنبيه في الوثائق المولَّدة. وتجيب دائمًا عن هذه الأسئلة:

  • هل أُطلق مسح من قبل؟
  • هل انتهى الأخير، أم قطعته ميزانيته الزمنية؟
  • كم صفحة جرى جلبها فعلًا (لا سحبها من الطابور)؟
  • كم صفحة تعذّر جلبها، وما أول خطأ وقع؟
  • هل أبلغ متصفّحٌ يومًا بشيء، أم لم يُرصد جافاسكربت قطّ؟
  • ما النافذة التي تختفي بعدها أداةُ تتبّع لم تُشاهَد؟

والمسح الذي لم يبلغ أي صفحة يُعرض بوصفه إخفاقًا، لا نتيجةً نظيفة. وهذه هي اللوحة التي يجب أن تقرؤوها قبل نشر سياسة ملفّات تعريف ارتباط مبنيّة على هذه النتائج.

تبويب Scanner

ثلاث بطاقات (أدوات التتبّع المكتشَفة، وغير المصنَّفة، وآخر مسح والتنفيذ التالي)، ولوحة التغطية، وزرّ «شغّل مسحًا الآن»، ونموذج الجدولة، ثم قائمة النتائج: مرشّحات حسب الفئة، وبحث نصّي، ومرشّح حسب نوع العنصر (script، وinline_script، وiframe، وstylesheet، وpixel، وcookie، وlink، وpreconnect)، ومرشّح حسب الحالة، وتصدير CSV، وترقيم صفحات بـ 25. والتصنيف فرديًا أو جملةً — ولمُحدِّد الجملة عنصر أول فارغ ومعطَّل، حتى لا يتحوّل إرسال عرضيّ إلى إلغاء تصنيف شامل.

إعدادات الماسح

الإعدادالافتراضيالحدود
scanner_enabledfalseقيمة منطقية
scanner_frequencyweeklyhourly، twicedaily، daily، weekly
scanner_max_urls25من 1 إلى 500
scanner_timeout8من 1 إلى 60
scanner_probe_modeadminsadmins، off
scanner_alert_email''عنوان بريد إلكتروني

لعلمكم: scanner_probe_mode غير مُستهلَك في هذا الإصدار. والشيفرة تشير إلى ذلك صراحةً — فشرط طباعة المِجَسّ لم يعد يقرأ هذا الإعداد ويعتمد على scanner_enabled وحده. وحفظُ القيمة off يخزّنها دون تعطيل المِجَسّ. ولإيقاف المِجَسّ فعلًا، عطّلوا الماسح.

حدود الماسح

  1. لا يُنفَّذ أي جافاسكربت في المسح من جهة الخادم. فبلا المِجَسّ، يغيب عن الجرد ما يحقنه مدير الوسوم.
  2. المِجَسّ مقصور على المديرين المسجَّلين، ولا يوجد أي وضع يشغّله لزائر عادي: فذلك سيتطلّب إعلامًا مسبقًا خاصًّا به.
  3. ملفّ تعريف ارتباط وُضع بترويسة Set-Cookie يُكتشَف لكنه غير قابل للحجب.
  4. المسح لا يخرج من النطاق أبدًا وهو محدود بـ 25 رابطًا افتراضيًا: فالموقع الكبير لا يُغطّى بالكامل أبدًا.
  5. على مستضيف يُحجب فيه الاتصال الحلقي عبر HTTP (مصادقة HTTP في بيئة اختبار، أو جدار حماية)، لا يقرأ المسح شيئًا.
  6. النتيجة التي لم تُشاهَد منذ 90 يومًا تختفي، ومن ثمّ تختفي أيضًا من سياسة ملفّات تعريف الارتباط.
  7. الماسح يعتمد على WP-Cron: فعلى موقع فيه DISABLE_WP_CRON وبلا cron على مستوى النظام، لا ينطلق المسح المجدول.

مولّد الوثائق القانونية

الوثائق الأربع

النوعالمحتوىاللغات المتاحة
cookie_policyسياسة ملفّات تعريف الارتباطالفرنسية، الإنجليزية، البرتغالية
privacy_policyسياسة الخصوصيةالفرنسية، الإنجليزية، البرتغالية
legal_noticeالبيانات القانونيةالفرنسية فقط
termsالشروط العامةالفرنسية فقط

كل وثيقة مولَّدة هي صفحة ووردبريس، ذات إصدارات مضبوطة ببيانات وصفية: _owc_policy_type، و_owc_policy_version (تُزاد عند كل توليد)، و_owc_policy_hash (بصمة SHA-256 لشيفرة HTML)، و_owc_policy_generated_at، و_owc_policy_profile، و_owc_policy_lang، و_owc_policy_manual_edit.

وبعد التوليد، يُعاد حقن الرابط في الإعدادات المقابلة (link_cookie_policy، وlink_privacy_policy، وlink_legal_notice، وlink_terms)، ونشرُ سياسة الخصوصية يحدّث صفحة السياسة المعلنة في ووردبريس.

قفلان قبل النشر

القفل 1 — الحقول الإلزامية. يُرفض التوليد مع قائمة المفاتيح الفارغة، بدل نشر بنود ناقصة.

الوثيقةالحقول المطلوبة
الجميعlegal_company_name، legal_company_email
عدا سياسة ملفّات تعريف الارتباط+ legal_company_address، legal_country
البيانات القانونية+ legal_company_phone، legal_publication_director، legal_host_name، legal_host_address، legal_host_phone
البيانات القانونية، بلد FR / BE / LU+ legal_company_legal_form، legal_company_reg_number

القفل 2 — اللغة. يرفض المولّد نشر وثيقة محرَّرة بلغة لا تستعملها الولاية القضائية. وفي المعاينة، تخرج الوثيقة بشريط تنبيه أحمر؛ أما في النشر فهو رفض قاطع. وفي تبويب Policies، يكون زرّ التوليد مخفيًّا حين لا يوجد قالب للنوع والملفّ النشطين، بدل أن يظهر ويُخفق دائمًا.

تحديد اللغة

الملفّلغة الوثيقة
quebecالفرنسية
lgpdالبرتغالية
gdpr مع legal_country ضمن {FR, BE, LU}الفرنسية
كل ما عدا ذلكالإنجليزية

التنبيه الإلزامي

ما دام policy_disclaimer مفعَّلًا — وهو كذلك افتراضيًا — تنتهي كل وثيقة بكتلة تقول إنها نموذج مولَّد آليًا يجب أن يراجعه مختصّ مؤهَّل قبل النشر، وتحمل تاريخ التوليد وإصدار الإضافة. فلا تعطّلوه إلا عن دراية.

جدول أدوات التتبّع — قواعد الصدق

الجدول المنشور في سياسة ملفّات تعريف الارتباط يأتي من جدول الماسح لديكم، لا من قاعدة طرف ثالث. وخمس قواعد تحكم ما يعرضه.

  1. نافذة الحداثة: لا تُنشر إلا النتائج التي شوهدت خلال التسعين يومًا الأخيرة. وإذا لم يكن عمود آخر مشاهدة موجودًا بعدُ لأن ترحيلة لم تُنفَّذ، تُتجاهَل النافذة بدل نشر «لا أدوات تتبّع» على موقع لديه أدوات — فالإفصاح الناقص هو الاتجاه الوحيد الذي لا يجوز لوثيقة قانونية أن تُخفق فيه.
  2. بطاقة تنبيه في رأس الجدول، مشتقّة من لوحة تغطية الماسح: مسح لم يُطلق قطّ، أو لم تُقرأ أي صفحة، أو مسح مقطوع، أو N رابطًا أخفق، أو لا ملاحظة مع جافاسكربت نشط، أو نافذة من N يومًا. فالمسح الناقص يُفصَح عنه، لا يُنشر كجرد مكتمل.
  3. أدوات التتبّع غير المصنَّفة لا تُخفى: بل لها قسمها الخاص. وهي التي لم يفحصها أحد.
  4. ملفّ تعريف الارتباط الملاحَظ في ترويسة Set-Cookie يُعلَّم بعلامة مميّزة، مع ملاحظة تشرح أن الخادم هو من يضعه وأن أي حجب من جهة العميل لا يستطيع إيقافه. ولذلك لا يجوز تقديمه على أنه مشروط بالموافقة، والبندُ الذي يؤكّد أن أدوات التتبّع غير المصنَّفة لا تُوضع إلا بعد الموافقة يحمل الاستثناء المقابل.
  5. اسم المسؤول والرابط إلى سياسته يأتيان من الكتالوج، وللقواعد التي تستهدف رابطًا فقط. أما أنماط أسماء ملفّات تعريف الارتباط فمستبعدة: فلا نؤكّد في وثيقة قانونية من يعالج البيانات بلا إثبات.

ملفّات تعريف الارتباط الخاصة بالموقع والمُدد المنشورة

يسرد قسم «ملفّات تعريف الارتباط التي يضعها هذا الموقع» ملفّات الإضافة نفسها: owc_consent (مدّته مشتقّة من إعداد التجديد)، وeuconsent-v2 إذا كان TCF مفعَّلًا، وowc_geo إذا كان الكشف الإقليمي مفعَّلًا، وowc_gpc (مدّة الجلسة)، وowc_gpc_notice (5 دقائق)، إضافةً إلى ملفّات تسجيل الدخول والإعدادات في ووردبريس.

ويستمدّ جدول مُدد الحفظ أرقامه من الإعدادات الحقيقيةledger_retention_days، وretention_form_data_days، وretention_dsar_days، ومدة تجديد الموافقة. ولا تُنشر أي قيمة تزيينية. ومدةُ ملفّ تعريف ارتباط الموافقة مشتقّة من الحساب نفسه الذي يحكم الملفّ ذاته، ما يضمن أن إعدادًا بقيمة 0 شهر ينشر «13 شهرًا» لا «أبدًا».

كشف نوع النشاط (الشروط العامة)

تضمّ الشروط العامة 21 قسمًا، مع تبديل بين بائع ومقدّم خدمة، وبين منتجات وخدمات، وبين عرض سعر وطلب، وبنود خاصة بكل نوع نشاط.

وlegal_business_type (auto، وvitrine، وrental، وecommerce، وservices، وsaas، وcontent) هو مصدر الحقيقة. وحين تكون قيمته auto، يفحص استدلالٌ الموقعَ — وجود WooCommerce، والتسجيل المفتوح، وإضافات الاشتراكات، وصفحة الأسعار، وصفحات الخدمات، ثم كثافة الكلمات المفتاحية في آخر خمسين محتوًى منشورًا — لكن حُكمه لا يُطبع أبدًا في وثيقة منشورة: فهو لا يخدم سوى اختيار البنود الاختيارية.

ولا تُدرَج الاستشهادات بالمواد الفرنسية إلا إذا كانت قيمة legal_country هي FR. ولبلجيكا استشهاداتها الخاصة (قانون القانون الاقتصادي المادة VI.45 §1، والمادة VI.47، ودائرة الوساطة للمستهلك)؛ أما لوكسمبورغ وكيبك فيتلقّيان صيغة محايدة. فالاستشهاد بنصّ غير مُتحقَّق منه سيكون هو العيب، لا العلاج.

سلوكيات أخرى

  • تاريخ الوثيقة يُنسَّق بلغة الوثيقة. وإذا لم تكن حزمة الترجمة المقابلة مثبَّتة، انتقل التنسيق إلى DD/MM/YYYY: فالوثيقة الفرنسية لا يمكن أن تُفتتح بـ «4 September 2026».
  • كشف التعديل اليدوي: إذا لم يعد المحتوى المخزَّن مطابقًا لبصمته، سُجّلت مراجعة قبل الاستبدال وعرضت الشاشة شارة «استُبدلت تعديلات يدوية»، مع رابط إلى المراجعات.
  • المولّد لا يتراجع أبدًا: فالصفحة المنشورة تبقى منشورة حتى لو أُلغي تأشير خانة «نشر»، وأي عنوان أو رابط دائم أعدتم تسميته يبقى بعد إعادة التوليد.
  • الحقن في قائمة التذييل: auto_footer_menu_inject، معطَّل افتراضيًا. فلا تعدّل الإضافة موقعكم العمومي بلا طلب صريح. والمواضع المعروفة عند تفعيله: footer، وfooter-menu، وfooter_menu، وfooter-1، وfooter_1، وsecondary، وlegal.

نقاط التوسّع

// المتن الخام للقالب، مع بقاء {{المتغيّرات}} في مكانها.
add_filter( 'owc_policy_template', function ( $html, $type, $profile ) {
    return $html;
}, 10, 3 );

// المتغيّرات المحقونة في القالب.
add_filter( 'owc_policy_vars', function ( array $vars, $type, $profile ) {
    return $vars;
}, 10, 3 );

// شيفرة HTML النهائية، بعد استبدال المتغيّرات.
add_filter( 'owc_policy_html', function ( $html, array $vars ) {
    return $html;
}, 10, 2 );

وتوفيرُ متنكم الخاص عبر owc_policy_template يعطّل قفل اللغة: فالموقع الذي يوفّر نصّه يتحمّل مسؤولية لغته. وهذه هي الطريقة الرسمية لنشر بيانات قانونية بغير الفرنسية.

وثمة أربع كتل مولَّدة مسبقًا متاحة كمتغيّرات محجوزة: {{__trackers_table__}}، و{{__categories_list__}}، و{{__retention_table__}}، و{{__jurisdictional_rights__}}. وكل المتغيّرات مُهرَّبة سلفًا في سياق استعمالها. وثلاث دوال عمومية قابلة لإعادة الاستعمال من قالب خارجي: OWC_Policies::build_cookie_table()، وbuild_data_retention_table()، وrender_first_party_cookies().

مسارات REST

الطريقةالمسارالمعاملاتالوصول
POST/owc/v1/policies/generatetype (مطلوب)، publish (منطقي، الافتراضي false)manage_options
GET/owc/v1/policies/previewtype (مطلوب)manage_options

وتمرّ شيفرة HTML الخاصة بالمعاينة عبر wp_kses_post() قبل إعادتها.

حدود المولّد

  1. هذه نماذج، لا استشارة قانونية. اعرضوها على مختصّ.
  2. البيانات القانونية والشروط العامة موجودة بالفرنسية فقط. وأي ولاية قضائية أخرى تصطدم بقفل اللغة، إلا إذا وفّرتم متنكم الخاص.
  3. ثلاث لغات فقط: الفرنسية والإنجليزية والبرتغالية.
  4. أربع دول في المنطقة الاقتصادية الأوروبية لها سلطة مُسمّاة؛ وما عداها يتلقّى صيغة عامة.
  5. جدول أدوات التتبّع لا يساوي إلا ما يساويه مسحكم — والوثيقة تقول ذلك.
  6. صنف المولّد يزن نحو 440 كيلوبايت من القوالب القانونية: ولذلك يُحمَّل تكاسليًا، وفقط حين تُستدعى إحدى نقاط الدخول الثلاث فعلًا.

سجلّ الموافقات

السجلّ هو الجواب على المادة 7.1 من اللائحة العامة لحماية البيانات: القدرة على إثبات أن الشخص وافق. وهو مفعَّل افتراضيًا.

الجدول

{prefix}owc_ledger، وكل التواريخ بتوقيت UTC:

العمودالنوعالمحتوى
idbigintالمفتاح الأساسي
created_atdatetimeالطابع الزمني بتوقيت UTC
visitor_tokenchar(32)رمز مستعار للمتصفّح، 32 محرفًا ستّ عشريًا
eventvarchar(20)accept_all، reject_all، save_preferences، withdraw، auto، gpc_opt_out
categoriesvarchar(255)قائمة الفئات الممنوحة
profilevarchar(20)ملفّ الامتثال الساري وقت الإجراء
sourcevarchar(60)banner، preferences، footer_link، api، auto
ip_pseudonymousvarchar(45)عنوان IP مبتور
ua_hashchar(64)بصمة مملّحة لوكيل المستخدم
page_urlvarchar(500)الصفحة التي وقع فيها الإجراء
prev_hashvarchar(128)بصمة السطر السابق
row_hashvarchar(128)بصمة هذا السطر
policies_hashchar(64)بصمة الوثائق السارية
banner_revisionvarchar(40)بصمة اللافتة التي عُرضت فعلًا
plugin_versionvarchar(20)إصدار الإضافة وقت الكتابة

وتتيح الأعمدة الثلاثة الأخيرة إعادة بناء ما رآه الزائر، لا ما أشّر عليه فحسب.

السلسلة

كل سطر موقَّع بخوارزمية HMAC على تسلسل قياسي مسبوق بالطول لمحتواه ولبصمة السطر السابق. والنشأة (genesis) سلسلة من 64 صفرًا. وتجري الكتابة داخل معاملة، مع قفل سطر على المدخل الأخير: وهذا القفل هو ما يُسلسل الكتابات المتزامنة فعلًا ويمنع السلسلة من التشعّب. ويُؤخَذ قفل MySQL مُسمّى كخطّ دفاع ثانٍ، على قدر الإمكان: فإن رُفض، تابعت الإضافة، وأُطلق إجراء كي تتمكّنوا من تتبّع الأمر.

وتُبتَر القيم قبل التوقيع، حتى تكون القيمة الموقَّعة هي بالضبط القيمة المخزَّنة.

الصدق بشأن قابلية كشف التزوير

تحدّد الإضافة بنفسها مصدر مفتاح توقيعها:

المصدرالشرطالحُكم
constantOWC_LEDGER_KEY معرَّفغير قابل للتزوير
wp-configAUTH_KEY وAUTH_SALT معرَّفان وغير فارغين ومختلفان عن بعضهما وخاليان من العبارة الافتراضيةغير قابل للتزوير
databaseما عدا ذلكقابل للتزوير

وفي الحالة الثالثة، يخزّن ووردبريس الأملاح في قاعدة البيانات: فمن يصل إلى القاعدة يستطيع إعادة توقيع السلسلة. والإضافة تُبلغ بذلك في نتيجة التحقّق وتعرض إشعارًا إداريًا يقولها صراحةً. وتُحفَظ بصمة غير قابلة للعكس للمفتاح، ما يتيح التمييز بين تدوير الأملاح وإعادة الكتابة.

ولهذا السبب يوصي قسم التثبيت بتعريف OWC_LEDGER_KEY.

التحقّق

زرّ «Verify the chain now» في تبويب Audit ledger — أو المسار GET /owc/v1/ledger/verify — يمرّ على السلسلة كلها على دفعات من 500 سطر.

وثمة ثلاثة مخطّطات توقيع معروفة: المخطّط القياسي الحالي، ومخطّط تاريخي سابق، ومخطّط بلا مفتاح من أوائل الإصدارات. وهذا الأخير ينتج بصمة يستطيع أي شخص يملك قاعدة البيانات إعادة حسابها: ولذلك لا يُعدّ صحيحًا أبدًا، بل يُحتسب على حدة ويُبلَّغ عنه كانقطاع. فالبصمة بلا مفتاح ليست إثباتًا.

الانقطاعات المُبلَّغ عنها: hash_mismatch، وchain_break، وbad_genesis، وunkeyed_rows، وtable_emptied، وtail_truncated، وhead_mismatch، وcount_mismatch.

وتحمل النتيجة خصوصًا: ok، وtotal، وchecked، وtable_total، وbroken_at، وbreaks، وbreak_count، وpartial، وlegacy_rows، وunverifiable_rows، وanchor، وanchor_ok، وkey_source، وtamper_evident، وkey_rotated.

مرساة الرأس

تُحفَظ مرساة خارج الجدول: معرّف، وبصمة، وعدد أسطر، وطابع زمني. فبدونها، لن يترك حذفُ أحدث الأسطر أو تفريغُ الجدول أي أثر. ويُطلق إجراء عند كل تحريك للمرساة، والشيفرة تدعو صراحةً إلى استنساخها خارج قاعدة البيانات — ملفّ، أو syslog، أو نقطة نهاية خارجية — كي تصير إعادة التشغيل الشاملة قابلة للكشف.

وترفض الإضافة استبدال مرساة قائمة، وتُنبّه بصدق إلى أن مرساة مشتقّة من الجدول نفسه لا تجعل قابلًا للكشف سوى عمليات البتر اللاحقة.

مدة الحفظ

ledger_retention_days، والافتراضي 1825 يومًا (5 سنوات)، والحدود من 0 إلى 3650. والقيمة 0 تعني الحفظ بلا حدّ.

ويعمل التشذيب على cron يومي خاص به ولا يزيل سوى بادئة متّصلة: فلا ثقب في وسط السلسلة أبدًا. وتُحفَظ بصمة آخر سطر محذوف كي يبقى الباقي قابلًا للتحقّق. والسقف في كل تنفيذ: 20 000 سطر (40 دفعة من 500). ولذلك يُستوعَب تأخّر تشذيب كبير جدًّا على مدى أيام.

تقليل البيانات

  • عنوان IP: في IPv4 يُصفَّر البايت الأخير (ويُحفظ النطاق /24)، وفي IPv6 يُبتَر إلى /48 مع تصفير الـ 80 بت المتبقّية. ويجري الحجب على الصيغة الثنائية؛ وعنوان IPv6 يمثّل IPv4 يُعامَل معاملة IPv4.
  • وكيل المستخدم: لا تُخزَّن سوى بصمة مملّحة، ولا تُخزَّن السلسلة أبدًا.
  • page_url: يُتحقَّق منه أمام مضيفي الموقع. والمُستدعي هو المرجع — فإن وفّر القيمة، ولو فارغة، فهي الجواب؛ ولا يُستشار Referer إلا إذا لم يقل شيئًا على الإطلاق، ويُتحقَّق منه بالطريقة نفسها.
  • رمز الزائر: 32 محرفًا ستّ عشريًا من مولّد تشفيري، بلا أي صلة بهوية.

الخوارزمية

يقبل ledger_hash_algo القيمتين sha256 (الافتراضي) وsha3-256، مقاطَعتين مع الخوارزميات التي تدعمها PHP لديكم فعلًا. والإعداد معروض لكن غير قابل للتعديل في لوحة التحكّم: فتغيير الخوارزمية سيُفشل التحقّق من كل الأسطر القائمة. والأعمدة مقاسة أوسع، لكن الاختيار الفعلي محصور في هاتين الخوارزميتين.

تبويب Audit ledger

قائمة مرقَّمة بـ 25: المعرّف، والتاريخ المحلي والطابع الزمني الخام بتوقيت UTC، ورمز الزائر، والحدث، والفئات، والملفّ، وعنوان IP المستعار، وحلقة السلسلة (البصمة السابقة والبصمة الحالية، مبتورتين في العرض، وبقيمة كاملة في التلميح).

المرشّحات: رمز الزائر (32 محرفًا ستّ عشريًا)، والحدث، والملفّ، ومدى التواريخ — تُدخَل بتوقيت الموقع وتُقارَن بالطوابع الزمنية المخزَّنة فعلًا بتوقيت UTC.

والتصدير بصيغتَي CSV وJSON. ويحمل JSON غلافًا (الصيغة، والخوارزمية، ومصدر المفتاح) كي تستطيع جهةٌ ما إعادة التحقّق من المقتطف دون امتلاك بقية السلسلة. وكل خلايا CSV مُحيَّدة ضدّ حقن صيغ جداول البيانات.

الاطّلاع على السجلّ عبر الواجهة البرمجية

يقبل GET /owc/v1/ledger المعاملات page وper_page (من 1 إلى 200، الافتراضي 50) وvisitor_token وfrom وto. وتتيح الثلاثة الأخيرة الردّ على طلب اطّلاع (المادة 15) دون المرور على السلسلة كلها. وتُقرأ الحدود بتوقيت UTC، والتاريخ بصيغة YYYY-MM-DD يُوسَّع إلى اليوم كاملًا. وتُعاد المرشّحات المطبَّقة فعلًا داخل الاستجابة: فمرشّحٌ رفضته الفحوص لا يجوز أن يُقرأ على أنه «هذا هو السجلّ كله».

ماذا يحدث حين يرفض السجلّ الكتابة

هذا أهمّ سلوك في الإضافة كلها. إذا كان السجلّ مفعَّلًا وأخفقت كتابة السطر، أُلغي ملفّ تعريف ارتباط الموافقة وكانت الاستجابة 503. فلا شيء يُخزَّن، ولا أداة تتبّع تُطلَق.

والمنطق مباشر: موافقةٌ لا يمكن إثباتها لا ينبغي ادّعاؤها. انظروا استكشاف الأعطال لمعرفة ما يجب فعله.

نقاط التوسّع

add_action( 'owc_consent_updated',           function ( $categories, $event, $source ) {}, 10, 3 );
add_action( 'owc_consent_cookie_not_sent',   function ( $cookie, $event ) {}, 10, 2 );
add_action( 'owc_ledger_lock_failed',        function ( $event, $token ) {}, 10, 2 );
add_action( 'owc_ledger_write_failed',       function ( $error, $event, $token ) {}, 10, 3 );
add_action( 'owc_ledger_anchor',             function ( array $anchor ) {} );
add_action( 'owc_ledger_pruned',             function ( $deleted, $days ) {}, 10, 2 );

وowc_ledger_anchor هو الخطّاف الذي يُستعمل لاستنساخ المرساة خارج قاعدة البيانات.

حدود السجلّ

  1. قابلية كشف التزوير مشروطة، والإضافة تقول ذلك بنفسها.
  2. الأسطر السابقة للإصدار 1.2.0 تحمل بصمة بلا مفتاح: ولا يُعاد توقيعها أبدًا — فإعادة التوقيع ستتيح لمهاجم أن يُعيد توقيع تاريخ مزوَّر — وهي تمنع حكم «السلسلة سليمة» ما دامت باقية.
  3. مدة الحفظ محدودة بـ 20 000 سطر في كل تنفيذ يومي.
  4. السجلّ لا يُحذف بأداة محو البيانات الشخصية في ووردبريس: فهو سلسلة بصمات، وإزالته ستدمّر الإثبات الذي وُجد ليحمله، وهو لا يحوي سوى رمز مستعار وعنوان IP مبتور. ورسالةٌ تشرح هذا الاختيار للشخص المعني.

بوّابة الحقوق (DSAR)

تتيح البوّابة للشخص ممارسة حقوقه من صفحة في موقعكم. وهي مفعَّلة افتراضيًا، لكنها لا تظهر إلا حيث تضعون الرمز المختصر.

النموذج

[owc_dsar_form]

السمات:

السمةالافتراضيالدور
typesaccess,rectification,erasure,portability,restrict,object,optoutالأنواع المعروضة، مفصولة بفواصل
title«ممارسة حقوقي على بياناتي الشخصية»عنوان الكتلة
submit_label«إرسال طلبي»تسمية الزرّ

وإذا كان dsar_enabled معطَّلًا، عرض الرمزُ المختصر «البوّابة معطَّلة» وردّ مسار REST بالرمز 404: فالتعطيل من جهة الخادم فعلًا.

والقائمة التي تطلبونها تُقاطَع مع القائمة التي يقبلها الخادم: فخيارٌ ترفضه نقطة النهاية لا يُعرض على الزائر أبدًا.

أنواع الطلبات الثمانية

access، وrectification، وerasure، وportability، وrestrict، وobject، وoptout، وwithdraw.

وwithdraw مسحوب عن قصد ممّا يعرضه النموذج. فسحبُ الموافقة على ملفّات تعريف الارتباط فوريّ في لوحة التفضيلات؛ وإمرارُه عبر إجراء مكتوب مدّته 30 يومًا سيجعل السحب أصعب من الموافقة (المادة 7.3 من GDPR). ورابطٌ تحت النموذج يفتح لوحة التفضيلات مباشرةً لهذه الحالة.

والمرشّح owc_dsar_types هو مصدر الحقيقة الوحيد: ومنه تُشتقّ القائمة البيضاء لنقطة النهاية.

الدورة الكاملة

1. الإرسال. POST /owc/v1/dsar. وثلاث حمايات على الخادم، بهذا الترتيب:

  • فخّ للروبوتات: حقلٌ خفيّ مملوء يؤدّي إلى رفض 400 مع الرسالة العامة لإرسالٍ مُشوَّه — فلا يتعلّم الروبوت شيئًا عن سبب رفضه. ومن جهة المتصفّح، يعرض النموذج رسالة النجاح حتى دون إرسال شيء.
  • الإقرار (المادة 12.6): يجب تأشير خانة «أؤكّد أنني أمارس حقًّا على بياناتي الشخصية أنا»، ويُتحقَّق من ذلك على الخادم، لا في المتصفّح وحده. وتُسجَّل مع الطلب.
  • مهلة دنيا مدّتها 3 ثوانٍ بين عرض النموذج وإرساله، من جهة العميل.

حدود المعدّل: 3 في الساعة لكل عنوان IP، و3 في اليوم لكل عنوان بريد إلكتروني مستهدَف — فالعنوان يختاره المهاجم، ولذلك هو ما يجب تحديده — و30 في الساعة للموقع كله.

ويُدرَج السطر بالحالة pending، مع رمز من 64 محرفًا لا يُخزَّن منه سوى بصمة SHA-256، وتاريخ انتهاء صلاحية للرمز، وموعد نهائي للردّ. ولا يُعاد المعرّف: فلا تعداد، ولا تسريب لحجم الطلبات. وتساوي الاستجابة {ok, mail_sent, message}، وmail_sent يعكس الإخفاق الحقيقي في الإرسال.

ولا يُخطَر مسؤول حماية البيانات في هذه المرحلة. وإلا لأرسل مستدعٍ مجهول رسالتين عن كل إرسال من نطاقكم.

2. رسالة التحقّق. يشير الرابط إلى صفحتكم الرئيسية مع الرمز بصيغته الصريحة في المعامل. والصلاحية: dsar_token_ttl_days، الافتراضي 7 أيام، والحدود من 1 إلى 90. وتحمل الرسالة ترويسة Reply-To لكن لا From مُعاد كتابته أبدًا — فإعادة كتابة المُغلَّف هي ما يكسر SPF. وعنوان الردّ هو dsar_email، وإلا legal_dpo_email؛ ولا يكون أبدًا عنوان إدارة الموقع، الذي لا يجوز نشره.

3. تأكيد الهوية. يفتح الرابط صفحة لا تنفّذ شيئًا: فالتأكيد يتمّ عبر طلب POST محميّ برمز nonce. وهذا ما يمنع ماسحَ روابط البريد (Safe Links، وURL Defense، ومعاينة صندوق الوارد) من تأكيد هوية بدلًا من صاحبها.

والصفحة مستند HTML مستقلّ، يُقدَّم خارج القالب، مع noindex, nofollow وترويسات تمنع التخزين المؤقت. والمحاولات محدودة بـ 30 في الساعة لكل عنوان IP. والاستجابات متمايزة: 404 لرابط مجهول، و200 لرابط سبق تأكيده، و410 لرابط منتهي الصلاحية، و403 لرمز nonce منتهٍ، و500 لإخفاق في الكتابة، و200 للتأكيد.

4. ما الذي يطلقه التأكيد.

  • تنتقل الحالة إلى verified.
  • ويُعاد حساب الموعد النهائي انطلاقًا من التحقّق. المادة 12.3: المهلة تسري منذ اكتمال الطلب، لا منذ إرسالٍ لم يُؤكَّد قطّ.
  • ويُحرَق الرمز. وتُحفَظ بصمته عن قصد، كي يقرأ من يعيد فتح رابطه «مؤكَّد سلفًا» بدل خطأ 404 يطالبه بإعادة كل شيء. والاستعمال مرة واحدة مضمون بفحص الحالة.
  • وتُسجَّل: تاريخ التأكيد، وعنوان IP مبتورًا، ورمز المتصفّح المستعار — وهو الجسر الوحيد الممكن بين سجلّ الموافقات والطلب — ومعرّف طلب ووردبريس المرتبط.
  • ويُفتح طلب ووردبريس أصلي بهوية مُثبَتة سلفًا، أي مباشرةً في طابوركم عبر الأدوات ثم «تصدير / محو البيانات الشخصية». وهذا ما يجعل التنفيذ يغطّي كل إضافات الموقع، لا OW Consent وحدها. والمطابقة: access وportability تفتحان تصديرًا؛ وerasure تفتح حذفًا؛ أما بقية الأنواع فلا تفتح طلبًا أصليًا.
  • ويُخطَر المسؤول على dsar_email وdsar_notify_email، مع ارتداد إلى عنوان الإدارة إن لم يكن أيٌّ منهما صالحًا.

5. التنفيذ. لوحة أعلى تبويب DSAR requests تسرد آخر 20 طلبًا مُتحقَّقًا، مرتّبة حسب الموعد النهائي، مع عدد الأيام المتبقّية أو أيام التأخّر.

الإجراءالسلوك
تنزيل البيانات (JSON)رفض بالرمز 409 إذا لم تُؤكَّد الهوية قطّ. ويُسمّى الملفّ dsar-<id>-<YYYYMMDD>.json
محو البياناتيُعرض فقط لطلب من نوع erasure، وفقط بعد تأكيد الهوية. ويُغلَق الطلب قبل المحو، وإلا لبقي النصّ الحرّ للطلب الجاري حيًّا بعد تنفيذه هو نفسه
تمديد بشهرينتمديد المادة 12.3، مرة واحدة لا غير، مع سبب لا يتجاوز 500 محرف. ويتأخّر الموعد النهائي 60 يومًا، وتُعاد تسليح التذكيرات، ويتلقّى صاحب البيانات رسالة بالموعد الجديد والأسباب
الإغلاقالحالة resolved أو rejected، والملاحظة إلزامية. ويستحيل إعادة كتابة طلب مغلق سلفًا، ويستحيل تسجيل «مُلبّى» على هوية لم تُؤكَّد قطّ
إعادة إرسال الرابطيُصدر رمزًا جديدًا، ما يُبطل السابق

وخمس حالات: pending، وverified، وresolved، وrejected، وexpired.

ولا تُحمّل الشاشة أبدًا الرمزَ ولا بصمته، ولا تعرض اسم مقدّم الطلب.

6. مراقبة المهلة. على cron اليومي: يُمرّ على ما يصل إلى 200 طلب مُتحقَّق حسب الموعد النهائي، مع تذكير قبل سبعة أيام، وتذكير عند التجاوز، مرة واحدة لكلٍّ منهما. وشريطٌ إداري ينبّه إلى الطلبات المتجاوزة للمهلة وتلك التي بقي لها أقلّ من سبعة أيام.

7. التطهير. تُحذف الإرساليات التي لم تُتحقَّق قطّ بعد انتهاء صلاحية رمزها، وتُحذف الطلبات المغلقة بعد retention_dsar_days. والقياس يبدأ من الإغلاق، لا من الإرسال.

حزمة قابلية النقل

ينتج التصدير مستندًا بصيغة ow-consent/dsar-export، مع الطابع الزمني، والموقع، والشخص المعني، والطلب، ومجموعات البيانات. وهو يستدعي كل أدوات التصدير المسجَّلة في الموقع، ويرقّم حتى 50 صفحة لكل أداة، ويتوقّف عند 20 ثانية. والمحو يفعل الشيء نفسه مع أدوات المحو، بالحدود نفسها.

المرشّح: owc_dsar_export_bundle( $bundle, $email, $id ).

ولذلك يعتمد ما يغطّيه التصدير والمحو على الإضافات المثبَّتة في موقعكم: فالإضافة التي لا تسجّل أيًّا من هذه الخطّافات يجب التعامل معها يدويًا.

التكامل مع أدوات ووردبريس الأصلية

  • أداة تصدير مسجَّلة بالمفتاح ow-consent، بمجموعتين: طلبات الحقوق وسجلّ الموافقات.
  • أداة محو:
    1. الإرساليات التي لم تُؤكَّد قطّ تُحذف — فلا قيمة إثباتية لها، وليست سوى بيانات شخصية؛
    2. والطلبات المغلقة يُمحى نصّها الحرّ واسمها، ويُحتفظ بالسطر الأدنى (التاريخ، والنوع، والحالة) كإثبات (المادة 5.2) حتى retention_dsar_days؛
    3. والطلب الذي لا يزال مفتوحًا يُحفَظ، مع رسالة تشرح أنه يجب الردّ عليه قبل حذفه؛
    4. وسجلّ الموافقات لا يُحذف، للسبب المشروح أعلاه.
  • كما تغذّي الإضافة مسوّدة سياسة الخصوصية في ووردبريس.

إشعار المعلومات تحت النموذج

تحت النموذج، كتلة قابلة للطيّ تحمل إشعار المادة 13: هوية المسؤول وعنوانه، وجهة التواصل بشأن الخصوصية، والغرض والأساس القانوني (المادة 6.1.c)، والبيانات المجموعة، والمُستقبِلون ومدة الحفظ، ومهلة الردّ وإمكانية التمديد، وسلطة الرقابة المختصّة، والرابط إلى السياسة. المرشّح: owc_dsar_form_notice( $html, $context ).

والسلطة المعروضة تأتي من الاشتقاق الموصوف في ملفّات الامتثال الأحد عشر، ولا تُعتمد إلا إذا بدأت بحرف كبير: فقراءة الإعداد الخام ستسمّي السلطة الفرنسية على موقع في جنوب أفريقيا أو الهند أو أستراليا أو كاليفورنيا.

وبلا جافاسكربت، يُخفى زرّ الإرسال وتقترح رسالةٌ عنوانَ التواصل — كي لا يُجري المتصفّح أبدًا إرسالًا أصليًا يضع عنوان مقدّم الطلب في الرابط، ومن ثمّ في سجلّات كل الخوادم والوكلاء التي يمرّ بها.

إعدادات DSAR

الإعدادالافتراضيالحدود
dsar_enabledtrueقيمة منطقية
dsar_email''جهة تواصل عمومية ومُستقبِل الإشعارات
dsar_notify_email''مُستقبِل إضافي
dsar_response_days30من 1 إلى 30 — ولا يتجاوز شهرًا أبدًا
dsar_token_ttl_days7من 1 إلى 90
retention_dsar_days1095 (3 سنوات)من 1 إلى 3650

نقاط التوسّع

add_action( 'owc_dsar_submitted',   function ( $type, $email, $message ) {}, 10, 3 );
add_action( 'owc_dsar_verified',    function ( $id, array $row ) {}, 10, 2 );
add_action( 'owc_dsar_fulfilled',   function ( $id, $what, $trace ) {}, 10, 3 );
add_action( 'owc_dsar_mail_failed', function ( $id, $email, $kind ) {}, 10, 3 );

حدود البوّابة

  1. الهوية تقوم على عامل واحد: جولة البريد الإلكتروني. وأي إثبات إضافي بموجب المادة 12.6 يُدخَل يدويًا في ملاحظات الطلب.
  2. إخفاقُ إرسال البريد يوقف الدورة: فالاستجابة تُظهر mail_sent: false ويعرض النموذج رسالة تحيل إلى عنوان التواصل، لكن الطلب يبقى pending والمهلة القانونية لا تنطلق.
  3. تذكيرات المواعيد والتطهير تعتمد على WP-Cron.
  4. جدول الطلبات يُحذف دائمًا عند إلغاء تثبيت الإضافة، أيًّا كان إعدادكم. صدّروا قبل الحذف.

انسحاب CCPA «Do Not Sell or Share»

تحت الملفّات الأمريكية، يفرض القانون وجود عنصر تحكّم مُسمّى ومرئيّ ينفّذ الانسحاب فعلًا.

طريقتان لوضعه

رمز مختصر، حيث تشاؤون:

[owc_dnsmpi]
[owc_dnsmpi label="لا تبيعوا معلوماتي الشخصية ولا تشاركوها" class="mon-lien"]
السمةالافتراضي
label«Do Not Sell or Share My Personal Information»
classowc-dnsmpi

حقن تلقائي في التذييل: الإعداد ccpa_inject_footer، مفعَّل افتراضيًا، ويُعرض على wp_footer بالأولوية 20.

ما تفعله النقرة

النقرة تنفّذ الانسحاب. ولا تفتح لوحة. يجلب المُشغِّل رمز nonce طازجًا ثم يرسل reject_all بالمصدر footer_link وكل الفئات الاختيارية على false. وينتقل الرابط إلى aria-busy="true" وتعرض منطقة role="status" الحالة: «جارٍ التسجيل»، ثم «سُجّل انسحابكم على هذا المتصفّح»، أو رسالة الخطأ.

وتذكر الشيفرة السبب: فبموجب لوائح تطبيق CCPA (§7026(a)(1))، الرابطُ الذي يكتفي بفتح لوحة ليس آلية ممتثلة.

والارتداد بلا fetch ولا Promise (WebView قديمة، أو متصفّح مدمج): النقرة تفتح لوحة التفضيلات مع وضع الفئات الإعلانية على off سلفًا.

قيد التخزين المؤقت

شيفرة HTML المُقدَّمة واحدة للجميع. ولذلك يُعرض الرابط مرئيًّا إذا كان الملفّ المُهيَّأ للموقع هو ccpa أو us_generic؛ وإلا فيُعرض مخفيًّا ويُكشف من جهة العميل للزوّار الذين تفرضه ولايتهم القضائية، استنادًا إلى ملفّ تعريف ارتباط الكشف الإقليمي.

وإذا كان الكشف الإقليمي معطَّلًا وكان ملفّكم المُهيَّأ غير أمريكي، فإن الكتلة لا تُطبَع أصلًا: فلا شيفرة ميّتة.

ولا تسافر أي بيانات زائر داخل إعدادات جافاسكربت لهذه الوحدة — بل قوائم الملفّات فحسب، ولا القيمة المنطقية المحسوبة أبدًا.

وتُطبَع موارد هذه الوحدة داخل <head> لا في التذييل، كي يبلغ رفضُ Consent Mode gtag قبل أن ينطلق مدير الوسوم. والجافاسكربت بـ ES5 حصرًا.

الحدود

  1. التحكّم بنقرة واحدة يتطلّب fetch وPromise.
  2. الرابط إلزامي تحت الملفّين ccpa وus_generic فقط؛ وتحت أي ملفّ آخر لا يُعرض ولا يُكشف.
  3. الكشف من جهة العميل يعتمد على ملفّ تعريف ارتباط الكشف الإقليمي، ومن ثمّ على جافاسكربت.

Google Consent Mode v2

الوحدة مفعَّلة افتراضيًا (gcm_enabled).

الإشارات السبع

تُرسَل إشارات Consent Mode v2 السبع: ad_storage، وad_user_data، وad_personalization، وanalytics_storage، وfunctionality_storage، وpersonalization_storage، وsecurity_storage. وترتبط بها فئات الإضافة الستّ انطلاقًا من مصدر حقيقة واحد، ما يضمن ألّا تتباعد اللافتة والحجب والإقلاع. والجدول مذكور في فئات ملفّات تعريف الارتباط.

القيم الافتراضية، قبل أي موافقة

يُطبَع نداء default في شيفرة ثابتة، ويُحسب update داخل المتصفّح: وهذا ما يبقي الصفحة قابلة للتخزين المؤقت.

الإشارةنظام الموافقة المسبقةنظام الانسحاب
ad_storagedeniedgranted
analytics_storagedeniedgranted
ad_user_datadeniedgranted
ad_personalizationdeniedgranted
personalization_storagedeniedgranted
functionality_storagedenied إذا كان الموقع يعرض الفئة functional، وإلا grantedgranted
security_storagegranted دائمًاgranted

والمجموعتان تُطبعان في الصفحة نفسها. ويختار المُشغِّل أيّهما يطبّق استنادًا إلى ملفّ تعريف ارتباط الكشف الإقليمي. فبدون ذلك، ستثبّت صفحةٌ مخزَّنة مؤقتًا الولاية القضائية لزائر أمريكي على زائر أوروبي.

الإعدادان المرتبطان

الإعدادالافتراضيالأثر
gcm_ads_data_redactiontrueيحجب المعرّفات الإعلانية ما دام ad_storage مرفوضًا
gcm_url_passthroughtrueيمرّر gclid / dclid عبر الروابط ما دامت ملفّات تعريف الارتباط مرفوضة

لعلمكم

لا تُمَسّ security_storage أبدًا بأي تحديث: فهي تبقى ممنوحة، كما تنصّ المواصفة. وتعرض لوحة المعلومات بطاقة تبيّن ما إذا كان Consent Mode نشطًا.


IAB TCF v2.2

وحدة TCF معطَّلة افتراضيًا، وهي تتطلّب معرّفًا لا تستطيع الإضافة توفيره. اقرؤوا قسم الحدود قبل تفعيلها.

التفعيل

الإعدادالافتراضيالحدود
tcf_enabledfalseقيمة منطقية
tcf_cmp_id0من 0 إلى 4095
tcf_publisher_countryFRرمز ISO من حرفين
tcf_publisher_purposes_li[]قائمة أغراض
tcf_special_features[]قائمة ميزات خاصة

والسقف 4095 ليس اعتباطيًا: فحقل CmpId يشغل 12 بت داخل سلسلة TCF.

ثلاث حالات ترفض فيها الوحدة إصدار أي شيء

  1. لا CMP ID (tcf_cmp_id < 1): فلا __tcfapi، ولا سلسلة TC، ولا ملفّ تعريف ارتباط euconsent-v2، ولا مسار REST. ويشرح ذلك إشعارٌ إداري. ويجب أن تمنحكم IAB Europe رقم CMP ID؛ فالإضافة لا توفّره. وإصدارُ سلسلة تحمل CmpId بقيمة 0 سيكون أسوأ من عدم إصدار شيء.
  2. CMP ID أكبر من 4095: الرفض نفسه، مع إشعار مخصَّص. فقيمة مبتورة على 12 بت ستشير إلى منصّة CMP أخرى — أي انتحال هوية.
  3. لا قائمة مزوّدين عالمية في الذاكرة المؤقتة: يُطبَع الجذع لكن الواجهة تردّ cmpStatus: 'error' بسلسلة فارغة، بدل اختلاق رقم إصدار للقائمة.

ويُكتب تشخيص في خيار (disabled، وmissing_cmp_id، وno_gvl، وactive)، وفقط في سياق إداري أو سياق cron، ولا يُكتب أبدًا على صفحة عمومية.

قائمة المزوّدين العالمية

  • المصدر: https://vendor-list.consensu.org/v3/vendor-list.json.
  • لا تُنزَّل أبدًا أثناء عرض صفحة. بل يتولّى ذلك cron يومي، مع تنفيذ أول بعد خمس دقائق من التفعيل؛ وفي لوحة التحكّم مع ذاكرة مؤقتة باردة، يُدرَج جلب واحد في الطابور.
  • الطلب: مهلة قصوى 5 ثوانٍ، وإعادتا توجيه، واستجابة محدودة بـ 4 ميغابايت. والمتن الذي يبلغ السقف يُعدّ مبتورًا ويُرفض.
  • ولا يُحتفظ لكل مزوّد إلا بالحقول المفيدة؛ وتُفرَّغ الأكداس (stacks). وإذا بقي التسلسل ضخمًا، طُبِّقت مرحلتا بتر: التسميات والروابط أولًا، ثم الاختزال إلى الأغراض وحدها.
  • الحفظ: أسبوع في عابر، مع stale-if-error — فعند الإخفاق تُحفَظ آخر نسخة صالحة.
  • مسار عمومي: GET /owc/v1/tcf/gvl، محدود بـ 10 طلبات في الساعة. ويقدّم النسخة المخزَّنة مؤقتًا مع ETag وCache-Control: public, max-age=86400، ويتعامل مع الطلبات الشرطية. وإذا لم يكن ثمة شيء في الذاكرة المؤقتة، ردّ بالرمز 503 مع Retry-After: 300 — ولا يقدّم أبدًا قائمة مصطنعة. ولا يُطلق هذا المسار أي طلب خارجي أبدًا.

أين تُحسب سلسلة TC

داخل المتصفّح، لا في PHP. يُطبَع جذع ثابت بالكامل داخل <head> بالأولوية 0: إطار محدِّد الموقع، وتنفيذ window.__tcfapi، ومُرحِّل postMessage، ومُرمِّز لمقطع Core بالجافاسكربت. والإعدادات المنشورة لا تحوي أي بيانات زائر — وهذا ما يتيح البقاء متوافقًا مع تخزين مؤقت للصفحات. المرشّح: owc_tcf_stub_config.

وثمة نظير لهذا المُرمِّز مكتوب بـ PHP لكن لا مستدعي له داخل الإضافة: فهو مخصَّص لعمليات الدمج والاختبارات، مع تنبيه بعدم طباعته أبدًا في شيفرة قابلة للتخزين المؤقت.

ما يُرمَّز

مقطع Core فقط، بترميز base64url بلا حشو. ويُرمَّز قسم المزوّدين إما كحقل بتّات أو كمَدَيات: ويُقاس الحجمان وتفوز الأصغر. أما فهرس المزوّدين المُرسَل إلى المتصفّح فيستعمل صيغة مضغوطة خاصة، بسقف صلب يُفرَّغ الفهرس بعده (فتُفقَد عندئذٍ موافقات المزوّدين، ويُحفَظ إصدار القائمة).

مطابقة الفئات مع أغراض TCF

الفئةالأغراض
necessaryلا شيء — خارج نطاق TCF، ما يضمن ألّا يُنتج «رفض الكل» موافقةً على الغرض 1
functional1
analytics1، 8، 9، 10
marketing1، 2، 3، 4، 7
preferences1، 5، 6، 11
social1

المرشّح: owc_tcf_purpose_map.

والمصلحة المشروعة للناشر: لا تُعتمد سوى الأغراض 2 و7 و8 و9 و10 و11، لأن TCF v2.2 يمنع المصلحة المشروعة للأغراض 1 و3 و4 و5 و6. وأي قيمة أخرى في tcf_publisher_purposes_li تُستبعَد بصمت.

ويُعدّ المزوّد موافَقًا عليه ما إن يُمنح غرضٌ واحد على الأقلّ من الأغراض التي يعلنها على أساس «الموافقة».

الميزات الخاصة

مدخلان فقط مدعومان: 1 — استخدام بيانات تحديد موقع جغرافي دقيقة و2 — الفحص النشط لخصائص الجهاز. أعلنوا ما تستعملونه منهما في tcf_special_features؛ والقائمة تُختزل إلى هذا الكتالوج.

وتظهران كخانتَي تأشير حقيقيتين في لوحة التفضيلات. و«قبول الكل» لا يؤشّر عليهما: فهما تتطلّبان موافقة مسبقة صريحة خاصة بهما. أما «رفض الكل» و«Do Not Sell» فيلغيان تأشيرهما. وهما تعيشان داخل سلسلة TC نفسها، ويُعاد ترطيبهما عند إعادة فتح اللوحة انطلاقًا من واجهة TCF.

طبقة TCF في اللوحة

لا تُعرض إلا إذا كانت الوحدة نشطة، أي tcf_enabled ورقم CMP ID قابل للاستعمال. وفيها كتلتان:

  • الأغراض: تلك التي يمكن بلوغها عبر فئة غير إلزامية والمُسمّاة في كتالوج قائمة المزوّدين فقط. فمفتاحٌ يعود من تلقاء نفسه أسوأ من غياب المفتاح. وتبديلُ غرضٍ يكتب في كل الفئات التي تعلنه، ثم يُعاد اشتقاق العرض.
  • الميزات الخاصة المعلَنة.

ولا يُرمَّز في السلسلة شيء لم يُعرض.

واجهة جافاسكربت

window.__tcfapi( command, version, callback, parameter );
// الأوامر: ping, getTCData, getInAppTCData,
//          addEventListener, removeEventListener, getVendorList

window.__owcTcfUpdateState( tcData );        // يستبدل البيانات ويُخطر المستمعين
window.__owcTcfRefresh();                    // يعيد الحساب ويُصدر 'useractioncomplete'
window.__owcTcfUiShown(); window.__owcTcfUiHidden();
window.__owcTcfSetSpecialFeatures( [ 1, 2 ] );

الإصدارات المقبولة: غائب، أو null، أو 2، أو '2'، أو 2.2، أو '2.2'. وأي قيمة أخرى تعطي callback(null, false).

gdprApplies

يُقرَّر من جهة العميل. فإذا كان الكشف الإقليمي معطَّلًا، كانت القيمة true. وإلا قُورن بلد الزائر بقائمة الرموز الـ 31 التي تنطبق فيها GDPR بمعناها في TCF (27 دولة في الاتحاد الأوروبي، إضافةً إلى IS وLI وNO وGB وCH). والإخفاق نحو الإغلاق: فبلد مجهول يعطي true.

ملفّ تعريف الارتباط euconsent-v2

يُكتب من جهة العميل فقط، وفقط حين تكون الوحدة جاهزة ويكون الزائر قد تصرّف. وإلا فيُمحى. ومدّته هي مدة الموافقة، بسقف 13 شهرًا (توصية IAB / CNIL). وSameSite=Lax، وSecure على HTTPS.

حدود وحدة TCF — اقرؤوها حتمًا

  1. هذه ليست منصّة CMP مسجَّلة لدى IAB Europe. فهي تتطلّب رقم CMP ID خاصًّا بكم، وحتى معه، تفرض سياسة TCF على منصّة CMP مسجَّلة أن تعرض خيارات على مستوى الغرض وعلى مستوى المزوّد. وهنا تتبع مفاتيح الأغراض الفئاتِ ولا يوجد أي خيار على مستوى المزوّد: فللمزوّدين حقّ رفض هذه الإشارة. وشاشة لوحة التحكّم تقول ذلك وتتحدّث عن «وضع متوافق مع CMP (غير رسمي)»، تقبله معظم منصّات SSP في التطوير لكنها ترفضه في الإنتاج الفعلي داخل المنطقة الاقتصادية الأوروبية. فإن كان دخل الإعلانات عبر TCF يهمّكم، استعملوا منصّة CMP معتمدة.
  2. مقطع Core فقط: فلا مقطع disclosedVendors ولا allowedVendors ولا publisherTC.
  3. ولا تُصدَر أي قيود ناشر: فالعدّاد المقابل يساوي 0 دائمًا وكائن القيود فارغ.
  4. وpurposeOneTreatment وuseNonStandardTexts يساويان false دائمًا، وisServiceSpecific يساوي true دائمًا — فلا نطاق عالمي — وشاشة الموافقة تساوي 0 دائمًا.
  5. وgetVendorList يتجاهل معامل الإصدار ويعيد دائمًا القائمة المخزَّنة مؤقتًا.
  6. وموافقات الناشر تنسخ الأغراض العامة: فلا غرض مخصَّص.
  7. وميزتان خاصّتان فقط.
  8. وتتطلّب الوحدة cron يعمل واتصال HTTPS صادرًا. فبلا قائمة مخزَّنة مؤقتًا، تردّ الواجهة cmpStatus: 'error' ويعيد المسار العمومي الرمز 503.

Global Privacy Control

إشارة GPC يرسلها المتصفّح — الترويسة Sec-GPC: 1 والخاصية navigator.globalPrivacyControl. والإضافة تحترمها افتراضيًا (gpc_honor)، لكن معالجتها تتوقّف على النظام القانوني، وهذه هي النقطة المهمّة.

تحت الملفّات الأمريكية: مُلزِمة

تُعامَل الإشارة انسحابًا شاملًا مُلزِمًا تحت الملفّين ccpa وus_generic. وأستراليا مستثناة صراحةً: نظام انسحاب، لكنه لا يعترف بـ GPC.

ولا تحدث الكتابة على الخادم إلا بعد سلسلة كاملة من الفحوص، بهذا الترتيب:

  1. gpc_honor مفعَّل؛
  2. الإشارة موجودة — الترويسة Sec-GPC، مع ارتداد إلى X-Sec-GPC لأن بعض الوكلاء وشبكات التوصيل يعيدون تسمية الترويسة؛ ولا تُحتسب إلا القيمة 1 بالضبط؛
  3. الملفّ الفعلي هو ccpa أو us_genericوإلا فلا يُكتب شيء؛
  4. الطلب مجرّد استعراض لصفحة: لا لوحة تحكّم، ولا cron، ولا AJAX، ولا REST، ولا XML-RPC، ولا WP-CLI، والطريقة هي GET؛
  5. لم تُرسَل الترويسات بعد — فملفّ تعريف ارتباط لا يمكن وضعه هو قرار سيُعاد تسجيله عند كل طلب؛
  6. علامة الجلسة owc_gpc غائبة: مرة واحدة في كل جلسة تصفّح؛
  7. الزائر لا يشبه روبوتًا (وكيل مستخدم فارغ، أو يحوي bot أو crawl أو spider أو slurp أو monitor أو uptime أو pingdom أو headless أو preview أو curl/ أو wget أو python- أو java/ أو go-http أو okhttp أو httpclient أو libwww أو facebookexternalhit
  8. الاختيار المخزَّن سلفًا لا يلبّي الإشارة أصلًا — وإلا اكتُفي بوسم المتصفّح؛
  9. حدّ المعدّل المشترك محترَم: 30 في الساعة لكل عنوان IP؛
  10. يُوسَم المتصفّح قبل الكتابة، حتى لا يتحوّل الإخفاق إلى حلقة إعادة تشغيل.

ويُسجَّل الحدث بوصفه gpc_opt_out بالمصدر auto. ويُعاد بناء رابط الصفحة من رابط الموقع والمسار المطلوب — ولا يُبنى أبدًا من الترويسة Host، ولا أبدًا من Referer.

النطاق: كل الفئات الاختيارية تنتقل إلى false؛ وتبقى الفئات الإلزامية ممنوحة. وهذه قراءة واسعة لمفهوم البيع أو المشاركة.

الشفافية: إذا طمست GPC اختيارًا مسجَّلًا صراحةً، أطلق ملفُّ تعريف ارتباط مدّته خمس دقائق إشعارًا من جهة العميل في أسفل الشاشة يشرح ذلك، مع زرّ «إدارة تفضيلاتي» يفتح اللوحة، وزرّ إغلاق.

تحت ملفّات GDPR وما يماثلها: مجرّد قرينة

خارج أنظمة الانسحاب الأمريكية، تُعامَل الإشارة قرينةً، لا موافقةً أبدًا:

  • تُوضع السمة data-owc-gpc="1" على <html>؛
  • وينقل Consent Mode كلًّا من ad_storage وanalytics_storage وad_user_data وad_personalization وpersonalization_storage إلى denied؛
  • وتُضبط كل الفئات الاختيارية على false في الذاكرة فقط؛
  • ويبقى given خطأً، وتبقى اللافتة معروضة، ولا يُسجَّل شيء.

وثمة راية داخلية تمنع المُشغِّل من إخبار الزائر بأنه «منسحب سلفًا» بينما لا ملفّ تعريف الارتباط ولا السجلّ يقولان ذلك. والتبرير مكتوب في الشيفرة: فـ GPC ليست إشارة معترفًا بها قانونًا تحت GDPR وePrivacy، ولا قانون حماية البيانات السويسري الجديد، ولا LGPD، ولا POPIA، ولا PIPL، ولا DPDP، ولا القانون 25.

ملفّا تعريف الارتباط اللذان تضعهما هذه الوحدة

ملفّ تعريف الارتباطالمدةالدور
owc_gpcالجلسةيُعلِّم أن الإشارة عولجت سلفًا لهذا المتصفّح
owc_gpc_notice300 ثانيةيُطلق إشعار «حلّت GPC محلّ اختياركم»

وكلاهما على path=/ وSameSite=Lax وSecure على HTTPS، وقابلان للقراءة بالسكربت.

نقطة التوسّع

add_action( 'owc_gpc_honored', function ( array $categories ) {} );

الكشف الإقليمي

يطبّق الكشف الإقليمي على كل زائر ملفَّ ولايته القضائية بدل الملفّ المُهيَّأ للموقع. وهو معطَّل افتراضيًا.

الإعدادالافتراضي
geo_enabledfalse
geo_default_profilegdpr
geo_mmdb_enabledfalse

تسلسل الكشف

الأول نجاحًا يفوز:

  1. Cloudflare (CF-IPCountry) — فقط إذا كان الموقع قد أعلن أنه خلف Cloudflare؛
  2. AWS CloudFront (CloudFront-Viewer-Country) — الشرط نفسه؛
  3. GEOIP_COUNTRY_CODE، وهو المتغيّر الذي يكتبه الخادم نفسه (mod_geoip، وngx_http_geoip)، ومن ثمّ لا يمكن للعميل تزويره؛ ثم، إذا أُعلن وكيل، صيغه في ترويسات HTTP؛
  4. قاعدة MaxMind محلية، إذا كان geo_mmdb_enabled مفعَّلًا؛
  5. لا شيء.

وبلا إعلان صريح في wp-config.php، لا تُصدَّق أي ترويسة HTTP للبلد: فالعميل يستطيع تزويرها. انظروا التثبيت للاطّلاع على الثوابت.

ويُتحقَّق من رمز البلد أمام القائمة البيضاء ISO-3166-1 alpha-2 المخصَّصة رسميًا (نحو 249 رمزًا مُعدَّدة في الشيفرة). أما الرموز المخصَّصة للمستخدم أو المحجوزة — XX، وZZ، ورمز T1 لمخارج Tor — فتُرفض.

الإخفاق نحو الإغلاق

بلا بلد مكتشَف، تقرأ الإضافة geo_default_profile لكنها تُنزِّل كل ملفّ قائم على الانسحاب إلى gdpr. ولذلك يُتجاهَل geo_default_profile المضبوط على ccpa أو us_generic أو au بالنسبة إلى الزوّار غير المكتشَفين — ولا تعرض شاشة لوحة التحكّم في هذا المُحدِّد سوى ملفّات الموافقة المسبقة، بدل تقديم خيار يُتجاهَل بصمت.

والدافع مباشر: فبلا هذا الحاجز، سيضع موقعٌ مُهيَّأ بالإنجليزية الأمريكية كلَّ زائر من المنطقة الاقتصادية الأوروبية تحت نظام الانسحاب، مع أدوات تتبّع مُعلَنة «ممنوحة» بلا أي موافقة.

ولا ارتداد إلى لغة الموقع: فلغةُ موقعٍ لا تقول شيئًا عن مكان زائره.

ملفّ تعريف الارتباط owc_geo

  • مدّته 24 ساعة، وpath=/، وSameSite=Lax، وSecure على HTTPS، وقابل للقراءة بالسكربت — فالإقلاع في الواجهة الأمامية يحتاج إليه.
  • محتواه: البلد، والملفّ، وطابع زمني، ورمز مصادقة. ولا عنوان IP أبدًا.
  • وعند القراءة: الحجم محدود، والبلد يُتحقَّق منه أمام قائمة ISO، والطابع الزمني ضمن النافذة، والرمز يُتحقَّق منه في زمن ثابت. ويُعاد حساب الملفّ دائمًا على الخادم انطلاقًا من البلد: فلا يستطيع زائر اختيار نظامه القانوني.
  • ولا يُخزَّن مؤقتًا إلا كشفٌ حقيقي. أما ارتداد «الإخفاق نحو الإغلاق» فلا يُحفَظ أبدًا.
  • ولا يُكتب إلا على طلب في الواجهة الأمامية، وفقط إذا كان الكشف مفعَّلًا.

مطابقة البلد بالملفّ

البلدالملفّ
دول المنطقة الاقتصادية الأوروبية الثلاثونgdpr
GB، JE، GG، IMuk_pecr
CHch_nfadp
BRlgpd
ZApopia
CN، HKpipl
INdpdp
AU، NZau
CAquebec
USccpa
كل ما عدا ذلكالارتداد، مُنزَّلًا إلى موافقة مسبقة

وهونغ كونغ تخضع في الواقع لقانونها المحلي الخاص؛ لكنها تُعامَل معاملة PIPL أخذًا بالأشدّ. ونيوزيلندا تُعامَل معاملة أستراليا. وكندا كلها تتلقّى quebec — فالنظام الأشدّ هو الذي يفوز. والولايات المتحدة تتلقّى ccpa، الذي يقوم مقام الملفّ لبقية الولايات.

قيد التخزين المؤقت — ما لا يفعله الكشف

الملفّ المُحدَّد جغرافيًا لا يغيّر شيفرة HTML المعروضة. فإعادة كتابة الملفّ لا تنطبق إلا على مساري REST الخاصين بالزائر، /owc/v1/consent و/owc/v1/state. أما عرض الصفحات، والمسارات الإدارية، وwp-admin، وcron، وWP-CLI، فتحتفظ كلها بالملفّ المُهيَّأ. وأي استجابة استهلكت إعادة الكتابة تُوسَم بأنها غير قابلة للتخزين المؤقت.

والمُشغِّل في الواجهة الأمامية هو الذي يختار النظام، من جهة العميل، انطلاقًا من ملفّ تعريف الارتباط. والنتيجة المُعلنة: النظام المطبَّق على زائرٍ يتوقّف على جافاسكربت، والزائر الذي تأتي صفحته الأولى من الذاكرة المؤقتة يُعامَل تحت الملفّ المُهيَّأ للموقع ما دام ملفّ تعريف الارتباط غير موجود.

قارئ MaxMind المُضمَّن

تُضمِّن الإضافة قارئ MMDB خاصًّا بها، مكتوبًا بـ PHP خالصة، بلا أي اعتماد على Composer — فإضافة منشورة على WordPress.org لا يمكنها تضمين الحزمة الرسمية.

  • قراءة فقط، وبلد فقط. فلا مدينة، ولا ASN.
  • مدخلات/مخرجات محدودة: القراءة بكتل صغيرة، ولا تحميل لملفّ من عدّة ميغابايت في الذاكرة أبدًا.
  • ولا يرفع استثناءً أبدًا: فملفّ مفقود أو غير مقروء أو مبتور أو تالف أو عدائي يعطي null، ويرتدّ الكشف إلى ملفّه الأشدّ.
  • وحواجز داخلية على عمق المرور، وميزانية فكّ الترميز، وحجم الحمولة. وتُخزَّن البيانات الوصفية مؤقتًا في عابر يدمج مفتاحُه حجمَ الملفّ وتاريخه: فاستبدال تنزيلكم الشهري يُبطل الذاكرة المؤقتة من تلقاء نفسه.
  • وregistered_country وrepresented_country مُتجاهَلان عن قصد. فهذه هي الصيغة الموثَّقة لنطاقات الوكلاء المجهولة، وشبكات VPN، والأقمار الصناعية، حيث يشير بلد التسجيل إلى مكان تسجيل الكتلة لدى المزوّد، لا إلى الزائر. واستعمالهما سيضع زائرًا من المنطقة الاقتصادية الأوروبية خلف VPN أمريكي تحت نظام الانسحاب.
  • وإذا كانت إضافة أخرى تُحمّل قارئ GeoIP2 سلفًا، استُعمل كخيار احتياطي بعد القارئ المُضمَّن.

وأين يوضع الملفّ: wp-content/uploads/ow-geoip/GeoLite2-Country.mmdb. والمسار قابل للترشيح عبر owc_geo_mmdb_path، مع تحقّق من اجتياز المجلّدات.

حدّ مهمّ: الإضافة لا تنزّل القاعدة ولا تقدّم أي شاشة رفع. فعليكم الحصول على الملفّ من MaxMind، ووضعُه بأنفسكم، وتحديثه بأنفسكم. وفي المقابل، لا يُرسَل شيء إلى MaxMind: فالبحث محلي بالكامل، وعنوان IP يخدم نقطة البحث وحدها ويُتلَف بعدها صراحةً — فلا يُسجَّل أبدًا، ولا يُخزَّن أبدًا، ولا يُكتب أبدًا في ملفّ تعريف الارتباط.

حدود الكشف الإقليمي

  1. معطَّل افتراضيًا، ونسخة MaxMind منه تتطلّب ملفًّا توفّرونه أنتم.
  2. تُتجاهَل ترويسات البلد ما لم تُعلنوا وكيلكم.
  3. لا تفصيل ولايةً بولاية في الولايات المتحدة، ولا مقاطعةً بمقاطعة في كندا.
  4. نظام الزائر يتوقّف على جافاسكربت وعلى ملفّ تعريف الارتباط ذي الـ 24 ساعة.
  5. الملفّ us_generic لا يُسنَد تلقائيًا أبدًا.

التكامل مع OW Forms

النطاق بالضبط: يستهدف هذا التكامل الإضافة الشقيقة OW Forms، ولا شيء غيرها. فلا يوجد أي تكامل مع Contact Form 7 أو Gravity Forms أو WPForms.

الإعداد: forms_integration_enabled، مفعَّل افتراضيًا، لكن التكامل لا يفعل شيئًا إن لم تكن OW Forms نشطة.

ما الذي يضيفه

1. الربط بين الموافقة والإرسال. عند كل إرسال مخزَّن، يُكتب سطر في جدول خاص بـ OW Consent — ولا يُمَسّ مخطّط OW Forms أبدًا — يحوي:

  • رمز الزائر المستعار (32 محرفًا ستّ عشريًا، ولا عنوان البريد الإلكتروني أبدًا
  • معرّف أحدث مدخل في السجلّ لهذا الرمز؛
  • الفئات الممنوحة وملفّ الامتثال الساري؛
  • البصمة الكاملة للوثائق المنشورة في تلك اللحظة؛
  • الطابع الزمني للموافقة؛
  • حالة خانة GDPR في النموذج والتسمية الدقيقة التي كانت تحملها.

وهذه النقطة الأخيرة هي الأنفع عمليًا: إذ تستطيعون إثبات أن الخانة كانت مؤشَّرة، وإثبات ما كان مكتوبًا بجانبها كذلك.

2. تسلسل المحو. طلبُ محو مُتحقَّق منه يفوّض الحذف إلى روتين OW Forms — الذي يحذف أيضًا الملفّات المرفوعة — ثم يحذف أسطر الربط. ويكتشف التكامل ما إذا كانت OW Forms قد ربطت مستمعها الخاص بالإجراء نفسه، وعندها يكتفي بتشذيب روابطه.

3. أدوات الخصوصية في ووردبريس. تُسجَّل أداة تصدير وأداة محو، بحيث تغطّي الأدوات ثم «تصدير / محو البيانات الشخصية» إرساليات OW Forms — وبوّابة حقوق OW Consent أيضًا، لأنها تمرّ بالخطّافات نفسها. ويستعيد التصدير التسميات الحقيقية للحقول ويضيف حقول الموافقة. وكل قيمة مصدَّرة مُحيَّدة ضدّ حقن صيغ جداول البيانات ومبتورة.

4. مدة الحفظ. على cron اليومي، تُحذف الروابط الأقدم من retention_form_data_days (الافتراضي 1095 يومًا، والحدود من 1 إلى 3650) على دفعات من 500، مع مسح لليتيمة منها. ولا تُمَسّ سوى أسطر OW Consent: فمدةُ حفظ الإرساليات نفسها تخصّ OW Forms.

الحدود

  1. لا يُكتب أي حدث إرسال في السجلّ المُتسلسِل. فسطر الربط يشير إلى مدخل قائم ولا ينشئ مدخلًا — إذ لا يجوز الكتابة في السلسلة من الخارج.
  2. يستحيل ربط إرسال إذا كانت OW Forms مهيَّأة لعدم تخزين الإرساليات: فلا يوجد سطر يُعلَّق عليه.
  3. ولا استرجاع بأثر رجعي: فالربط يبدأ من أول إرسال بعد التحديث.
  4. ويجري التطابق على البصمة المملّحة للعنوان التي تحسبها OW Forms، مع ارتداد إلى العنوان الصريح الذي تحتفظ به OW Forms أيضًا. وهذا ليس مخطّطًا بإفشاء معدوم: فالعنوان يبقى صريحًا لدى OW Forms، لأنه لا بدّ من إمكانية الردّ على الشخص.
  5. ولا يعدّل التكامل أبدًا إضافة OW Forms ولا جداولها ولا خياراتها.
  6. وإذا كانت OW Forms نشطة لكنها أقدم من أن تعرض روتين المحو لديها، ردّت أداة المحو صراحةً بأن الإرساليات لم تُمَسّ.

الزرّ العائم

زرّ صغير دائم يتيح إعادة فتح لوحة التفضيلات في أي وقت. وهو مقتضى المادة 7(3) — إذ يجب أن يبقى السحب بالبساطة نفسها التي عليها الموافقة — ومقتضى قرار CNIL رقم 2020-091، الذي يطلب آلية يمكن بلوغها من كل صفحة.

شروط وجوده

يتطلّب الإعدادين معًا: floating_button_enabled وbanner_enabled. فلوحة التفضيلات وواجهة جافاسكربت تعيشان داخل مُشغِّل اللافتة؛ وبدونها سيكون الزرّ عنصر تحكّم لا يفعل شيئًا.

وينسحب كذلك في لوحة التحكّم، وعلى تغذية، وعلى robots.txt، وإذا لم يُطلَق wp_head.

الخيارات

الإعدادالقيمالافتراضي
floating_button_enabledقيمة منطقيةtrue
floating_button_positionbottom-left، bottom-right، top-left، top-rightbottom-left
floating_button_stylepill، iconpill
floating_button_labelنصّ حرّCookies

وليس للزرّ إعداد سمة خاص به: بل يأخذ banner_style، كي يتبع السطحان اللوحة اللونية نفسها.

السلوك وسهولة الوصول

هو <button> حقيقي، ومن ثمّ يمكن استعماله بلوحة المفاتيح. ويحمل aria-haspopup="dialog" وaria-label قابلًا للترجمة لكن غير قابل للضبط («Manage my cookie choices»): فالتسمية المرئية وحدها هي التي تُضبط. وفي الوضع icon، تُخفى التسمية بصريًا لكن تبقى مقروءة لقارئات الشاشة.

ويُعرض بالسمة hidden؛ وجافاسكربت هو الذي يقرّر إظهاره. وهو مرئيّ في كل الحالات عدا حين تكون اللافتة أو اللوحة معروضة سلفًا — بما في ذلك مباشرةً بعد اختيار على الصفحة الحالية.

والنقر عليه يفتح لوحة التفضيلات. وإن لم تكن واجهة اللافتة موجودة، ارتدّ الزرّ إلى الجزء #owc-preferences، مع إعادة إطلاق الحدث يدويًا إن كان هو الجزء الحالي سلفًا.

وz-index بقيمة 99990، ومخفيّ عند الطباعة، ودعم لوضع التباين القسري ولـ prefers-reduced-motion، وإزاحة أسفل شريط الإدارة في الموضع العلوي.


الرموز المختصرة

تعلن الإضافة رمزين مختصرين، لا ثالث لهما. ولا رمز للافتة ولا للزرّ العائم: فهما يظهران في كل مكان أو لا يظهران أبدًا، بقيادة إعداداتهما.

[owc_dsar_form] — بوّابة الحقوق

[owc_dsar_form]
[owc_dsar_form types="access,erasure,portability" title="حقوقي" submit_label="إرسال"]
السمةالافتراضي
typesaccess,rectification,erasure,portability,restrict,object,optout
title«ممارسة حقوقي على بياناتي الشخصية»
submit_label«إرسال طلبي»

وتُقاطَع الأنواع المطلوبة مع تلك التي يقبلها الخادم. والنوع withdraw لا يعرضه النموذج أبدًا؛ انظروا بوّابة الحقوق.

[owc_dnsmpi] — انسحاب CCPA

[owc_dnsmpi]
[owc_dnsmpi label="لا تبيعوا معلوماتي الشخصية ولا تشاركوها" class="lien-pied"]
السمةالافتراضي
label«Do Not Sell or Share My Personal Information»
classowc-dnsmpi

والنقرة تنفّذ الانسحاب؛ انظروا انسحاب CCPA. وإذا تركتم ccpa_inject_footer مفعَّلًا، كان الرابط محقونًا في التذييل سلفًا ولم يعد هذا الرمز المختصر مفيدًا إلا لوضعه في مكان آخر.

إعادة فتح اللوحة من قائمة أو رابط

لا رمز مختصر لذلك، لأن سمة فئة تكفي:

<a href="#owc-preferences" class="owc-open-preferences">إدارة ملفّات تعريف الارتباط</a>
<button type="button" data-owc-open>تفضيلاتي</button>
<a href="#owc-dnsmpi" data-owc-dnsmpi="1">لا تبيعوا معلوماتي</a>

وهذه هي الطريقة الموصى بها لإضافة مدخل «ملفّات تعريف الارتباط» إلى قائمة التذييل لديكم.


واجهة REST البرمجية

تعيش كل المسارات تحت النطاق owc/v1، على جذر REST المعتاد (https://exemple.com/wp-json/owc/v1/…). وثلاثة عشر مسارًا في المجموع: اثنا عشر تسجّلها وحدة REST، إضافةً إلى مسار قائمة المزوّدين الذي تسجّله وحدة TCF.

المسارات العمومية

بلا أي مصادقة. وأمنها يقوم على فحص الأصل، ورمز خاص بالإضافة، وحدود المعدّل الموصوفة أدناه.

الطريقةالمسارالمعاملاتالدور
GET/nonceaction (الافتراضي wp_rest)يعيد رمزًا طازجًا. الاستجابة: {nonce, action, header: "X-OWC-Nonce", ttl: 43200}، مع no-store وVary: Cookie
POST/consentevent (الافتراضي save_preferencessource (الافتراضي bannercategories (مطلوبpage_url (الافتراضي ''cookie_unreadable (منطقي، الافتراضي false)يسجّل اختيارًا، ويضع ملفّ تعريف الارتباط، ويكتب سطر السجلّ
GET/stateحالة المُستدعي وحده: {given, categories, profile, at}. ولا رمز الزائر أبدًا، ولا عنوان IP، ولا رابط الصفحة. no-store + Vary: Cookie
GET/tcf/gvlيقدّم قائمة المزوّدين العالمية المخزَّنة مؤقتًا. ETag، وCache-Control: public, max-age=86400، و304 على طلب شرطي، و503 + Retry-After: 300 إن لم يكن ثمة شيء مخزَّن
POST/dsartype (مطلوبemail (مطلوب، بصيغة بريد إلكتروني)، message (الافتراضي ''، بحدّ أقصى 2000 محرف)يودع طلب ممارسة حقوق. الاستجابة {ok, mail_sent, message}ولا المعرّف أبدًا

القيم المقبولة:

  • event: accept_all، وreject_all، وsave_preferences، وwithdraw، وauto، وgpc_opt_out
  • source: banner، وpreferences، وfooter_link، وapi، وauto
  • type (لـ DSAR): access، وrectification، وerasure، وportability، وrestrict، وobject، وoptout، وwithdraw
  • categories: كائن، بـ 32 مدخلًا كحدّ أقصى، وبقيم قياسية حصرًا
  • action (لـ nonce): wp_rest فقط

المسارات الإدارية

كلها تتطلّب صلاحية manage_options.

الطريقةالمسارالمعاملاتالدور
GET/ledgerpage (1 فأكثر، الافتراضي 1)، per_page (1–200، الافتراضي 50)، visitor_token (32 محرفًا ستّ عشريًا)، from، toيقرأ السجلّ. وتُعاد المرشّحات المطبَّقة فعلًا في الاستجابة
GET/ledger/verifyيتحقّق من السلسلة من طرف إلى طرف
GET/settingsالإعدادات الفعّالة
POST/settingsجسم JSON حرّيكتب الإعدادات. الاستجابة {ok, updated, rejected, settings}
POST/scanner/runيطلق مسحًا
POST/scanner/ingestجسم JSON بصيغة {page, findings[]}استقبال ملاحظات المِجَسّ
GET/scanner/findingspage، وper_page (1–200، الافتراضي 50)، وfilter (معرّف فئة أو unknown)يسرد النتائج
POST/policies/generatetype (مطلوبpublish (منطقي، الافتراضي false)يولّد وثيقة
GET/policies/previewtype (مطلوب)يعاين وثيقة

ويتطلّب /scanner/ingest إضافةً إلى ذلك رمز wp_rest صالحًا، في الترويسة X-WP-Nonce أو في المعامل _wpnonce — لأن sendBeacon لا يستطيع وضع ترويسة.

ولا يقبل /settings في الكتابة سوى المفاتيح المعلَنة إعداداتٍ حقيقية: فقد يحقن مرشّحٌ مفاتيح اصطناعية ليست كذلك. وتُنقّى كل قيمة على حدة. وغيابُ أي مفتاح معروف يعطي الرمز 400.

ويعيد /ledger اختبار الصلاحية داخل المعالج نفسه، دفاعًا في العمق ضدّ permission_callback جرى ترشيحه في مكان آخر.

نموذج الأمان للكتابات العمومية

الملاحظة الأولى بسيطة: لا يمكن لرمز nonce أن يعيش في شيفرة قابلة للتخزين المؤقت. ولذلك لـ /consent و/dsar تحكّمٌ متساهل في الوصول، محميّ بأربع طبقات بترتيب مهمّ.

  1. فحص الأصل على المضيف نفسه. مجّاني، وحتميّ، ولا يستهلك أي ميزانية.
  2. رمز خاص بالإضافة في الترويسة X-OWC-Nonce — وهو إثبات، لا حقّ نقض أبدًا. وخيارُ عدم استعمال X-WP-Nonce مقصود: فنواة ووردبريس تعترض هذه الترويسة قبل أي فحص وصول للمسار وترفض الطلب كاملًا إن لم تتحقّق منها. ولذلك سيقتل رمزٌ منتهي الصلاحية قدّمته ذاكرةٌ مؤقتة كتابةً كانت نقطة النهاية ستقبلها بلا أي رمز أصلًا.
  3. الإخفاق نحو الإغلاق: فلا أصل ولا رمز مُتحقَّق منه يعطي 403 owc_missing_origin.
  4. حدّ المعدّل في الأخير. فلو جاء أولًا، لاستهلك خطأٌ في التهيئة رمزين عن كل نقرة وانتهى الأمر بالرمز 429، ما يخفي خطأ التهيئة خلف حدّ معدّل.

المضيفون المقبولون: أولئك الذين يعلنهم ووردبريس (رابط الموقع، ورابط ووردبريس، وجذر REST) مع توأمهم www./الجذر، إضافةً إلى مضيف الترويسة Host في الطلب الحالي وتوأمه. فـ «الأصل نفسه» تعني «الأصل يطابق المضيف الذي اتصل به المتصفّح»، لا «يطابق ما لدى ووردبريس في قاعدة البيانات» — وإلا لرُفض بصمت كلُّ موقع يُبلَغ عبر نطاق معاينة، أو اسم بديل، أو اسم بيئة اختبار، أو نطاق مرتبط في وضع الشبكة، أو خلف وكيل يعيد كتابة Host، بلا أي إمكانية للإصلاح الذاتي. المرشّح: owc_allowed_request_hosts.

وتُترك CORS لنواة ووردبريس، عن قصد.

ويرفض /nonce صيغة JSONP صراحةً: فبدون هذا الرفض، تستطيع صفحة خارجية أن تحصد الرمز الحيّ لمدير عابر عبر <script src> بسيط، لا يخضع لفحص الأصل.

حدود المعدّل

السلّةالميزانيةالنافذةالمفتاح
nonce1205 دقائقعنوان IP
consent305 دقائقعنوان IP
dsar3ساعة واحدةعنوان IP
dsar_email324 ساعةعنوان البريد المستهدَف
dsar_global30ساعة واحدةالموقع كله
gpc30ساعة واحدةعنوان IP
tcf_gvl10ساعة واحدةعنوان IP
  • نافذة ثابتة، لا منزلقة: فالسلّة التي تتلقّى حركة تنتهي صلاحيتها دائمًا في النهاية.
  • والمفتاح المخزَّن بصمة مملّحة: فلا عنوان IP ولا عنوان بريد إلكتروني صريح يوجد في الخيارات أو في ذاكرة الكائنات.
  • تسوية عناوين IP: يُحفَظ IPv4 كاملًا، ويُبتَر IPv6 إلى /64 — فالعميل يتحكّم بكل بت من معرّف الواجهة، ولذلك سيتيح مفتاحٌ كامل إنشاء ميزانية جديدة عند كل طلب.
  • هوية مشتركة: خلف شبكة توصيل محتوى أو وكيل غير معلَن عبر OWC_TRUSTED_PROXY، يصل كل الزوّار بالعنوان نفسه. وعندئذٍ تُجزَّأ الميزانية لكل زائر، مع عدّاد موسَّع على العنوان المشترك. وهذا حدّ أخشن: فأعلنوا وكيلكم.
  • المرشّح owc_throttle_max( $max, $bucket, $window ) — وإعادة 0 تعطّل الحدّ.
  • والمحدِّد يُخفق نحو الانفتاح إذا كانت ذاكرة الكائنات غير متاحة: فعدم التحديد خير من منع شخص من ممارسة حقوقه.

المسار /consent بالتفصيل

  • تُقرأ headers_sent() في المقام الأول. فإذا كان الإخراج قد بدأ، تعذّر وضع ملفّ تعريف الارتباط من الخادم: ويُكتب السطر رغم ذلك وتبقى الاستجابة 200، مع cookie_set: false وواصف cookie (name، وvalue، وttl، وpath، وsamesite، وsecure) يضعه العميل بنفسه.
  • والفئات التي لا يعرضها الموقع تُعاد في dropped_categories، لا تُتجاهَل بصمت.
  • ويُتحقَّق من page_url أمام مضيفي الموقع، مع ارتداد إلى Referer مُتحقَّق منه بالطريقة نفسها، وإلا فالسلسلة الفارغة. والمفتاح موجود دائمًا، كي لا يذهب السجلّ للبحث عن Referer الخام.
  • وإذا كان السجلّ مفعَّلًا ورُفضت الكتابة، أُلغي ملفّ تعريف الارتباط وكانت الاستجابة 503 owc_ledger_write_refused. فلا شيء يُخزَّن، ولا أداة تتبّع تُطلَق.
  • وcookie_unreadable قياس عن بُعد خالص: فلا يُطبَّق عليه أي فحص تحقّق، تحديدًا كي لا يستطيع حقلُ تشخيص أن يرفض كتابة موافقة أبدًا. وأثره الوحيد ملاحظة في سجلّ الرفض.

الاستجابة النموذجية: {ok, state, dropped_categories, logged, cookie_set[, cookie]}. والحقل logged يساوي null حين يكون السجلّ معطَّلًا.

رموز الأخطاء

الرمزHTTPالمعنى
owc_bad_param400معامل غير صالح
owc_bad_categories400كائن categories مُشوَّه أو أكبر من اللازم أو غير قياسي
owc_bad_email400عنوان بريد إلكتروني غير صالح
owc_bad_dsar400إرسال DSAR مُشوَّه (بما في ذلك فخّ الروبوتات)
owc_dsar_not_attested400إقرار المادة 12.6 غائب
owc_no_settings400لا مفتاح إعدادات معروف في الجسم
owc_missing_origin403لا أصل ولا رمز: إخفاق نحو الإغلاق
owc_bad_origin403الأصل المُعلَن ليس مضيفًا لهذا الموقع — والاستجابة تسرد حتى عشرة مضيفين مقبولين
owc_bad_nonce403رمز nonce غير صالح على /scanner/ingest
owc_jsonp_forbidden403صيغة JSONP مرفوضة على /nonce
owc_forbidden401/403صلاحية غير كافية
owc_dsar_disabled404بوّابة الحقوق معطَّلة من جهة الخادم
owc_no_template404لا قالب لهذا النوع وهذا الملفّ
owc_rate_limited429بلوغ حدّ المعدّل
owc_consent_failed500إخفاق في تطبيق الموافقة
owc_dsar_store_failed500إخفاق في كتابة الطلب
owc_gen_failedمتغيّررفض توليد وثيقة (حقول ناقصة، أو حاجز اللغة)
owc_ledger_write_refused503رفض السجلّ الكتابة — فلا شيء يُسجَّل، ولا شيء يُطلَق

سجلّ الرفض

يُحتفظ بآخر عشرين رفض كتابة وتُعرض على لوحة المعلومات — فقط إذا لم يكن السجلّ فارغًا. ويُميَّز فيه بين طبيعتين:

  • المدخل الذي يحمل حالة HTTP رفضٌ حقيقي: فلا شيء خُزّن وقد رأى الزائر خطأً؛
  • والمدخل الذي حالته 0 تحذير: فالاختيار سُجّل فعلًا.

وتعرض اللوحة جنبًا إلى جنب المضيفَ الذي أعلنه الأصل وترويسةَ Host في الطلب. وهذا بالضبط ما يختلف حين يتصفّح زوّاركم على مضيف بينما ووردبريس مُهيَّأ بمضيف آخر — وهو السبب الأكثر شيوعًا لموافقة «لا تُسجَّل».

حدود الواجهة البرمجية

  1. يقبل /consent و/dsar كتابات مجهولة بحكم التصميم؛ والحماية هي الأصل مع حدّ المعدّل، لا رمز nonce.
  2. ومحدِّد المعدّل يُخفق نحو الانفتاح بلا ذاكرة كائنات.
  3. وملفّ تعريف ارتباط الموافقة مقصور على المضيف (host-only): فملفّ وُضع للنطاق الجذر لا يمكن قراءته من صفحة www.، ولا تستطيع أي ترويسة CORS إصلاح ذلك. والعلاج رابطُ كتابة من الأصل نفسه.
  4. ولا يقبل /scanner/ingest سوى manage_options: فالمِجَسّ لا يمكن أن يأتي من زائر.
  5. وليس لـ /settings رمز nonce خاص به: بل manage_options مع فحص nonce عبر ملفّ تعريف الارتباط في النواة.

مرجع الإعدادات

تتّسع كل الإعدادات لـ خيار واحد، owc_settings، يُحمَّل تلقائيًا لأنه يُقرأ في كل صفحة من الواجهة الأمامية.

القراءة والكتابة في PHP

$settings = OWC_Core::settings();               // الإعدادات الفعّالة (الافتراضية + المحفوظة + المرشّحات)
$profile  = OWC_Core::setting( 'compliance_profile' );
$raw      = OWC_Core::stored_setting( 'compliance_profile' ); // يتجاهل إعادة الكتابة حسب الزائر

OWC_Core::update_settings( array(
    'consent_renewal_months' => 6,
    'compliance_strict'      => true,
) );

ولا تدمج update_settings() سوى المفاتيح المُرسَلة فوق الموجود، لا مجموعة القيم الافتراضية كلها أبدًا. وهذا ما يتيح لسطر الخيار أن يبقى فارغًا ما دمتم لم تخصّصوا شيئًا، ومن ثمّ يتيح للنصوص أن تتبع لغة الموقع.

ونتيجة settings() محفوظة في الذاكرة (memoized)، بمفتاح مبنيّ على مجموعة نداءات المرشّح owc_settings: فالوحدة التي تسجّل مرشّحها بعد القراءة الأولى تُبطل الحفظ بدل أن تُتجاهَل. ويُفرَّغ الحفظ عند كل كتابة للخيار.

القيم الافتراضية

[
    // اللافتة
    'banner_enabled'            => true,
    'banner_position'           => 'bottom-bar',   // bottom-bar | bottom-card | center-modal | top-bar
    'banner_style'              => 'auto',         // auto | light | dark
    'banner_accept_all'         => true,
    'banner_reject_all'         => true,
    'banner_preferences'        => true,
    'banner_close_x'            => false,          // علامة الإغلاق = رفض ضمني
    'banner_show_logo'          => true,
    'text_title'                => 'We use cookies',
    'text_message'              => 'We use cookies to personalise content, measure audience, '
                                 . 'and provide social media features. You can accept or reject, '
                                 . 'and change your choice at any time.',
    'text_accept_all'           => 'Accept all',
    'text_reject_all'           => 'Reject all',
    'text_preferences'          => 'Customize',
    'text_save'                 => 'Save my choices',

    // الزرّ العائم
    'floating_button_enabled'   => true,
    'floating_button_position'  => 'bottom-left',
    'floating_button_style'     => 'pill',
    'floating_button_label'     => 'Cookies',

    // الموافقة
    'consent_renewal_months'    => 12,             // القيمة 0 تُحوَّل إلى 13، لا إلى «أبدًا»
    'consent_policy_hash_check' => true,

    // الامتثال
    'compliance_profile'        => 'gdpr',
    'compliance_strict'         => true,
    'geo_enabled'               => false,
    'geo_default_profile'       => 'gdpr',
    'geo_mmdb_enabled'          => false,

    // IAB TCF v2.2
    'tcf_enabled'               => false,
    'tcf_cmp_id'                => 0,
    'tcf_publisher_country'     => 'FR',
    'tcf_publisher_purposes_li' => [],
    'tcf_special_features'      => [],

    // CCPA / GPC
    'ccpa_inject_footer'        => true,
    'gpc_honor'                 => true,

    // Google Consent Mode v2
    'gcm_enabled'               => true,
    'gcm_ads_data_redaction'    => true,
    'gcm_url_passthrough'       => true,

    // الفئات
    'cat_necessary_available'   => true,
    'cat_functional_available'  => true,
    'cat_analytics_available'   => true,
    'cat_marketing_available'   => true,
    'cat_preferences_available' => true,
    'cat_social_available'      => true,
    'cat_necessary_label'       => 'Necessary',
    'cat_necessary_desc'        => 'Strictly required for the site to function …',
    'cat_functional_label'      => 'Functional',
    'cat_functional_desc'       => 'Enhance the experience (chat, embedded videos, maps) …',
    'cat_analytics_label'       => 'Statistics',
    'cat_analytics_desc'        => 'Help us understand how you use the site (anonymously) …',
    'cat_marketing_label'       => 'Marketing',
    'cat_marketing_desc'        => 'Enable us to show you ads and content tailored …',
    'cat_preferences_label'     => 'Preferences',
    'cat_preferences_desc'      => 'Remember your interface choices (layout, saved filters).',
    'cat_social_label'          => 'Social & embeds',
    'cat_social_desc'           => 'Allow embedded social content (YouTube, Instagram, X) to load.',

    // السجلّ
    'ledger_enabled'            => true,
    'ledger_retention_days'     => 1825,           // 5 سنوات ؛ 0 = بلا حدّ
    'ledger_hash_algo'          => 'sha256',

    // الماسح
    'scanner_enabled'           => false,
    'scanner_frequency'         => 'weekly',
    'scanner_alert_email'       => '',
    'scanner_max_urls'          => 25,
    'scanner_timeout'           => 8,
    'scanner_probe_mode'        => 'admins',

    // بوّابة الحقوق
    'dsar_enabled'              => true,
    'dsar_email'                => '',
    'dsar_response_days'        => 30,
    'dsar_notify_email'         => '',
    'dsar_token_ttl_days'       => 7,

    // الحجب
    'blocker_unknown_script_policy' => 'allow',
    'blocker_unknown_iframe_policy' => 'block',
    'blocker_allowlist'             => '',         // مضيف واحد في كل سطر
    'blocker_block_resource_hints'  => true,

    // التكامل ودورة الحياة
    'forms_integration_enabled' => true,
    'auto_footer_menu_inject'   => false,
    'delete_data_on_uninstall'  => false,

    // الهوية القانونية
    'legal_company_name'         => '',
    'legal_company_legal_form'   => '',
    'legal_company_capital'      => '',
    'legal_company_address'      => '',
    'legal_company_email'        => '',
    'legal_company_phone'        => '',
    'legal_country'              => 'FR',
    'legal_company_reg_number'   => '',
    'legal_company_reg_place'    => '',
    'legal_company_vat'          => '',
    'legal_publication_director' => '',
    'legal_eu_representative'    => '',
    'legal_host_name'            => '',
    'legal_host_address'         => '',
    'legal_host_phone'           => '',
    'legal_host_url'             => '',
    'legal_profession_body'      => '',
    'legal_profession_title'     => '',
    'legal_profession_state'     => '',
    'legal_profession_rules'     => '',
    'legal_mediator_name'        => '',
    'legal_mediator_address'     => '',
    'legal_mediator_url'         => '',
    'legal_dpo_name'             => '',
    'legal_dpo_email'            => '',
    'legal_dpa_authority'        => '',            // فارغ عن قصد: يُشتقّ من البلد + الملفّ
    'legal_transfer_countries'   => '',
    'legal_third_parties_note'   => '',
    'legal_automated_decisions'  => false,
    'legal_automated_decisions_desc' => '',
    'legal_minor_age'            => 15,
    'legal_data_provision_note'  => '',
    'legal_currency'             => 'EUR',
    'legal_tax_label'            => 'TTC',
    'legal_business_type'        => 'auto',
    'retention_form_data_days'   => 1095,
    'retention_dsar_days'        => 1095,
    'policy_disclaimer'          => true,

    // الروابط
    'link_privacy_policy'        => '',
    'link_cookie_policy'         => '',
    'link_terms'                 => '',
    'link_legal_notice'          => '',
]

القوائم المغلقة

أي قيمة خارج القائمة تُردّ إلى القيمة الافتراضية.

الإعدادالقيم المقبولة
banner_positionbottom-bar، bottom-card، center-modal، top-bar
banner_styleauto، light، dark
floating_button_positionbottom-left، bottom-right، top-left، top-right
floating_button_styleicon، pill
compliance_profile، geo_default_profilegdpr، ccpa، lgpd، popia، pipl، dpdp، quebec، uk_pecr، ch_nfadp، au، us_generic
ledger_hash_algosha256، sha3-256 (مقاطَعتان مع ما تدعمه PHP)
scanner_frequencyhourly، twicedaily، daily، weekly
scanner_probe_modeadmins، off
legal_business_typeauto، vitrine، rental، ecommerce، services، saas، content
blocker_unknown_script_policy، blocker_unknown_iframe_policyallow، block

حدود الأعداد الصحيحة

الإعدادالحدود
consent_renewal_monthsمن 0 إلى 13 (والقيمة 0 تُعامَل معاملة 13)
dsar_response_daysمن 1 إلى 30
dsar_token_ttl_daysمن 1 إلى 90
ledger_retention_daysمن 0 إلى 3650 (و0 = بلا حدّ)
scanner_max_urlsمن 1 إلى 500
scanner_timeoutمن 1 إلى 60
legal_minor_ageمن 13 إلى 18
retention_form_data_daysمن 1 إلى 3650
retention_dsar_daysمن 1 إلى 3650
tcf_cmp_idمن 0 إلى 4095

التنقية

  • text_message هو الحقل الوحيد ذو HTML الغنيّ؛ وهو يقبل شيفرة HTML المسموحة في مقال ووردبريس، ولا تعرض اللافتة في النهاية سوى <a href target rel>.
  • الحقول متعدّدة الأسطر: legal_company_address، وlegal_eu_representative، وlegal_host_address، وlegal_mediator_address، وlegal_third_parties_note، وlegal_automated_decisions_desc، وlegal_data_provision_note، وblocker_allowlist، وكل مفتاح ينتهي بـ _desc.
  • الروابط: كل مفتاح يبدأ بـ link_ أو ينتهي بـ _url، إضافةً إلى legal_profession_rules.
  • عناوين البريد الإلكتروني: كل مفتاح يحوي email.
  • وكل ما عدا ذلك: نصّ بسيط.
  • والقيمة غير القياسية المُرسَلة على إعداد قياسي تُتجاهَل، ولا يُكتب المفتاح.

أين يُضبط ماذا

التبويبالإعدادات
Bannerbanner_*، text_*، floating_button_*، consent_renewal_months، consent_policy_hash_check
Compliancecompliance_profile، compliance_strict، gcm_*، blocker_*، ccpa_inject_footer، gpc_honor، tcf_*، geo_*، auto_footer_menu_inject، forms_integration_enabled، delete_data_on_uninstall، link_*
Legal identitylegal_*، retention_form_data_days، retention_dsar_days، policy_disclaimer
Categoriescat_*_available، cat_*_label، cat_*_desc
Audit ledgerledger_enabled، ledger_retention_days (والخوارزمية معروضة لا قابلة للتعديل)
Scannerscanner_*
DSAR requestsdsar_*

الجداول

الجدولالمحتوى
{prefix}owc_ledgerسجلّ الموافقات المُتسلسِل
{prefix}owc_dsarطلبات ممارسة الحقوق
{prefix}owc_scannerنتائج الماسح
{prefix}owc_scriptsكتالوج بصمات الحجب
{prefix}owc_form_linksالروابط بين الموافقة وإرساليات OW Forms

وثمة دالة مساعدة في PHP، owc_table( 'ledger' | 'dsar' | 'scanner' | 'scripts' )، تعيد حساب الاسم انطلاقًا من السابقة الحالية: استعملوها داخل switch_to_blog()، فالثوابت مجمّدة طوال مدة الطلب.

خيارات وعوابر أخرى

الخيارات: owc_settings، وowc_version، وowc_pending_upgrade، وowc_upgrade_lock، وowc_ledger_head، وowc_ledger_trim، وowc_ledger_key_source، وowc_scanner_secret، وowc_scanner_lock، وowc_scanner_queue، وowc_scanner_status، وowc_scanner_alerted، وowc_scanner_probe_status، وowc_scanner_manual، وowc_refusal_log، وowc_tcf_status، وowc_tcf_gvl_version، وowc_forms_db_version، إضافةً إلى رايات الترحيل (owc_catalog_sanitized_v2، وowc_match_target_migrated_v1، وowc_ledger_hmac_migrated_v1، وowc_inline_sig_labels_cleaned_v1، وowc_scanner_secret_rotated_v1).

العوابر: owc_catalog_<version>، وowc_invalid_patterns، وowc_gvl_cache، وowc_gvl_stub، وowc_gvl_etag، وowc_gvl_retry، وowc_mmdb_<empreinte>، وowc_policies_hash، وowc_site_analysis، وowc_scanner_last_run، وowc_scanner_run_result، وowc_scanner_pruned، وowc_scanner_fail_alerted، وowc_ledger_verify_result، وowc_ledger_write_error، وowc_policy_gen_result، وowc_dsar_sla_alert، وowc_dsar_admin_result، وعدّادات تحديد المعدّل.

الثوابت المعروفة في wp-config.php

الثابتالأثر
OWC_LEDGER_KEYمفتاح HMAC للسجلّ، والمفتاح المشتقّ لملفّ تعريف ارتباط الكشف الإقليمي
OWC_TRUSTED_PROXY / OWC_TRUSTED_PROXIESنطاقات CIDR للوكلاء الموثوقين؛ وبدونها تُتجاهَل ترويسات عنوان IP للعميل
OWC_GEO_TRUSTED_HEADERScloudflare، أو cloudfront، أو proxy، أو all
OWC_BEHIND_CLOUDFLAREاختصار لترويسة البلد الخاصة بـ Cloudflare
OWC_BEHIND_CLOUDFRONTاختصار لترويسة البلد الخاصة بـ CloudFront

خطّافات المطوّرين

المرشّحات

المرشّحالدور
owc_settingsالإعدادات الفعّالة. ويجب أن تتوقّف الاستجابة على شيء ثابت طوال الطلب
owc_banner_textsنصوص اللافتة
owc_bootstrap_configالإعدادات الثابتة المطبوعة في <head>ولا بيانات خاصة بزائر أبدًا
owc_scripts_catalogأسطر الكتالوج قبل التحقّق منها
owc_blocker_allowlistمضيفون لا يُحجبون أبدًا
owc_scanner_urlsالروابط المراد مسحها (تُقيَّد بعدها بمضيف الموقع)
owc_throttle_maxميزانية حدّ معدّل؛ و0 تعطّله
owc_allowed_request_hostsالمضيفون المقبولون لكتابة عمومية
owc_allow_headerless_writeيرفع الإخفاق نحو الإغلاق عن الكتابات بلا أصل (الافتراضي false)
owc_geo_mmdb_pathمسار قاعدة MaxMind
owc_tcf_purpose_mapمطابقة الفئات مع أغراض TCF
owc_tcf_stub_configالإعدادات الثابتة لجذع TCF
owc_policy_templateالمتن الخام لقالب — يعطّل قفل اللغة
owc_policy_varsمتغيّرات وثيقة
owc_policy_htmlشيفرة HTML النهائية لوثيقة
owc_dsar_typesأنواع الطلبات المعروضة والمقبولة
owc_dsar_form_noticeإشعار المعلومات تحت النموذج
owc_dsar_export_bundleمحتوى حزمة قابلية النقل
owc_dsar_show_fulfilment_panelعرض لوحة التنفيذ

الإجراءات

الإجراءالتوقيع
owc_consent_updated( array $categories, string $event, string $source )
owc_consent_cookie_not_sent( array $cookie, string $event )
owc_ledger_lock_failed( string $event, string $token )
owc_ledger_write_failed( $error, string $event, string $token )
owc_ledger_anchor( array $anchor )
owc_ledger_pruned( int $deleted, int $days )
owc_catalog_updated
owc_gpc_honored( array $categories )
owc_tcf_inactive( string $reason )
owc_dsar_submitted( string $type, string $email, string $message )
owc_dsar_verified( int $id, array $row )
owc_dsar_fulfilled( int $id, string $what, $trace )
owc_dsar_mail_failed( int $id, string $email, string $kind )

مهامّ cron: owc_daily_maintenance، وowc_ledger_retention، وowc_scanner_run، وowc_scanner_run_batch، وowc_tcf_refresh_gvl، وowc_run_upgrade.

التدويل

نطاق الترجمة هو ow-consent، والمسار /languages. واللغة المصدر هي الإنجليزية. وتُسلَّم الحزمة مع القالب ow-consent.pot وترجمة فرنسية كاملة.

وتذكيرًا بالآلية الموصوفة أعلاه: ما دامت تسميةٌ أو نصّ لافتة غير مخصَّص في الإعدادات، فهو يتبع لغة الموقع. وما إن تُدخلوا قيمتكم الخاصة، تُقدَّم كما هي، أيًّا كانت لغة الزائر.

أما متون الوثائق القانونية فلا تمرّ بهذه الآلية: فلغتها تتبع الولاية القضائية، لا لغة المدير أبدًا.


استكشاف الأعطال

اللافتة لا تظهر

راجعوا القائمة بالترتيب:

  1. هل banner_enabled مفعَّل؟ الشارة أعلى شاشة لوحة التحكّم تقول ذلك.
  2. هل يستدعي قالبكم wp_head() وwp_footer()؟ فبدونهما ترفض اللافتة أن تُطبع بدل أن تنتج شيفرة خاملة.
  3. هل سبق للزائر أن اختار؟ لا تظهر اللافتة إلا على <html data-owc="none">. اختبروا في تصفّح خاص أو بـ window.OWCBanner.reset().
  4. هل لدى الزائر جافاسكربت؟ فبدونه تبقى اللافتة مخفيّة — عن قصد — وتتولّى كتلة <noscript> الأمر.
  5. هل يقدّم تخزينٌ مؤقت للصفحات نسخةً سابقة للتفعيل؟ فرّغوه.

اللافتة تعود في كل صفحة رغم تسجيل الاختيار

ثلاثة أسباب، بترتيب الشيوع.

  1. المضيف المتصفَّح يختلف عن المضيف المُهيَّأ في ووردبريس (نطاق www. مقابل النطاق الجذر، أو اسم بديل، أو نطاق بيئة اختبار). وعندئذٍ يرفض المتصفّح تخزين ملفّ تعريف الارتباط بينما يردّ ووردبريس بالرمز 200. افتحوا لوحة المعلومات: يعرض سجلّ الرفض جنبًا إلى جنب الأصلَ وترويسةَ Host. والعلاج تقديمُ الموقع على مضيف قياسي واحد.
  2. consent_policy_hash_check مفعَّل ووثائقكم تغيّرت — وهذا هو السلوك المقصود، إذ يُسأل الزائر من جديد بعد تعديل سياسة.
  3. أنتم على إصدار سابق لـ 1.4.3. فملفّ تعريف الارتباط كان يومها مُرمَّزًا مرتين ولم يكن المتصفّح يستطيع إعادة قراءته، بينما كان الخادم يقرؤه جيدًا. حدّثوا: فملفّات تعريف الارتباط المكتوبة قبل التصحيح تبقى قابلة للقراءة.

«تعذّر تسجيل اختياركم» — خطأ refused أو 403

انظروا إلى data-owc-code على عنصر الرسالة، أو إلى سجلّ الرفض في لوحة المعلومات.

  • owc_bad_origin: الأصل المُعلَن ليس مضيفًا معروفًا. والاستجابة تسرد المضيفين المقبولين. وإذا كان موقعكم يُبلَغ بأسماء متعدّدة بوجه مشروع، فأضيفوها بالمرشّح owc_allowed_request_hosts.
  • owc_missing_origin: لا أصل ولا رمز. وهذا عادةً إضافةُ خصوصية تحذف الترويسات، أو وكيلٌ يعيد كتابتها.
  • owc_bad_nonce: لا يخصّ سوى مِجَسّ الماسح، لا كتابة الموافقة — فرمز nonce ليس حقّ نقض أبدًا على /consent.

خطأ ratelimit — 429

الحدود منخفضة عن قصد على الكتابات العمومية. وثمة سببان:

  1. شبكة توصيل محتوى أو وكيل غير معلَن: فيصل كل زوّاركم بالعنوان نفسه ويتقاسمون الميزانية نفسها. أعلنوه بـ OWC_TRUSTED_PROXY في wp-config.php.
  2. اختبار آليّ يرسل أكثر من 30 كتابة في 5 دقائق من العنوان نفسه.

الخطأ 503 مع الرمز owc_ledger_write_refused

رفض السجلّ الكتابة، ومن ثمّ لم يُسجَّل شيء ولم تُطلَق أي أداة تتبّع. وهذا هو السلوك المقصود: فموافقةٌ لا يمكن إثباتها لا ينبغي ادّعاؤها.

  1. تحقّقوا من وجود الجدول {prefix}owc_ledger. ويعرض تبويب Audit ledger رسالة مقروءة «لم يُثبَّت بعد» بدل شاشة بيضاء.
  2. تحقّقوا من صلاحيات الكتابة لمستخدم MySQL.
  3. وكملاذ أخير، عطّلوا ledger_enabled مؤقتًا لاستعادة الخدمة — مع علمكم أنكم تفقدون الإثبات في تلك المدة.

أدوات تتبّع لا تزال تُحمَّل قبل الموافقة

  1. هل compliance_strict مفعَّل؟ فبدونه لا تُعالَج سوى السكربتات التي أدرجها ووردبريس.
  2. هل أداة التتبّع في الكتالوج؟ فالسكربت الخارجي المجهول مسموح افتراضيًا. شغّلوا مسحًا، وصنّفوا النتيجة: فذلك يكتب قاعدة الحجب.
  3. هل يحقنها جافاسكربت داخلي؟ فالحارس الديناميكي لا يغطّي سوى عشرين مضيفًا. أضيفوا قاعدة كتالوج على نطاق أداة التتبّع.
  4. هل هو ملفّ تعريف ارتباط وُضع بترويسة Set-Cookie؟ فلا حجب من جهة العميل يمكنه إيقافه. ويجب معالجته من مصدره، على الخادم.
  5. حوّلوا blocker_unknown_script_policy إلى block — ثم اختبروا الموقع بعناية، لأن هذا الإعداد يحجب كل طرف ثالث غير معروف.

تكاملٌ مشروع محجوب

أضيفوا مضيفه إلى blocker_allowlist، واحدًا في كل سطر، أو عبر المرشّح owc_blocker_allowlist. وتحقّقوا كذلك من blocker_unknown_iframe_policy: فالإطارات المجهولة محجوبة افتراضيًا، وهذه هي الحالة الأكثر شيوعًا.

وإذا كان التكامل يجب أن يبقى مشروطًا بالموافقة، فصنّفوه في الفئة الصحيحة بدل ذلك: فالبديل البصريّ يحمل زرّ «قبول …» يُطلقه بنقرة واحدة.

الماسح لا يجد شيئًا

  1. هل هو مفعَّل؟ فهو معطَّل افتراضيًا.
  2. هل يعمل WP-Cron؟ فمع DISABLE_WP_CRON وبلا cron على مستوى النظام، لا ينطلق المسح المجدول أبدًا. شغّلوا واحدًا يدويًا للتحقّق.
  3. هل الاتصال الحلقي عبر HTTP ممكن؟ فمصادقة HTTP في بيئة اختبار أو جدار حماية يحجب المسح. ولوحة التغطية تعرض أول خطأ.
  4. لا يُنفَّذ أي جافاسكربت في المسح من جهة الخادم. استعرضوا صفحة من الموقع بوصفكم مديرًا مسجَّلًا كي يُبلغ المِجَسّ عمّا يحقنه مدير الوسوم.

وفي كل الأحوال، اقرؤوا لوحة «ما الذي يغطّيه هذا المسح فعلًا» قبل الاستنتاج: فهي تميّز «لم يُعثر على شيء» من «لم يُقرأ شيء».

توليد وثيقة مرفوض

سببان محتملان، والرسالة تقولهما:

  • حقول إلزامية فارغة — وتُعرض قائمة المفاتيح الناقصة. أكملوا تبويب Legal identity.
  • حاجز اللغة — أنتم تطلبون بيانات قانونية أو شروطًا عامة لولاية قضائية غير ناطقة بالفرنسية. والزرّ مخفيّ في هذه الحالة. والسبيل الوحيد هو توفير متنكم الخاص عبر المرشّح owc_policy_template.

رسالة تحقّق DSAR لا تصل

هي مسألة قابلية تسليم في الغالب الأعمّ، لا مسألة إضافة.

  1. تحمل استجابة الواجهة البرمجية mail_sent: false عند إخفاق الإرسال، ويعرض النموذج عندئذٍ رسالة مخصَّصة تحيل إلى عنوان التواصل.
  2. ثبّتوا إضافة SMTP. فدالة mail() في PHP ترفضها معظم خوادم الاستقبال.
  3. تحقّقوا من SPF وDKIM وDMARC لنطاقكم. فالإضافة لا تعيد كتابة عنوان المُرسِل أبدًا — وهو ما سيكسر SPF — بل تضع Reply-To فحسب.
  4. تحقّقوا من أن dsar_email عنوان صالح.

وما دامت الرسالة لم تُستلَم ولم تُؤكَّد، يبقى الطلب pending والمهلة القانونية لا تنطلق.

وحدة TCF لا تُفعَّل

افتحوا تبويب Compliance: فإشعارٌ إداري يسمّي السبب.

  • missing_cmp_id: قيمة tcf_cmp_id تساوي 0. وعليكم الحصول على CMP ID من IAB Europe؛ فالإضافة لا توفّره وترفض إصدار سلسلة بمعرّف 0.
  • CMP ID أكبر من 4095: القيمة لا تتّسع في حقل الـ 12 بت داخل السلسلة وستشير إلى منصّة CMP أخرى.
  • no_gvl: قائمة المزوّدين العالمية لم تُنزَّل بعد. وهي تصل عبر cron يومي؛ تحقّقوا من أن WP-Cron يعمل ومن أن خادمكم يستطيع بلوغ vendor-list.consensu.org عبر HTTPS صادر.

كل الزوّار يتلقّون الملفّ المُهيَّأ رغم الكشف الإقليمي

  1. هل geo_enabled مفعَّل؟ فهو معطَّل افتراضيًا.
  2. هل أعلنتم وكيلكم؟ فبلا OWC_BEHIND_CLOUDFLARE أو OWC_BEHIND_CLOUDFRONT أو OWC_GEO_TRUSTED_HEADERS في wp-config.php، تُتجاهَل ترويسات البلد، لأنها قابلة للتزوير.
  3. هل ملفّ MaxMind في مكانه؟ فالإضافة لا تنزّله ولا تقدّم شاشة رفع.
  4. قد يكون الأمر طبيعيًا: فالعرض الأول لزائر يأتي من الذاكرة المؤقتة يستعمل الملفّ المُهيَّأ ما دام ملفّ تعريف الارتباط ذو الـ 24 ساعة غير موجود. وتعرض لوحة المعلومات كتلة تشخيص فيها البلد المكتشَف والملفّ المطبَّق والمصدر.

لوحة التحكّم تنبّه إلى أن مفتاح السجلّ يعيش في قاعدة البيانات

هذا هو الإشعار notice_ledger_key. وهو يعني أن AUTH_KEY وAUTH_SALT ليسا في wp-config.php — فيخزّنهما ووردبريس عندئذٍ في قاعدة البيانات — وأن OWC_LEDGER_KEY غير معرَّف أيضًا. وتستمرّ السلسلة في البناء، لكن من يصل إلى قاعدة البيانات يستطيع إعادة توقيعها: فادّعاء قابلية كشف التزوير لم يعد قائمًا.

والعلاج إضافةُ OWC_LEDGER_KEY (وما دمتم هناك، AUTH_KEY وAUTH_SALT) في wp-config.php. ويميّز التحقّق بعدها بين تدوير مفتاح وإعادة كتابة، فلا يُبطل هذا التغيير تاريخكم.

الإضافة لا تفعل شيئًا البتّة، مع إشعار أحمر

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

قواعد كتالوج «لا يمكن أن تنطبق»

إشعارٌ إداري ينبّه إليها، ولتبويب Tracker catalogue مرشّح مخصَّص. وأربعة أسباب ممكنة: نمط فارغ أو مكوَّن من محارف غير مرئية فقط، أو تعبير نمطي لا يُترجَم أو يتراجع تراجعًا كارثيًا، أو نمط أقصر من اللازم وبلا نقطة لاستهداف رابط، أو فئة لم تعد موجودة في الموقع. صحّحوا هذه الأسطر أو احذفوها: فهي تعطي انطباعًا زائفًا بالتغطية.


الأسئلة الشائعة

هل تعمل الإضافة خلف تخزين مؤقت للصفحات؟ نعم، وبنيتها كلها مقامة حول هذا القيد. فشيفرة HTML المُنتَجة واحدة لجميع الزوّار؛ والموافقة تُقرأ داخل المتصفّح وتُطبَّق قبل أول رسم. ولا يُطبَع أي رمز nonce في شيفرة قابلة للتخزين المؤقت. ولا تُوسَم بأنها غير قابلة للتخزين إلا الاستجابات الشخصية فعلًا.

هل تحلّ محلّ منصّة CMP مدفوعة؟ على معظم المواقع، هي تغطّي المساحة نفسها: لافتة، وحجب، وسجلّ تدقيق، وطلبات حقوق، وتوجيه جغرافي، ووثائق مولَّدة. وثمة أمران لا تفعلهما: فهي ليست منصّة CMP مسجَّلة لدى IAB Europe، وهي لا تقدّم استشارة قانونية ولا وثائق مراجَعة — فالمولّد ينتج مسوّدات عليكم أن تعرضوها للاعتماد.

هل السجلّ غير قابل للتزوير؟ هو قابل لكشف التزوير، بشرط واحد. فكل سطر موقَّع بخوارزمية HMAC على بصمة سابقه: وأي سطر عُدّل أو حُذف يكسر السلسلة، والتحقّق يقول أين. والضمانة تقوم على أن مفتاح التوقيع يعيش خارج قاعدة البيانات. وهذا متحقّق إذا كان AUTH_KEY وAUTH_SALT في wp-config.php، أو إذا عرّفتم OWC_LEDGER_KEY. وإلا فإن ووردبريس يخزّن الأملاح في قاعدة البيانات ويستطيع مهاجم يصل إليها إعادة توقيع السلسلة — والإضافة تكتشف هذه الحالة وتنبّهكم إليها.

هل يُبطئ الماسح الموقع؟ لا. فهو معطَّل افتراضيًا، وحين يُفعَّل يعمل على WP-Cron بالوتيرة التي تختارونها، بجلب عيّنة من صفحاتكم من جهة الخادم. ولا يعمل أبدًا أثناء تصفّح زائر.

هل يجد الماسح ملفّات تعريف الارتباط؟ جزئيًا، ومن المهمّ فهم ذلك. فالمسح من جهة الخادم يقرأ ترويسات Set-Cookie في صفحاتكم: ولذلك يجد ملفّات تعريف الارتباط التي يضعها الخادم، بما فيها HttpOnly. وهو لا ينفّذ أي جافاسكربت، فالملفّات التي تكتبها سكربتات داخل المتصفّح غير مرئية له؛ وتلك يجمعها مِجَسّ لا يعمل إلا لمدير مسجَّل. عاملوا النتيجة على أنها جرد لما شوهد، لا قائمة شاملة — والشاشتان تقولان ذلك بدل تركِكم تفترضون العكس.

كيف يُنفَّذ طلب حقوق؟ يرسل الشخص النموذج ويتلقّى رسالة تحقّق. وتأكيدُ الطلب على الصفحة المرتبطة يبدأ مهلة المادة 12.3 ويفتح طلب ووردبريس أصليًا. ومن شاشة DSAR، تنزّلون تصديرًا بصيغة JSON تنتجه كل أدوات التصدير المسجَّلة في الموقع، وتشغّلون كل أدوات المحو، وتغلقون بجواب مكتوب يبقى مرفقًا بالطلب. ولذلك يعتمد ما يغطّيه التصدير على الإضافات المثبَّتة؛ وتلك التي لا تسجّل أيًّا من هذه الخطّافات يجب التعامل معها يدويًا.

هل أستطيع استعمال وحدة TCF مع AdSense أو Ad Manager؟ فقط برقم CMP ID خاص بكم تصدره IAB Europe، وحتى في هذه الحالة مع تحفّظ. فبلا CMP ID، لا تُحمَّل الوحدة إطلاقًا. ومع CMP ID، تصدر سلسلة TC مُرمَّزة ترميزًا صحيحًا وتعرض اللوحة كل غرض وكل ميزة خاصة يمكن لهذه السلسلة أن تدّعيها — لكن سياسة TCF تفرض على منصّة CMP مسجَّلة خيارات على مستوى الغرض وعلى مستوى المزوّد. وهنا تتبع مفاتيح الأغراض الفئاتِ ولا يوجد أي خيار على مستوى المزوّد: فهذه ليست منصّة CMP مسجَّلة، وللمزوّدين حقّ رفض إشارتها. فإن كان دخل الإعلانات عبر TCF يهمّ موقعكم، استعملوا منصّة CMP معتمدة.

بأي لغة تُولَّد الوثائق؟ سياسة الخصوصية وسياسة ملفّات تعريف الارتباط موجودتان للملفّات الأحد عشر، بلغة الولاية القضائية: الإنجليزية، والفرنسية لفرنسا وبلجيكا ولوكسمبورغ وكيبك، والبرتغالية للبرازيل. أما البيانات القانونية والشروط العامة فبالفرنسية فقط؛ ولأي ولاية قضائية أخرى، يرفض المولّد إنتاجهما بدل نشر وثيقة غير ملائمة.

ما الذي أستطيع تغييره في اللافتة؟ أربعة مواضع، وسمة فاتحة أو داكنة أو تلقائية، وشعار اختياري، والتسميات، وزرّ عائم لإعادة الفتح. وأي عنصر يحمل الفئة owc-open-preferences يعيد فتح اللوحة. و«رفض الكل» يُعرض بالبروز نفسه الذي عليه «قبول الكل». وعلامة الإغلاق معطَّلة افتراضيًا؛ وإذا فُعّلت، سجّلت رفضًا كاملًا، لا إغلاقًا صامتًا. واللوحة قابلة للاستعمال بلوحة المفاتيح، ومفاتيحها تحمل حالة مرئية، والنافذة الحوارية تحصر التركيز ثم تعيده. والنصوص قابلة للترجمة وللاستبدال عبر المرشّح owc_banner_texts.

ما الذي يحجبه الحجب التلقائي بالضبط؟ السكربتات الخارجية، ومقاطع التتبّع المضمّنة، والإطارات، وبكسلات القياس، وأوراق أنماط التحليلات والتسويق، ومصادر وسائط الأطراف الثالثة — كلها يُعاد كتابتها قبل الموافقة وتُطلَق بعدها، بترتيب المستند. وتلميحات الموارد المتّجهة إلى طرف ثالث مُفهرَس تُحذف بدل أن تُؤجَّل، لأن التلميح يفتح اتصالًا ولا يبقى بعده ما يُستعاد. وأوراق الأنماط والخطوط التي يقدّمها مضيف مصنَّف وظيفيًا تُترك سليمة. وسمات التحميل التكاسلي في إضافات التخزين المؤقت تُحيَّد كي لا يستعيد مُحمِّلٌ رابطًا محجوبًا. وتُسلَّم الإضافة مع 175 بصمة، قابلة للتعديل من شاشة Tracker catalogue وقابلة للتوسيع عبر مرشّح.

ما الذي يُقيَّد في السجلّ؟ كل إجراء موافقة — قبول، ورفض، وحفظ جزئي، وانسحاب GPC، وتجديد، وسحب — يُضاف إلى الجدول المُتسلسِل. ويحوي السطر عنوان IP مستعارًا، وبصمة لوكيل المستخدم، ورابط الصفحة، وملفّ الامتثال، وبصمة الوثائق السارية، وبصمة اللافتة التي عُرضت فعلًا، وإصدار الإضافة — أي العناصر التي تتيح إعادة بناء ما رآه الزائر.

ما الحمايات الموجودة على نموذج الحقوق؟ فخّ للروبوتات، ومهلة دنيا للملء، وإقرار إلزامي يُتحقَّق منه على الخادم، وثلاثة حدود معدّل متمايزة، ورمز يُستعمل مرة واحدة ولا يُخزَّن إلا بصيغة بصمة، وتأكيدٌ يتطلّب إجراءً صريحًا على الصفحة — بحيث لا يستطيع ماسح روابط بريدي أن يؤكّد هوية بدلًا من صاحبها. والطلب الذي لم يؤكّد صاحبه هويته قطّ لا يمكن تصديره ولا محوه ولا تسجيله مُلبّى، وهذا الفحص مطبَّق على الخادم، لا بإخفاء أزرار فحسب.

ما إشارات Google Consent Mode v2 المُرسَلة؟ السبع كلها: ad_storage، وad_user_data، وad_personalization، وanalytics_storage، وfunctionality_storage، وpersonalization_storage، وsecurity_storage. وترتبط بها الفئات الستّ انطلاقًا من مصدر حقيقة واحد، بحيث لا تستطيع اللافتة والحجب والإقلاع أن تتباعد.

كيف يُدار انسحاب CCPA وإشارة GPC؟ يُحقَن عنصر تحكّم «Do Not Sell or Share» في التذييل أو يُوضع برمز مختصر. والنقرة الأولى تسجّل الانسحاب، كما تفرض اللوائح الكاليفورنية، بدل أن تفتح لوحة. وتُعامَل إشارة Global Privacy Control انسحابًا مُلزِمًا تحت الملفّات الأمريكية، مرة واحدة في كل جلسة تصفّح، ويُنبَّه الزائر إن كانت قد حلّت محلّ اختيار سجّله. أما تحت ملفّات عائلة GDPR، فتُعامَل قرينةً: فتُرفض الفئات الاختيارية مسبقًا في الواجهة، وتبقى اللافتة معروضة، ولا يُسجَّل شيء — لأن الموافقة هناك يجب أن تكون فعلًا إيجابيًا.

ما ملفّات تعريف الارتباط التي تضعها الإضافة نفسها؟ كلها ملفّات داخلية، ولا يخدم أيٌّ منها التتبّع، وكلها معلَنة في سياسة ملفّات تعريف الارتباط المولَّدة: owc_consent (الاختيارات، ورمز المتصفّح المستعار، والملفّ؛ ومدّته تتبع إعداد التجديد، 12 شهرًا افتراضيًا، بسقف 13)، وowc_geo (البلد والملفّ المكتشَفان، 24 ساعة، بلا أي عنوان IP)، وowc_gpc (علامة جلسة)، وowc_gpc_notice (5 دقائق)، وeuconsent-v2 (سلسلة TCF، فقط إذا كانت الوحدة مفعَّلة وبعد تصرّف من الزائر).

هل تعمل في وضع الشبكة (multisite)؟ نعم. فلكل موقع في الشبكة جداوله وإعداداته الخاصة. والتفعيل الشبكي يمرّ على كل المواقع فقط إذا كانت الشبكة تضمّ 200 موقع كحدّ أقصى؛ وفوق ذلك، يُهيَّأ كل موقع عند أول طلب له.

وماذا لو حذفت الإضافة؟ يبقى افتراضيًا السجلّ، ونتائج الماسح، والكتالوج، وروابط OW Forms، والخيارات والإعدادات. وثمة أمران يختفيان دائمًا، أيًّا كان إعدادكم: المهامّ المجدولة الستّ، وجدول طلبات الحقوق — وهو الوحيد الذي يحوي بيانات شخصية تعرّف أطرافًا أخرى تعريفًا مباشرًا، وبعد رحيل الإضافة لا يبقى ما يحدّ مدة حفظه ولا شاشة تتيح الردّ عليه. صدّروا طلباتكم قبل حذف الإضافة. ولتنظيف الباقي تنظيفًا كاملًا، فعّلوا «Delete all data on uninstall» قبل الحذف.

أين أجد الدعم؟