عميل جديد عايز عرض سعر لصيانة موقعه، وقبل ما يديك باسورد ووردبريس لتضيف له ميزة جديدة، مثل متجر أو نموذج تواصل أو تحسين للسيو، دون كتابة كود. اختر الإضافات الموثوقة المحدّثة، ولا…">الإضافات والقوالب والمستخدمين والإعدادات، وما يظهر فيها يختلف حسب دور المستخدم.">لوحة التحكم عايز تعرف إنت داخل على إيه: 12 إضافة متحدّثة؟ ولا 4 إضافات آخر تحديث ليهم من 2022؟ الفرق ده ممكن يغيّر السعر كله.
الكلام ده مبني على تجربة مطور بنى أداة مجانية بتقرأ أي موقع ووردبريس من بره وتطلّع إضافاته. اكتشف إن الطريقة “البديهية” بتعدّ WooCommerce ست مرات، وإن الشغل الحقيقي كله في إنك متصدقش أدلتك بسرعة.
المشكلة: أداة ساذجة ترى ست إضافات بدل واحدة
وجّه كاشفاً بسيطاً إلى متجر WooCommerce وسيخبرك أن الموقع يشغّل wc وwc-admin وwc-analytics وwc-telemetry وwccom-site وwc-admin-email. هذه إضافة واحدة، وقد لا يظهر المعرّف الحقيقي woocommerce في القائمة أصلاً.
والكاشف نفسه سيعدّ wp-block-editor وwp-site-health إضافات، وهما جزء من نواة ووردبريس. هناك ثلاث إشارات تكشف الإضافات من الخارج، ولكل واحدة فخ.
ثلاث إشارات
أي إشارة تثق بها؟
| المعيار | مسارات الملفات | معرّفات السكربتات | نطاقات REST |
|---|---|---|---|
| درجة الثقة | عالية | متوسطة | منخفضة |
| يطابق اسم الإضافة؟ | نعم | لا دائماً | لا دائماً |
| يكشف إضافات بلا واجهة | لا | لا | نعم |
| يتأثر بدمج الكاش | نعم | أحياناً | لا |
| يحتاج تأكيداً | لا | نعم | نعم |
الإشارة 1: مسارات الملفات (الأكثر موثوقية)
كل إضافة (Plugin) تعيش في /wp-content/plugins/<slug>/، وعندما تحمّل ملف CSS أو JavaScript أو صورة، يظهر هذا المسار في HTML الصفحة:
const PLUGIN_PATH = //wp-content/plugins/([a-z0-9-]+)//gi;
function slugsFromPaths(html: string): Set<string> {
const slugs = new Set<string>();
for (const match of html.matchAll(PLUGIN_PATH)) {
slugs.add(match[1].toLowerCase());
}
return slugs;
}
ظهور المعرّف المختصر للإضافة (Plugin Slug) في مسار ملف يعني أنها مثبتة ونشطة على هذه الصفحة. وللإضافات القادمة من دليل WordPress.org، اسم المجلد هو نفسه المعرّف في الدليل.
الفخ: غياب الإضافة لا يثبت شيئاً. ثلاثة أشياء تخفيها:
- إضافات الكاش والتحسين التي تدمج كل الملفات في ملف واحد داخل مجلد الكاش الخاص بها.
- إضافات تعمل في لوحة التحكم أو على السيرفر فقط، بلا أي ملفات في الواجهة.
- إضافات الأمان التي تخفي مسارات الإضافات عمداً.
لذلك قائمة قصيرة من هذه الإشارة تعني “هذا ما يظهر”، لا “الموقع خفيف”. وضّح هذا للعميل في التقرير، وإلا سيفهم الرقم خطأً.
الإشارة 2: معرّفات السكربتات (مفيدة ومليئة بالفخاخ)
عندما يطبع ووردبريس ملفاً مسجلاً، يضيف له id مبنياً على معرّف السكربت (Script Handle) الذي اختاره المطور:
<link rel="stylesheet" id="contact-form-7-css" href="...">
<script id="wc-add-to-cart-js" src="..."></script>
احذف -js أو -css من النهاية تحصل على المعرّف:
const HANDLE_ID = /<(?:script|link)b[^>]*bid=["']([a-z0-9_-]+)-(js|css)["']/gi;
function handlesFromIds(html: string): Set<string> {
const handles = new Set<string>();
for (const match of html.matchAll(HANDLE_ID)) {
handles.add(match[1].toLowerCase());
}
return handles;
}
التعبير يشترط علامة الاقتباس بعد -js مباشرة، فيتجاهل الملحقات المضمّنة مثل -js-extra و-js-after لأنها تابعة لمعرّف حُسب بالفعل.
من هنا جاءت صفوف WooCommerce الستة: المعرّف ليس اسم الإضافة، بل أي نص اختاره المطور. وثلاثة أنواع تكسر الطريقة الساذجة:
- معرّفات النواة: مثل
wp-polyfillوjquery-coreوwp-block-libraryوglobal-styles. تحتاج قائمة استبعاد صريحة، ولا تستبعد كل ما يبدأ بـwp-لأن إضافات حقيقية مثلwp-mail-smtpتبدأ بها أيضاً. - عائلات المعرّفات: إضافة واحدة تسجّل معرّفات كثيرة ببادئة مشتركة. WooCommerce تستخدم
wc-*وwccom-*، وYoast تستخدمyoast-*وwpseo-*بينما مجلدهاwordpress-seo. - معرّفات القالب في Elementor تصميم محفوظ يُعاد استخدامه، مثل رأس الموقع أو التذييل أو صفحة المقالة أو صفحة المنتج. تصممه مرة وتحدد شروط ظهوره، فيُطبَّق على كل…">القالب (Theme): ملف CSS من القالب بمعرّف
acme-siteheaderسيبدو تماماً كإضافة غير موجودة.
الحل: اشترط التأكيد. لا تقبل معرّفاً جاء من handle فقط إلا إذا وُجد في دليل WordPress.org، أو ظهر أيضاً كمسار ملف حقيقي في الموقع. وكل ما عدا ذلك يُحذف بصمت:
// Core script and style handles. Extend this as WordPress adds packages.
const CORE_HANDLES = new Set([
'jquery', 'jquery-core', 'jquery-migrate', 'wp-polyfill', 'wp-emoji-release',
'wp-block-library', 'wp-block-editor', 'wp-site-health', 'global-styles',
'classic-theme-styles', 'admin-bar', 'regenerator-runtime', 'lodash', 'moment',
]);
// Prefix to parent slug. Order matters: more specific prefixes first.
const HANDLE_FAMILIES: Array<[string, string]> = [
['wccom-', 'woocommerce'],
['wc-', 'woocommerce'],
['wpseo-', 'wordpress-seo'],
['yoast-', 'wordpress-seo'],
['elementor-', 'elementor'],
];
function familyParent(handle: string): string | null {
if (handle === 'wc') return 'woocommerce';
const match = HANDLE_FAMILIES.find(([prefix]) => handle.startsWith(prefix));
return match ? match[1] : null;
}
function acceptHandle(
handle: string,
pathSlugs: Set<string>,
directorySlugs: Set<string>,
): string | null {
if (CORE_HANDLES.has(handle)) return null;
const parent = familyParent(handle) ?? handle;
if (pathSlugs.has(parent) || directorySlugs.has(parent)) return parent;
return null;
}
لماذا الحذف الصامت؟ لأن البديل المغري، أي عرض المعرّفات غير المطابقة كـ “ليست في الدليل”، يحوّل ملف CSS من القالب إلى “اكتشاف”. وأي مطور ووردبريس سيلاحظ الخطأ في عشر ثوانٍ ويفقد الثقة في التقرير كله.
في Elementor وJetEngine: إذا أضفت عائلات لمكدّس ArabCMS فانتبه للترتيب. elementor-pro يجب أن تسبق elementor- في القائمة، وإلا ستُنسب ملفات Elementor Pro إلى Elementor المجاني. وإضافات Crocoblock تشترك في البادئة jet- لكنها إضافات منفصلة (jet-engine وjet-smart-filters وغيرها)، فلا تضع قاعدة واحدة لكل jet-، بل اعتمد على مسار الملف للتمييز بينها.
الإشارة 3: نطاقات REST API (الأضعف)
معظم مواقع ووردبريس تعرض فهرساً على /wp-json/، وفيه مصفوفة namespaces تضم بادئات المسارات التي سجلتها كل إضافة نشطة في واجهة REST البرمجية (REST API):
{
"namespaces": ["oembed/1.0", "wc/v3", "yoast/v1", "contact-form-7/v1", "wp/v2"]
}
هذه الإشارة تلتقط إضافات لا تحمّل أي ملف في الواجهة لكنها تسجّل مسارات، فتسد جزءاً من ثغرة الإشارة الأولى.
الفخ: النطاقات ليست معرّفات أيضاً. wp/v2 وoembed/1.0 من النواة، وyoast/v1 تخص wordpress-seo. خريطة العائلات نفسها تؤدي معظم العمل هنا، وقاعدة التأكيد نفسها تنطبق. والنطاقات تأتي في عائلات كذلك: WooCommerce تتوزع على wc/v3 وwc/store/v1 وwc-admin.
بعض المواقع تعطّل فهرس REST أو تقيّده، ولذلك سجّل مع كل إضافة الإشارة التي كشفتها (مسار، معرّف، نطاق، أو أكثر من واحدة) لتعرف وزن كل صف لاحقاً.
معرفة الإصدار المثبت: مؤكد أم مُستنتج؟
معرفة أن الإضافة مثبتة نصف المهمة. أن تعرف أن الموقع على 4.2 بينما الإصدار الحالي 6.1 هو ما يهم في عرض السعر.
المصدر الأفضل ملف readme.txt داخل مجلد الإضافة، وفيه سطر Stable tag. لكن كثيراً من المواقع، والكبيرة غالباً، تحجب الطلبات المباشرة لمجلدات الإضافات.
البديل هو باراميتر ver في روابط الملفات، مع فحص مهم:
function versionFromAsset(
src: string,
pageUrl: string,
| coreVersion: string | null, |
| --- | --- |
| ): string | null { |
const ver = new URL(src, pageUrl).searchParams.get('ver');
if (!ver) return null;
if (coreVersion && ver === coreVersion) return null;
return ver;
}
السبب: عندما تسجّل إضافة ملفاً دون تمرير رقم إصدارها، يضيف ووردبريس رقم إصدار النواة بدلاً منه. إذا أخذته كما هو فستقول إن الإضافة على 6.8 بينما 6.8 هو إصدار ووردبريس نفسه.
قاعدتان إضافيتان:
- ميّز النوعين في التقرير: الإصدار من
readme.txtمؤكد، ومن?ver=مُستنتج لأنه باراميتر كسر الكاش (Cache Busting) والموقع يستطيع وضع أي قيمة فيه. - استخرج إصدار النواة من ملفات النواة: مثل
verعلى ملفات/wp-includes/، لأن وسمgeneratorكثيراً ما يُحذف.
ما يخبرك به دليل WordPress.org وما لا يخبرك
مع قائمة نظيفة من المعرّفات، تعطيك واجهة الدليل حقائق الصيانة لكل إضافة: تاريخ آخر إصدار، وآخر نسخة ووردبريس اختُبرت عليها، وهل ما زالت مدرجة في الدليل.
لكنها لا تعطيك بيانات الثغرات. وقرار الكاتب هنا صائب في رأينا: لا تخمّن. الأداة المجانية التي تزيّف فحص الأمان إما تحذّر من إضافات سليمة، أو تحذّر من حالات مشهورة وتسكت عن الباقي فتوحي بأن كل شيء فُحص. والأفضل أن تقول بوضوح إنك لم تُجرِ فحصاً أمنياً.
ونقطة مهمة لسوقنا: معظم مواقع العملاء في المنطقة تعتمد على إضافات مدفوعة من خارج الدليل، مثل Elementor Pro وJetEngine وقوالب ThemeForest. هذه لا يوجد لها سجل إصدارات عام، فإذا كانت 8 من 11 إضافة مدفوعة فلا تكتب “الموقع سليم” بناءً على الثلاث الباقية.
اقرأ أيضًا
الأسئلة الشائعة
س: هل يمكن معرفة كل إضافات موقع ووردبريس من الخارج؟
ج: لا. إضافات لوحة التحكم، والإضافات المدمجة بواسطة الكاش، والمخفية بإضافات الأمان قد لا تظهر. ما تحصل عليه هو ما يظهر علناً فقط.
س: لماذا تظهر WooCommerce في أدوات الفحص كأكثر من إضافة؟
ج: لأنها تسجل ملفات كثيرة بمعرّفات تبدأ بـ wc- وwccom-، والأداة الساذجة تعدّ كل معرّف كإضافة مستقلة بدل ربطها بالمعرّف الأصلي woocommerce.
س: هل رقم ?ver= في رابط الملف هو إصدار الإضافة؟
ج: أحياناً فقط. إذا طابق رقم إصدار ووردبريس فهو غالباً إصدار النواة، وفي كل الأحوال يُعتبر إصداراً مُستنتجاً لا مؤكداً.
س: هل فحص الموقع من الخارج قانوني؟
ج: قراءة HTML العام وفهرس /wp-json/ هي نفسها ما يراه أي زائر. لكن احصل على موافقة العميل قبل أي فحص أعمق أو أدوات اختبار اختراق.
الخلاصة
أقل نتائج وأصدقها أفضل من قائمة طويلة. قائمة الاستبعاد، وخريطة العائلات، وشرط التأكيد، وفحص إصدار النواة، كلها قواعد تحذف صفوفاً بدل إضافتها، لأن نتيجة كاذبة واحدة تكلفك ثقة العميل.
جرّب الإشارات التلاتة دي على موقع عميلك الجاي قبل ما تبعت عرض السعر، وهتلاقي التسعير بقى أدق بكتير. ابن موقعك قطعة قطعة، وابدأ بإنك تعرف القطع اللي عندك.
مرجع المقال (بالإنجليزية): The Obvious Way to Detect WordPress Plugins Counts WooCommerce Six Times
المقال ده مش ترجمة حرفية: متكيّف للقارئ العربي ومضاف عليه سياق ووردبريس وElementor وJetEngine.



