# نطاق العمل: ملاحظات المراجع + الحالات المشابهة

**الغرض:** تجميع ما ذكره فريق WordPress.org صراحة، مع كل ما يماثله في الكود (حتى لو لم يُذكر سطراً بسطر)، لتسهيل التخطيط والتنفيذ.  
**تاريخ المستند:** 2026-03-29 — **آخر تحديث للتنفيذ:** 2026-04-05 (دفعة تاسعة على **YOOAdmin Lite** فقط: توحيد بادئة **`yooadm*`** — إعادة تسمية **`YP_*`** على `window` + globals **`YOOAdmin*` / `YOOADMIN_*` / `yooadmin*`** الممرَّرة عبر `wp_localize_script` ومراجع JS؛ رسائل console للإشعارات `[yooadm Notifications]`)

### نطاق التنفيذ المسجَّل في هذا الملف (مهم)

- **ما يُوصَف هنا كـ «مُنفَّذ» أو «مُكتمل» يخص بشكل أساسي YOOAdmin Lite** — المجلد **`yooadmin/`** في هذا المستودع — إلا إذا وُضِعَت إشارة صريحة لملف أو مسار آخر.
- **YOOAdmin Extended** (`yooadmin-extended/`) **لم يُطبَّق عليه نفس الدفعات بالكامل** في نفس الـ commit. في الكود الحالي ما زالت تظهر أسماء قديمة مثل **`YP_Notifications`**, **`YOOADMIN_SETTINGS`**, **`YP_Inbox`**, **`YP_AdminUtils`** في JS و`wp_localize_script` وغيرها. **لا تُفترض مساواة نطاق المراجعة** بين النسختين حتى تُجرى مزامنة منفصلة على Extended (ملف بملف أو دفعة مخصصة).
- سجل «دفعة تاسعة» وقائمة الجزء ج أدناه تعكس **اكتمال المهام على اللايت**؛ بند **مزامنة Extended** يبقى مفتوحاً إلى أن يُنفَّذ صراحةً على ذلك المسار.
- **قائمة تحقق يدوية لـ Extended (منفصلة، بدون مزامنة تلقائية):** `yooadmin-extended/docs/REVIEW_AND_SIMILAR_SCOPE.md` — نفس المرجع النظري مع صناديق تبدأ غير منفّذة لتعليمها أثناء إصلاح Extended.

**صيانة المستند (إلزامي للتنفيذ):** أي دفعة عمل على YOOAdmin (قوائم، أمان، دمج إضافات، إلخ) **تُحدَّث فيها هذا الملف (`docs/REVIEW_AND_SIMILAR_SCOPE.md`)** في نفس الوقت: سطر «آخر تحديث»، أقسام **ب10** / **سجل التنفيذ** عند الاقتضاء، و**قائمة التحقق** إن وُجد بند جديد. الهدف: عدم فقدان السياق بين الجلسات والمراجعين. *(الملف داخل `docs/` لتفادي تحذير Plugin Check عن ملفات markdown في جذر الإضافة.)*

---

## الجزء أ — ما ذكره المراجعون صراحة

| # | ملاحظة المراجع (ملخص) | المثال الذي أرفقوه | الإجراء المطلوب |
|---|------------------------|---------------------|------------------|
| A1 | أخطاء مع `WP_DEBUG` — لا يعمل مع Elementor | استثناء Elementor بسبب `do_action` على `in_plugin_update_message-…` | إزالة أو استبدال استدعاء الخطاف في `includes/notifications/collector.php` (~242–245) بحيث لا يُشغَّل كود إضافات خارج سياق نواة ووردبريس، أو تمرير وسائط متوافقة مع توقعات الإضافات الكبيرة. |
| A2 | رابط Ajax لا يُفترض أنه دائماً `wp-admin/admin-ajax.php` | `assets/js/admin/notifications-ui.js:811` — `YP_Notifications.ajax_url = '/wp-admin/admin-ajax.php'` | إزالة المسارات الثابتة من JS؛ الاعتماد على `admin_url('admin-ajax.php')` عبر `wp_localize_script` فقط. |
| A3 | تحديد مسارات الملفات/الروابط بشكل صحيح | `templates/yoopixel/admin/pages/dashboard.php:15` — `dirname(__FILE__, 6)` | استخدام `plugin_dir_path(YOOADMIN_PLUGIN_FILE)` (أو ما يعادله) دون افتراض عمق المجلدات. |
| A3b | (نفس الفئة) | `includes/core/admin-favicon.php:63` — `ABSPATH . ltrim(wp_parse_url(...))` | استبدال المنطق بمسار آمن (مثلاً تحويل URL داخلي إلى مسار عبر `home_url`/`wp_normalize_path` أو الاكتفاء بـ `download_url` للمصادر الخارجية). |
| A4 | لا يجوز تغيير حالة تفعيل إضافات أخرى (أو التدخل بغير ما تسمح السياسة) | `yooadmin.php:28` — `deactivate_plugins('yooadmin/yooadmin.php', true)` | إزالة التعطيل البرمجي؛ استبداله بإشعار إداري + إيقاف تحميل الإضافة عند التعارض، أو استخدام **Plugin Dependencies** (WP 6.5+) حسب ما يناسب منتجك، مع توضيح للمراجعين. |
| A5 | أسماء عامة / بادئات — دوال، كائنات JS من localize، إلخ | أمثلة: `YP_Notifications`, `yooAdminFocusNotice`, `YOO_FOCUS`, … | توحيد بادئة واضحة (≥ 4 أحرف، مثل `yooadm*`) لكل كائنات `wp_localize_script` المذكورة في بريد المراجعة **و** أي مماثل في المشروع (انظر الجزء ب أدناه). |

---

## الجزء ب — حالات مشابهة لملاحظات المراجع (لم تُذكر كلها في البريد)

### ب1 — نفس مشكلة Ajax / REST بمسارات ثابتة (مثل A2)

| الملف | السطور (تقريباً) | المشكلة |
|-------|------------------|---------|
| `assets/js/admin/yp-admin-utilities.js` | 45، 66 | `fetch('/wp-json/yooadmin/v1/settings'…)` و`fetch('.../' + key)` — جذر الموقع ثابت. |
| `assets/js/admin/notifications-ui.js` | 796–818 | قيم افتراضية لـ `rest_url` و`ajax_url` بمسارات ثابتة عند غياب/فراغ الخصائص. |
| `assets/js/admin/yoo-settings.js` | 449–450 | fallback `'/wp-admin/'` عند غياب `yooadmSettings.adminUrl` — و`admin-settings.php` لا يمرّر `adminUrl` حالياً. |

**العمل المطلوب:** تمرير `ajaxUrl` و`restUrl` (و`adminUrl` إن لزم) من PHP بـ `rest_url()` و`admin_url()`، وتحديث JS لعدم استخدام سلاسل جذر ثابتة.

---

### ب2 — نفس فئة “مسار الإدارة / التثبيت غير القياسي” (مثل A3)

| الملف | السطور (تقريباً) | المشكلة |
|-------|------------------|---------|
| `includes/core/admin-bar-focus-toggle.php` | 36 | `strpos($current_url, '/wp-admin/')` — يفشل عند مسار إدارة مخصص. |
| `includes/core/assets.php` | 166 | افتراض `$notifications_scope = '/wp-admin/'` قبل استبداله من `admin_url()`. |
| `includes/notifications/ui-manager.php` | 44، 52 | `plugins_url(..., dirname(dirname(__FILE__)))` — هش مقارنة بـ `YOOADMIN_PLUGIN_FILE`. |

**العمل المطلوب:** الاعتماد على `admin_url()`، `rest_url()`، `plugin_dir_path` / `plugins_url` مع ملف الإضافة الرئيسي.

---

### ب3 — نفس روح “التعارض مع إضافات أخرى” (مثل A1 + سياسة الجودة)

| الملف | السطور (تقريباً) | المشكلة |
|-------|------------------|---------|
| `assets/js/admin/yp-legacy-notification-disable.js` | 95–116 | إعادة تعريف `window.fetch` لاعتراض طلبات معينة — يؤثر على **كل** سكربتات الصفحة (نفس فئة “لا تكسر الإيكوسيستم”). |

**العمل المطلوب:** إزالة إعادة التعريف العالمية أو استبدالها بآلية لا تلمس `window.fetch` (مثلاً إيقاف استدعاء الـ endpoint القديم من الكود الحالي، أو مسار توافق من الخادم فقط)، مع تعليق يوضح السبب إن بقي أي شِم.

---

### ب4 — توحيد البادئة — كل `wp_localize_script` غير متوافق مع توصية المراجعة

المراجع ذكر أمثلة؛ **المشابه** كان جدولاً أدناه — **جُزء كبير منه مُنفَّذ سابقاً** (`yooadmNotifications`, `yooadmRuntime`, …). **دفعة 2026-04-05 (تاسعة)** أكملت: **`YP_*` على `window`**، و**`YOOADMIN_SETTINGS` → `yooadmSettings`**، و**`YOOAdminToast` / `YOOAdminAlerts` / `YOOAdminPopup`** → `yooadmToast` / `yooadmAlerts` / `yooadmPopup`، و**`yooadminPosts` / `Pages` / `Categories` / `Tags` / `UsersBulk` / `Bar` / `WelcomePopup` / `License` / `Wizard`** (من PHP) → `yooadm*`، و**`YOODashboard` → `yooadmDashboard`**، ومعالج الإعداد **`yooadmWizardModule`** + بيانات **`yooadmWizard`** من `wp_localize_script`.

| الملف | الحالة (مختصر) |
|-------|------------------|
| `includes/notifications/ui.php`، `ui-manager.php`، `header.php` | `yooadmNotifications` (سابقاً) |
| `includes/core/assets.php` | `yooadmRuntime`, `yooadmCardMenus`, `yooadmFocus`, `yooadmBannerTooltip`, `yooadmPanel*`, `yooadmCardIconsI18n`, `yooadmFocusAlerts`, `yooadmWelcomePopup` |
| `includes/core/popup.php` | `yooadmCardMenus` |
| `includes/core/plugin-actions.php` | `yooadmCleanup` |
| `includes/core/focus-mode-notice.php` | `yooadmFocusNotice` |
| `includes/admin/users-page.php` | `yooadmUsers`, `yooadmProfile`, `yooadmUsersBulk` |
| `templates/yoopixel/admin/pages/yoopanel/enable-focus.php` | `yooadmFocusAlerts`, `yooadmFocusRedirect` |
| `includes/admin/admin-settings.php` | **`yooadmSettings`** (كان `YOOADMIN_SETTINGS`) |

**ما يبقى خارج نطاق «إعادة تسمية globals»:** ثوابت PHP مثل `YOOADMIN_SETTINGS_SLUG`؛ أسماء ملفات السكربتات (`yp-*.js`)؛ تعليقات `@package YOOAdmin`؛ نصوص العلامة التجارية للمستخدم.

---

### ب5 — فئة “الوثائق والسلوك” (يشبه اعتراض المراجع على الدقة)

| الملف | المشكلة |
|-------|---------|
| `readme.txt` — أسئلة شائعة “Does this plugin make external API calls?” | الجواب “No” قد يتعارض مع طلبات الترخيص/التحقق إلى `yooadmin.io` عند استخدام تلك الميزات. |

**العمل المطلوب:** صياغة FAQ توضح متى يحدث الاتصال الخارجي (بدون تضليل).

---

### ب6 — أمان REST — نفس روح “لا تضعف الموقع” (غير مذكور في البريد لكن شائع عند إعادة المراجعة)

| الملف | المشكلة |
|-------|---------|
| `includes/notifications/rest-api-compatibility.php` | مسار GET للإعدادات بصلاحية أضعف من POST؛ و`get_option($key)` بدون قائمة بيضاء مثل حفظ POST. |

**العمل المطلوب:** توحيد `permission_callback` مع سياسة الإعدادات؛ السماح بقراءة مفاتيح مسموحة فقط.

---

### ب7 — تسجيل مسارات REST مكررة (جودة / سلوك غير متوقع)

| الملفات | المشكلة |
|---------|---------|
| `includes/notifications/rest-api-endpoints.php` و`includes/notifications/rest-api-compatibility.php` | تسجيل متكرر لنفس المسار قد يجعل “الأخير يفوز”. |

**العمل المطلوب:** دمج التسجيل في مكان واحد.

---

### ب8 — class بدون بادئة واضحة (نفس فئة A5)

| الملف | المشكلة |
|-------|---------|
| `includes/core/License_Type_Mapper.php` | `class License_Type_Mapper` — يفضّل `YOOAdmin_License_Type_Mapper` أو الاعتماد الكامل على الـ namespace الحالي مع اسم فئة مُسبَّق. |

---

### ب9 — WordPress 6.7: `_load_textdomain_just_in_time` + تحذيرات الهيدرز (ليس من بريد المراجعة؛ ضروري مع `WP_DEBUG`)

| الموضوع | التفسير |
|---------|---------|
| **الظاهرة** | رسالة `_load_textdomain_just_in_time was called incorrectly` لنطاق `yooadmin`، ثم `Cannot modify header information` لأن الـ Notice يطبع HTML قبل إرسال الهيدرز. |
| **السبب في النواة (6.7+)** | الدالة `_load_textdomain_just_in_time` تُطلق تحذيرًا عندما يُستدعى تحميل الترجمة عبر JIT **قبل** اكتمال **`after_setup_theme`** (الشرط في `wp-includes/l10n.php`، وليس مجرد «قبل `init`» فقط). |
| **سبب جذري في YOOAdmin** | في `yooadmin.php` يُستدعى `YOOAdmin_Admin_Theme_Manager::get_instance()->init()` **أثناء تحميل ملف الإضافة** → `load_themes()` → `register_builtin_theme()` وكان يستخدام `__('YOOAdmin Legacy', 'yooadmin')` و`__('…', 'yooadmin')` لحقول الاسم/الوصف — أي **ترجمة قبل `after_setup_theme`** في كل طلب. |
| **ملاحظة تقنية** | في WP 6.7، `load_plugin_textdomain()` يُسجّل المسار ولا يحمّل ملف `.mo` فورًا بالقديم؛ لذلك أُضيف `yooadmin_bootstrap_textdomain()` في `yooadmin.php` يستدعي `load_textdomain()` بمسار `.mo` صريح (مجلد الإضافة + `wp-content/languages/plugins/`) قبل أي `require` لاحق، مع الإبقاء على `load_plugin_textdomain` على `init` مبكرًا. |
| **إصلاحات داعمة** | تأجيل تهيئة الإشعارات من `plugins_loaded` إلى `init`؛ روابط صف الإضافة في `plugin-actions.php` بنصوص إنجليزية ثابتة (كانت تستدعي `__()` مبكرًا في مسارات حافة)؛ رسالة `pre_http_request` في `external-api-guard.php` بنص ثابت عند الحظر؛ حماية `setcookie` في `focus-mode.php` بـ `headers_sent()`. |
| **خطأ PHP منفصل** | في `templates/yoopixel/admin/layout/header.php` كان `wp_localize_script` يمرّر `'license_active' => $license_active` دون تعريف `$license_active` — أُصلح بتعريف `$license_active = $is_active` بعد جلب حالة الترخيص واستخدامه في المصفوفة. |
| **`strip_tags(null)` (PHP 8.1+) مع `WP_DEBUG`** | `wp-admin/admin-header.php` يستدعي `strip_tags($title)` قبل تشغيل callback الصفحة. صفحات مسجّلة بـ `add_submenu_page('', …)` (مثل `yooadmin-admin-theme-settings`) تترك `$title` = `null` حتى ذلك الحين. كان هناك تطبيع على `admin_head` لكنه **متأخر** عن `admin-header.php`. **الإصلاح:** نفس التطبيع على **`admin_init`** (أولوية 0) في `yooadmin.php` / `yooadmin-extended.php`: إن `null === $title` فـ `$title = ''`. |

**الخلاصة:** لا تستخدم `__()` / `_e()` / `esc_html__()` في مسار يعمل **أثناء تحميل ملف الإضافة الرئيسي** أو قبل **`after_setup_theme`** ما لم يُحمَّل النطاق فعليًا عبر `load_textdomain()`؛ وتجنّب افتراض أن `load_plugin_textdomain()` وحده يكفي في 6.7.

---

### ب10 — Dashboard «Website Management»: Elementor (كرت مكرر، قائمة فرعية طويلة، أيقونة فارغة/صغيرة)

| الموضوع | التفسير |
|---------|---------|
| **لماذا كان يظهر كرتان؟** | `yooadmin_build_admin_menu_tree()` في `includes/core/popup.php` يبني **كرتًا لكل عنصر top-level** في `$menu`. Elementor يسجّل أحيانًا **أكثر من عنصر** بنفس الاسم الظاهر «Elementor» (مثل hub رئيسي + hub إعدادات/تطبيقات). |
| **لماذا كانت المشكلة «اتحاد القوائم» حسّاسة؟** | اتحاد `$submenu` من كل الـ hubs **بدون تصفية** قد يكرر عناصر الـ flyout أو يضيف صفحات غير قابلة للتحميل؛ الحل الحالي: **اتحاد بعد** `yooadmin_submenu_item_is_included` وإزالة التكرار بالـ URL، مع استبعاد صفحات مثل `elementor-system`. |
| **لماذا الأيقونة فارغة أو لا تشبه السايد؟** | (1) فرض أيقونة dashicon غير عامة في PHP كان يمنع `yp-card-icons.js` من استبدالها لأن `hasNonGenericDashicon()` يتخطى أي أيقونة ليست `dashicons-admin-generic`. (2) استخراج الأيقونة في **الكروت** (`readIconData`) لم يكن مطابقًا لـ **`yp-menus.js`**: Elementor يعرض الشعار غالبًا عبر **`-webkit-mask-image` على `::before`** داخل `.wp-menu-image` (SVG كـ data URI) وليس `<img>` أو `<svg>` داخل العنصر؛ النسخة القديمة لم تقرأ الماسك فكانت ترجع `null`. (3) دعم **`<svg>`** مضاف ليتوافق مع إضافات تضع SVG داخل `.wp-menu-image`. |
| **لماذا حجم الأيقونة أصغر من باقي الكروت؟** | بعد قراءة الماسك من السايد، كان يُنسخ **`mask-size` / `position` / `repeat`** من `getComputedStyle` (أبعاد الشريط الجانبي) كـ **inline** فوق `.ypi-wp-bg`، فيُلغى `contain` و`var(--yp-card-icon-size)` المعرّفان في CSS للكروت. |
| **ليش قائمتان باسم Elementor؟** | Elementor يستدعي **`add_menu_page` أكثر من مرة** بنفس العنوان. إحداهما غالباً slug **`elementor`** (Home / Editor / Upgrade) وقد لا يملأ **`$menu[i][6]`** → يبدو **بدون أيقونة dashicon**. الأخرى slug مختلف (مثل hub تطبيقات/واجهة أخرى) وقد يظهر له **أيقونة** في DOM. YOOAdmin كان ينسخ `#adminmenu` كما هو فيظهر **صفّان**. |

**الحل المُنفَّذ (ملخص):**

| الطبقة | الملف | السلوك |
|--------|-------|--------|
| **PHP** | `includes/core/popup.php` | كروت الداشبورد: `yooadmin_merge_elementor_top_level_menu_duplicates()` + فلتر `yooadmin_admin_menu_tree`. |
| **JS (سايد + yoopixelMenus)** | `assets/js/admin/yp-menus.js` | **المسار الافتراضي:** بناء `#yps-sidebar` وملء **`window.yoopixelMenus`** من **`window.yooadmCardMenus`** (نفس مصدر البوب-أب والكروت: `yooadmin_build_admin_menu_tree()`). البيانات تُمرَّر مرة على **`yp-admin-core-essential`** في `includes/core/assets.php` — لا تكرار تعريف عالمي. **`feedYoopixelMenusFromCardMenus`** + **`buildSidebarFromCardMenus`**؛ ثم **`hydrateExistingFromNative`** للأيقونات/الشارات من `#adminmenu`. **احتياطي** عند غياب البيانات: **`feedYoopixelMenus`** + **`addMissingFromNative`** (نسخ من DOM). **لا** تعديل `$menu` في PHP من أجل السايد. |
| **JS (كروت)** | `assets/js/admin/yp-card-icons.js` | SVG + ماسك `::before`؛ `mask-image` فقط على `.ypi-wp-bg`. |
| **PHP + توطين** | `includes/core/assets.php`، `includes/core/popup.php` | `yooadmCardMenus` على **`yp-admin-core-essential`**؛ **`yooadmin_maybe_localize_popup`** لا يعيد توطين نفس المتغيّر على `yooadmin-popup` (تجنّب `var yooadmCardMenus` مرتين). **`yooadmRuntime.excludedSubmenuPages`**: قائمة `page=` المستبعدة من المرآة (افتراضياً `elementor-system`)؛ نفس المنطق في JS. |
| **PHP — عناوين فرعية وبادجات** | `includes/core/popup.php` | **`yooadmin_submenu_title_and_badge()`**: فصل عنوان نظيف عن عدد التحديثات/التعليقات؛ البادج يُمرَّر في الحقلين `badge` / `badge_kind` فقط عند العدد &gt; 0 (لا يظهر «Updates 0» كنص). |
| **PHP — استبعاد روابط وهمية** | `includes/core/popup.php` | **`yooadmin_submenu_item_is_included()`** + **`yooadmin_get_excluded_submenu_pages()`** (فلتر `yooadmin_excluded_admin_submenu_pages`): يستبعد فواصل ووردبريس، `#`، `javascript:`، وصفحات مثل **`elementor-system`** التي لا تحمّل أو تعطي خطأ. |
| **PHP — دمج قوائم (عام)** | `includes/core/popup.php` | **`yooadmin_merge_duplicate_top_level_menus_by_title_family()`**: إن تكرر **نفس العنوان الظاهر** لأكثر من صف علوي وكانت الـ slugs من **نفس العائلة** (`foo` و`foo-bar` كما في `yp-menus.js`) يُدمج الصف في واحد ويُؤتَى على الفرعيّات (dedupe بالـ URL). **`yooadmin_merge_post_type_listing_into_prefixed_hub()`**: أي صف `edit.php?post_type=X` يُدمج تحت صف hub إن كان `X` يبدأ بـ `{token}_` حيث `token` مستخرج من slug الـ hub (مثال: `elementor_library` → `elementor`). فلاتر التعطيل: `yooadmin_merge_duplicate_top_level_menus_by_title_family`، `yooadmin_merge_post_type_into_prefixed_hub`، `yooadmin_post_type_hub_merge_skip`. الدالتان القديمتان باسم Elementor أصبحتا **aliases** لنفس المنطق. |
| **JS** | `yp-menus.js`، `yp-popup.js` | **`isNavigableSubmenuHref`** / **`isExcludedSubmenuHrefForPopup`**: نفس الاستبعاد عند المسار الاحتياطي من DOM (`buildFromSidebar` في البوب-أب). |

**الخلاصة:** التكرار من **تسجيل قائمتين في PHP**؛ الإصلاح عند **`$menu`** (`yooadmin_merge_elementor_top_level_menu_duplicates`) مع **اتحاد فرعيّات** لعناصر Elementor المكررة بعد **تصفية** الروابط غير الصالحة. السايدبار والبوب-أب يعرضان **نفس الشجرة** من `yooadmCardMenus` في المسار الافتراضي؛ الاستبعاد يمنع ظهور صفحات معطّلة مثل `admin.php?page=elementor-system`.

---

## الجزء ج — قائمة تحقق سريعة للتنفيذ

- [x] **A1 / ب3:** `collector.php` — إزالة/تأمين `do_action(in_plugin_update_message-…)`؛ مراجعة `window.fetch`.
- [x] **A2 / ب1:** إزالة مسارات Ajax/REST الثابتة من JS + تمرير كامل من PHP.
- [x] **A3 / ب2:** `dashboard.php`, `admin-favicon.php`, `admin-bar-focus-toggle.php`, `assets.php`, `ui-manager.php`.
- [x] **A4:** استبدال `deactivate_plugins` في `yooadmin.php` بسياسة مقبولة + رد للمراجع.
- [x] **A5 / ب4 / ب8:** إعادة تسمية كائنات localize + تحديث JS + تصحيح اسم الكلاس إن لزم.
- [x] **A5 — دفعة globals إضافية (2026-04-05):** `YP_*` → `yooadm*` على `window`؛ `YOOADMIN_SETTINGS` / `YOOAdmin*` / `yooadmin*` (من `wp_localize_script`) → `yooadm*` في **YOOAdmin Lite** (`yooadmin/`)؛ انظر سجل «دفعة تاسعة».
- [x] **ب5:** تحديث `readme.txt` (FAQ).
- [x] **ب6 / ب7:** REST compatibility + عدم تكرار التسجيل (موصى به بقوة قبل إعادة الرفع).
- [x] **ب9:** WP 6.7 — ترجمة مبكرة (`theme-manager` + bootstrap `load_textdomain` + تعديلات داعمة) + إصلاح `$license_active` في `header.php`.
- [x] **ب10:** Elementor/إضافات مماثلة: `popup.php` + `yp-card-icons.js` + `yp-menus.js` (دمج Elementor في PHP؛ سايدبار + `yoopixelMenus` من `yooadmCardMenus` مثل البوب-أب؛ احتياطي DOM عند غياب التوطين؛ استبعاد روابط معطّلة؛ بادجات التحديثات؛ اتحاد فرعيّات Elementor المصفّاة).
- [x] **صيانة المستند:** تحديث **`docs/REVIEW_AND_SIMILAR_SCOPE.md`** مع كل دفعة تنفيذ (سجل + ب10 + «آخر تحديث»).
- [ ] **مزامنة YOOAdmin Extended (`yooadmin-extended/`):** تطبيق نفس أهداف A5/ب1–ب4/ب9/الأمان حيث ينطبق — الأسماء القديمة (`YP_*`, `YOOADMIN_SETTINGS`, …) **ما زالت موجودة هناك**؛ لا يُعد هذا البند مُغلقاً حتى تُنفَّذ مزامنة صريحة (انظر قسم «نطاق التنفيذ» أعلاه).

### تحسينات أمنية وتدقيق (دفعة 2026-04-05)

- [x] **ترخيص على `init`:** حارس في `maybe_check_license_status` — لا تشغيل على طلبات الواجهة العامة؛ يبقى `wp_doing_cron` و`WP_CLI`.
- [x] **REST `banner-notifications`:** صلاحية `manage_options` بدل `read`.
- [x] **XSS / مودال الإشعارات:** نصوص `data.text` / `data.description` تُعرض بـ `textContent` فقط (بدون `innerHTML` لمحتوى من API).
- [x] **`window.applyFilters`:** إعادة تسمية إلى `window.yooadmApplyPostsFilters` في `posts-page.js`.
- [x] **REST + مودال HTML:** `wp_kses_post` على مخرجات الإشعارات في `integration.php`؛ عرض المودال بـ `innerHTML` للمحتوى المُصرَّح من السيرفر.

---

## سجل التنفيذ (2026-04-05)

| البند | ماذا تغيّر (ملخص) |
|--------|-------------------|
| **دفعة تاسعة (بادئة `yooadm*`)** | **مرحلة 1 — `YP_*`:** `YP_LegacyNotifications` → `yooadmLegacyNotifications`؛ `YP_ICON_CHOICES` → `yooadmIconChoices`؛ `YP_AdminUtils` → `yooadmAdminUtils`؛ `YP_ServiceWorker` → `yooadmServiceWorker`؛ `YP_AdminEssential` → `yooadmAdminEssential`؛ `YP_Broadcast` → `yooadmBroadcast`؛ `__YP_FOCUS_TOGGLE_WIRED__` → `__yooadmFocusToggleWired__`؛ `__YP_SPA_GUARD_WIRED__` → `__yooadmSpaGuardWired__`؛ `YP_IS_HEAVY` → `yooadmIsHeavy` (ملفات تحت `assets/js/admin/` + `broadcast-manager.js` + `service-worker.js`). **مرحلة 2 — globals:** `YOOADMIN_SETTINGS` → `yooadmSettings` (`admin-settings.php` + `yoo-settings.js`)؛ `YOOAdminAlerts` / `YOOAdminToast` / `YOOAdminPopup` → `yooadmAlerts` / `yooadmToast` / `yooadmPopup`؛ `YOOAdminWizardNotice` / `YOOAdminWizardWidget` / `YOOAdminNotifPrefs` → `yooadmWizardNotice` / `yooadmWizardWidget` / `yooadmNotifPrefs`؛ `yooadminWelcomePopup` → `yooadmWelcomePopup`؛ `yooadminPosts` / `Pages` / `Categories` / `Tags` / `UsersBulk` / `Bar` → `yooadm*`؛ `yooadminLicense` / `yooadminWizard` (من PHP) → `yooadmLicense` / `yooadmWizard`؛ `setup-wizard.js`: كائن الوحدة `yooadmWizardModule` + بيانات `yooadmWizard`؛ `YOODashboard` → `yooadmDashboard`؛ نافذة ترخيص `yooadmPanelConnect`؛ `notifications-ui.js`: بادئة console `[yooadm Notifications]`. **لم يُغطَّ:** `yooadmin-extended` في نفس الـ commit (يُنصح بمزامنة لاحقة إن تكرار الملفات). |
| A1 | `collector.php`: إيقاف استدعاء `do_action` لخطافات `in_plugin_update_message-*`. |
| A4 | `yooadmin.php`: إزالة `deactivate_plugins` عند تعارض Extended؛ إشعار إداري + إيقاف تحميل النسخة الأساسية. |
| A2 / ب1 | `notifications-ui.js`: لا قيم افتراضية لمسارات ثابتة؛ الاعتماد على `yooadmNotifications` من PHP. `yp-admin-utilities.js`: `yooadmUtilities.settingsUrl` + `wpApiSettings.root`؛ إصلاح `yoo-settings.js` + `adminUrl` من `admin-settings.php`. |
| A3 / ب2 | `dashboard.php`: اشتراط `YOOADMIN_PLUGIN_FILE`. `admin-favicon.php`: مسارات ملفات عبر `content_url`/`home_url` بدل `ABSPATH` المباشر. `admin-bar-focus-toggle.php`: مقارنة مسار الإدارة عبر `admin_url()`. `assets.php`: `$notifications_scope` من `admin_url()` فقط؛ إصلاح ترتيب `$opts` قبل الاستخدام. `ui-manager.php`: `plugins_url` مع ملف الإضافة الرئيسي. |
| ب3 | `yp-legacy-notification-disable.js`: إزالة استبدال `window.fetch`. |
| A5 / ب4 | توحيد بادئة `yooadm*` لكائنات `wp_localize_script` ومراجع JS المقابلة (مثل `yooadmNotifications`, `yooadmRuntime`, `yooadmFocus`, …). |
| ب5 | `readme.txt`: صياغة FAQ للاتصال الخارجي الاختياري. |
| ب6 | `rest-api-compatibility.php`: GET للإعدادات بصلاحية `manage_options` + قائمة بيضاء للمفاتيح؛ دالة `yooadmin_rest_settings_allowed_keys()`. |
| ب7 | حذف `rest-api-endpoints.php` غير المحمّل (تكرار مع compatibility). |
| ب8 | `License_Type_Mapper.php` → `YOOAdmin_License_Type_Mapper`. |
| أمن (دفعة ثانية) | `class-license-manager.php`: حارس في `maybe_check_license_status` يمنع المنطق الثقيل/الشبكة على زوار الموقع؛ `rest-api-compatibility.php`: `banner-notifications` بـ `manage_options`؛ `notifications-ui.js`: مودال التفاصيل بـ `textContent` لنصوص API؛ `posts-page.js`: `yooadmApplyPostsFilters` بدل `applyFilters` على `window`. |
| أمن (دفعة ثالثة) | `integration.php`: قبل إرجاع REST (`/notifications` و`/notifications/feed`) تُمرَّر الحقول `message` / `description` / `title` عبر `wp_kses_post`؛ المودال يعرض النص بـ `innerHTML` لأن المحتوى أصبح مُصرَّحًا من السيرفر (متوافق مع مراجعي ووردبريس). |
| ب9 (WP 6.7 i18n) | `yooadmin.php`: `yooadmin_bootstrap_textdomain()` + `load_textdomain` لملف `.mo`؛ `init` مبكر لـ `load_plugin_textdomain`. `class-admin-theme-manager.php`: اسم/وصف السمة المدمجة بنصوص إنجليزية عند التسجيل (بدون `__()` في مسار التحميل المبكر). `integration.php` / `ui-integration.php`: تهيئة على `init`. `plugin-actions.php` / `external-api-guard.php` / `focus-mode.php`: تفاصيل في قسم ب9. `header.php`: `$license_active = $is_active` وتمريره لـ `wp_localize_script`. |
| ب10 (Elementor — الدفعة الأولى) | `includes/core/popup.php`: `yooadmin_merge_elementor_top_level_menu_duplicates()` بعد بناء الشجرة؛ فلتر `yooadmin_admin_menu_tree`. |
| ب10 (Elementor — دفعة إكمال 2026-04-05) | **PHP:** فرعية **فقط** من عنصر الـ hub الأساسي (`elementor`) وليس اتحاد كل الـ `$submenu`؛ إزالة فرض `dashicons-admin-customizer` حتى لا يمنع `yp-card-icons` الترطيب. **JS (`yp-card-icons.js`):** `readIconData` يدعم `<svg>` وماسك `::before`/العنصر؛ `paintIntoHolder` لنوع `mask` يطبّق `mask-image` على `.ypi-wp-bg` دون نسخ `mask-size` من `#adminmenu`؛ ربط `elementor-home` في `findNativeLiForCard`. |
| ب10 (سايد — دمج عام) | `yp-menus.js`: `buildCanonSlugByTitle` + `mergeNativeSubmenuIntoYpsItem` — دمج صفوف القائمة المكررة في YOOAdmin فقط؛ حذف `admin-menu-merge-elementor.php` (كان يعدّل `$menu` ويسبب أعطالاً). |
| ب10 (سايد — توحيد مع البوب-أب، 2026-04-05) | **`yooadmCardMenus`** يُمرَّر على **`yp-admin-core-essential`** (`assets.php`). **`syncFromNative`**: إن وُجدت `yooadmCardMenus.items` → **`feedYoopixelMenusFromCardMenus`** + **`buildSidebarFromCardMenus`** + **`hydrateExistingFromNative`**؛ وإلا الاحتياطي من DOM. **`popup.php`**: إيقاف التوطين المكرر لـ `yooadmCardMenus` على سكربت البوب-أب. |
| ب10 (قوائم — بادجات + استبعاد + Elementor، 2026-04-05) | **`yooadmin_submenu_title_and_badge`** + حقول **`badge` / `badge_kind`**؛ **`yooadmin_submenu_item_is_included`** + **`yooadmin_get_excluded_submenu_pages`**؛ **`yooadmRuntime.excludedSubmenuPages`** في **`assets.php`**؛ دمج Elementor **بالاتحاد** بعد التصفية؛ **`yp-menus.js`** / **`yp-popup.js`** (`isNavigableSubmenuHref`، **`buildFromSidebar`**). |
| ب10 (Elementor — صف Templates، 2026-04-05) | **عموماً:** **`yooadmin_merge_post_type_listing_into_prefixed_hub()`** يغطي Elementor + أي إضافة تسجّل CPT ببادئة `{hub}_`. سبب «قائمة ثانية» لـ Templates: **`$menu` منفصل** لـ `post_type=elementor_library`؛ يُدمج تحت الـ hub الذي يطابق البادئة. |
| ب10 (دمج عام للإضافات، 2026-04-05) | استبدال دمج Elementor الخاص بـ **`yooadmin_merge_duplicate_top_level_menus_by_title_family`** + **`yooadmin_merge_post_type_listing_into_prefixed_hub`**؛ المحاذاة مع **`yp-menus.js`** (`samePluginFamily` / `mergeCanonicalSlug`). |

**متبقٍ للتحقق يدوياً:** اختبار كامل مع `WP_DEBUG` (بعد ب9: لا إشعار `_load_textdomain_just_in_time` ولا تحذيرات هيدرز ناتجة عنه)؛ صفحة المقالات (فلاتر)؛ الترخيص (إن مفعّل)؛ إشعارات المودال؛ ومسار إدارة غير قياسي إن أمكن؛ **مع Elementor مفعّل:** كرت واحد، **بوب-أب + سايدبار** بنفس روابط القائمة الفرعية (مصدر `yooadmCardMenus`)، أيقونة الكرت بنفس لون/حجم باقي الكروت (ماسك/SVG).

### أين `banner-notifications` وهل YOOAdmin يستخدمه؟

- **التسجيل:** `includes/notifications/rest-api-compatibility.php` — المسار `POST /wp-json/.../yooadmin/v1/banner-notifications` (توافق قديم).
- **مسح البانرات من واجهة الإعدادات:** لا يمرّ على هذا الـ REST؛ يستخدم **AJAX** `wp_ajax_yooadmin_clear_banner_notifications` في `includes/notifications/ui-integration.php` مع `manage_options` (انظر `yoo-settings.js` + زر `#yp-clear-banner-notifications`).
- **خلاصة:** رفع صلاحية الـ REST إلى `manage_options` يوافق سلوك التطبيق الفعلي (المدير يمسح من الإعدادات) ولا يعتمد مسار الواجهة على استدعاء REST ذلك لمسح البانرات.

---

## تقرير ما بعد التنفيذ (تغطية — كود مشابه — مخاطر)

### التغطية

- **قائمة الجزء ج:** ما ورد فيها من بنود **نُفِّذ** وسُجِّل أعلاه في «سجل التنفيذ» — **على مسار Lite** (`yooadmin/`)؛ بند **مزامنة Extended** ما زال مفتوحاً.
- **الجزء د:** **لم يُنفَّذ** عن قصد (تحسينات اختيارية وليست شرط إغلاق البريد نفسه).
- أي ملاحظات **لم تُدرَج** في البريد/هذا المستند أصلاً لا تُفترض مغطاة بالكامل دون مراجعة منفصلة.

### كود مشابه قد يبقى (مراجعة لاحقة محتملة)

- **بعد دفعة 2026-04-05 (تاسعة):** لم تعد **`YP_*`** ولا **`YOOADMIN_SETTINGS`** ولا **`YOOAdminToast` / `Alerts` / `Popup`** ولا **`YOODashboard`** على `window` بالأسماء القديمة في **YOOAdmin Lite** — راجع سجل «دفعة تاسعة».
- قد يبقى توحيد إضافي **اختياري:** أسماء على `window` لم تُستهدف بعد (مثل أنماط أخرى في إضافات فرعية أو **`yooadmin-extended`** إن كان يكرر JS قديماً)؛ تعليقات الملفات و`@package`؛ ثوابت PHP مثل `YOOADMIN_SETTINGS_SLUG`.
- **تمت معالجة:** تعارض اسم `window.applyFilters` (أصبح `yooadmApplyPostsFilters`).
- **لا** يُفترض بالضرورة رفض المراجعة؛ قد يُطلب توحيد إضافي في دورة لاحقة إن ركز الفريق على كل الـ globals.

### مخاطر خلل يُراعى اختبارها

| المخاطرة | ملاحظة |
|----------|--------|
| كاش / مراجع قديمة | أي كود أو كاش يعتمد أسماء JS القديمة (`YP_Notifications`, `YOOADMIN_RUNTIME`, …) قد يتعطل حتى يُحدَّث. |
| إشعارات لا تُحمَّل | إن لم يُمرَّر `rest_url` / `ajax_url` من PHP في حالة تحميل نادرة، `notifications-ui.js` يتوقف مبكرًا. |
| نصوص تحديث الإضافات | بعد إيقاف `in_plugin_update_message-*` في المجمّع، لا تُستورد رسائل الصف من ذلك الخطاف؛ تبقى `upgrade_notice` والبدائل الافتراضية. |
| تعارض Extended | بدون تعطيل برمجي قد تظهر النسخة الأساسية «مفعّلة» في الشاشة حتى يعطّلها المستخدم يدويًا؛ الوظيفة تُدار بعدم التحميل والإشعار. |
| REST GET للإعدادات | يتطلب `manage_options` ومفتاحًا ضمن القائمة البيضاء؛ أي استدعاء قديم بصلاحية أقل سيفشل (مقصود أمنيًا). |
| ترخيص على كل الطلبات | بعد الحارس: لا يعمل `maybe_check_license_status` على الزوار؛ راقب الترخيص بعد النشر (cron/CLI/Admin). |
| ترجمة 6.7 بدون ملف `.mo` | إن لم يوجد `yooadmin-{locale}.mo`، قد يبقى اعتماد على JIT لأول `__()`؛ تجنّب أي `__()` لنطاق `yooadmin` قبل `after_setup_theme` (كما في ب9). |
| أيقونات كروت من إضافات أخرى بماسك مخصص | إن استخدمت إضافة نفس نمط Elementor (`mask` على `::before`)، يُفترض أن يغطيها مسار `readIconData` + `ypi-wp-bg`؛ إن بقي استثناء، راجع مطابقة `#toplevel_page_*` في `findNativeLiForCard`. |

---

## الجزء د — خارج نطاق “نص البريد” لكن اختياري للجودة

ما يلي ظهر في التقرير الداخلي الشامل؛ **ليس** كلّه مطلوباً لإغلاق نفس الجمل التي في البريد، لكنه يقلل مخاطر دورة مراجعة لاحقة:

- تقييد `admin_enqueue_scripts` لبعض الأصول (بحذر — لا تكسر الإشعارات/Focus على كل الإدارة).
- مراجعة أي `innerHTML` **أخرى** في الإدارة (مثلاً أدوات جاهزة، قوائم، إلخ) — مودال تفاصيل الإشعارات: المحتوى من REST يُمرَّع بـ `wp_kses_post` ثم يُعرض بـ `innerHTML`.
- توحيد خيار `convert_banners_to_notifications` إن وُجد تخزين مزدوج مع `yooadmin_options`.

---

*نهاية المستند.*
