Skip to content

MelisMarketPlace

متجر وحدات داخل الواجهة الخلفية لاكتشاف وحدات Melis Platform وتنزيلها وتحديثها وإزالتها، ويُقدَّم الآن كفهرس React أصلي. الحزمة melisplatform/melis-marketplace.

الغرض

MelisMarketPlace هو متجر الوحدات في الواجهة الخلفية: فهو يسرد كل حزمة منشورة على خادم Melis Packagist، ويقارن كل إصدار مُثبَّت بأحدث إصدار منشور، ويتيح للمسؤول تنزيل الوحدات أو تحديثها أو إزالتها — وتثبيت منتجات المواقع الكاملة — دون مغادرة الواجهة الخلفية. وهو يستدعي MelisComposerService (melis-composerdeploy) للقيام بعمل Composer الفعلي، ويقرأ حالة الوحدة ويبدّلها عبر MelisAssetManagerModulesService (melis-asset-manager).

هناك ست وحدات أساسية — MelisCore, MelisEngine, MelisFront, MelisAssetManager, MelisComposerDeploy, MelisDbDeploy — مُدرجة كاستثناءات (مُعفاة) ولا تُعرَض أبدًا للتنزيل أو التحديث أو الإزالة من المتجر.

في الواجهة الخلفية بنسخة v6 المبنية على React (/melis-react) تُوفِّر الأداة لبِنة React كاملة أصلية: تُكتَب قائمة الفهرس وتفاصيل كل حزمة بلغة React وتقرأ من react-api بصيغة JSON مملوكة للوحدة. أما آلية التثبيت / التحديث / الإزالة (Composer وdbdeploy والربط/فك الربط) فتظل دون تغيير ولا تزال تعمل على جانب الخادم عبر المتحكّم القديم.

تفعيلها

أضِف إلى config/melis.module.load.php:

php
return [
    'MelisMarketPlace',
];

تتطلّب melisplatform/melis-core: ^5.1 وPHP ^8.1|^8.3. تُسجِّل الوحدة راية dbdeploy: true بحيث تُطبَّق أي تعديلات على قاعدة البيانات تشحنها الوحدة عند أول تحميل. لا تظهر لبِنة React إلا عندما تكون MelisMarketPlace موجودة في config/melis.module.load.php.

تُهيَّأ نقطة نهاية Packagist البعيدة في config/app.interface.php ضمن melismarketplace_toolstree_section/datas/melis_packagist_server (الافتراضي http://marketplace.melisplatform.com/melis-packagist).

الواجهة الخلفية بـ React

الموقع. الشريط الجانبي الأيسر ← Market Place (أيقونة عربة التسوّق)؛ يُفتَح كعلامة تبويب علوية باسم Market Place. قيمة route في البيان هي /melis-marketplace، وforwardKeyMelisMarketPlace/MelisMarketPlace يربط عقدة القائمة القديمة بها.

الفهرس (القائمة). شبكة قابلة للبحث من بطاقات الوحدات (صورة الغلاف، شعار المجموعة، العنوان، شارة الإصدار، عدد التنزيلات، وشارات Installed / Update-available أو زر Download). أعلى الشبكة توجد ثلاث بطاقات مؤشرات أداء رئيسية (KPI) (Packages / Installed / Updates available)، وصندوق بحث، ومُحدِّد ترتيب (Downloads / Date added / Name)، وزر Reset filters، ومُرشِّح المجموعة (All groups · Core · Cms · Marketing · Commerce · Sites)، ومُبدِّل Bundles، وزر تحديث (↻)، ومُبدِّل New / Old. تُحمِّل الشبكة المزيد أثناء التمرير (تمرير لا نهائي). يعرض شريط جانبي أيمن "Want your module listed?" و"Most downloaded packages".

فهرس Market Place بـ React: بطاقات مؤشرات الأداء الرئيسية، والبحث، والترتيب، ومُرشِّحات المجموعة، وشبكة بطاقات الوحدات مع شريط جانبي "Most downloaded packages"

عرض المنتج (التفاصيل). يفتح النقر على بطاقة عرض تفاصيل بـ React كاملة (دون إعادة تحميل الصفحة): لافتة بارزة (شعار المجموعة، العنوان، شارات الحالة، أزرار الإجراءات)، ومعرض صور (شريط تمرير + عرض مكبَّر بملء الشاشة)، والوصف، ولوحة Additional information (أحدث إصدار، والإصدار الحالي إن كان مُثبَّتًا، وGitHub، وPackagist، واسم الحزمة، والتنزيلات). يُعيد زر ← back إلى القائمة، التي تظل مركَّبة بحيث يُحفَظ البحث / المُرشِّحات / موضع التمرير. لا توجد علامات تبويب فرعية مضيفة — إذ يكون الانتقال بين القائمة والتفاصيل ⇄ حالةً داخلية، فتستخدم اللبِنة الواحدة علامة تبويب مضيفة واحدة بالضبط.

عرض المنتج بـ React لوحدة: لافتة بارزة مع شارات الحالة وأزرار الإجراءات، ومعرض صور، والوصف، ولوحة Additional information

مُبدِّل New / Old. يمكن للقائمة التبديل بين واجهة React (New، الافتراضية) والأداة الكلاسيكية المعروضة داخل إطار iframe (Old، /melis/react-tool-page?key=melis_market_place_tool_display). على نوافذ العرض الضيّقة يصبح المُبدِّل مقتصرًا على الأيقونة.

تعتمد أزرار الإجراءات على حالة الحزمة وعلى صلاحيات المُستدعي:

الزريُعرَض عندماالتأثير
Downloadالوحدة غير مُثبَّتةجلب عبر Composer ← dbdeploy ← تفعيل
Updateمُثبَّتة وneed_updateنفس عملية Composer على إصدار متأخّر
Removeمُثبَّتة وغير مُعفاةإلغاء التثبيت (مُعطَّل إذا اعتمدت عليها وحدات أخرى)
Privateحزمة خاصة/مقفلةلوحة اتصال؛ يجب شراؤها

يفتح كل إجراء نافذة Manage منبثقة بها وحدة تحكّم تقدُّم حيّة تبثّ مُخرَجات Composer / dbdeploy، ثم تعرض Activate module / Reload. إذا تعذَّر الوصول إلى خادم Packagist (marketAccessible = false) فإن واجهة React تُعطِّل التصفّح لكنها تُبقي الهيكل قائمًا.

لبِنة React

لبِنة React كاملة أصلية مبنية باستخدام Vite (IIFE؛ مع تصدير React / ReactDOM / react-router-dom إلى المتغيّرات العامة للمضيف). المصادر في ui-react/src/، وتُبنى إلى public/ui-react/brick.js بجوار brick.manifest.json.

حقل البيانالقيمة
idmarketplace (يجب أن يطابق المُعرِّف المُسجَّل في brick.tsx)
route/melis-marketplace
labelMarket Place
forwardKeyMelisMarketPlace/MelisMarketPlace
melisKeymelis_market_place_tool_display
entrybrick.js
persistenttrue
subTabsغائب — الانتقال بين القائمة والتفاصيل ⇄ حالة openId داخلية

بما أن قسم قائمة Market Place عقدة قابلة للنقر مباشرةً / is_parent_tool، فإن المفتاح الحامل للصلاحيات ومفتاح منطقة البيان هما نفسه (melis_market_place_tool_display). لا يمكن للبِنة استيراد وحدات المضيف، لذا فهي تستخدم أنماطًا مضمّنة + متغيّرات CSS للسمة وقاموسًا {fr,en} داخل الملف مدفوعًا بلغة المضيف (melis-ui-lang / melis-ui-locale في localStorage). تطلب البطاقات والمعرض لقطات شاشة React أولًا مع وضع عنوان URL للصورة القديمة في data-legacy، مع الرجوع إليها عند الخطأ.

الملفات الرئيسية (ui-react/src/): brick.tsx (يُسجِّل id: 'marketplace')، وMarketPlacePage.tsx (القائمة + التفاصيل + نافذة الإدارة المنبثقة)، وViewToggle.tsx (مُبدِّل New/Old)، وmarketplace-api.ts (عميل API للقراءة فقط)، وshared/useCaps.ts / shared/useDebounce.ts / shared/useIsNarrow.ts.

واجهة React البرمجية (React API)

تُعلَن مسارات الفهرس للقراءة فقط في config/module.config.php، مُتداخلةً تحت مسار application-MelisMarketPlace (الأساس /melis/MelisMarketPlace/react-api) — مملوكة للوحدة، لا تحت عقدة melis-react-api المشتركة. المتحكّم: MelisMarketPlace\Controller\MelisMarketPlaceReactApiController (الاسم المستعار القابل للاستدعاء MelisMarketPlace\Controller\MelisMarketPlaceReactApi). العقد { success, data, error }؛ وكل عملية جلب ترسل X-Requested-With: XMLHttpRequest وcredentials: 'include'.

الطريقة والعنوانالإجراءالغرض
GET …/react-api/packagespackagesالقائمة (page, limit, search, group, orderBy, order, bundle) ← {items, page, pageCount, limit, marketAccessible}
GET …/react-api/packages/:idgetتفاصيل حزمة واحدة (images, currentVersion, isExempted, versionStatus…)
GET …/react-api/groupsgroupsمجموعات الحزم ← {groups, marketAccessible}
GET …/react-api/statsstatsمؤشرات الأداء الرئيسية {total, installed, needUpdate, marketAccessible}
GET …/react-api/statusstatusحالة إصدار كل وحدة (need_update / up_to_date / in_advance)

كل إجراء قراءة محميّ بواسطة denyUnlessAccess() — المصادقة (MelisCoreAuth::hasIdentity) وMelisCoreRights::canAccess('melis_market_place_tool_display')، مع إرجاع 401 / 403 — فلا تُعدّ واجهة JSON البرمجية بابًا خلفيًا. يُعيد المتحكّم استخدام MelisMarketPlaceService (compareLocalVersionFromRepo، وتهيئة أحدث إصدار مسبقًا) وMelisAssetManagerModulesService (الإصدارات المُثبَّتة / قائمة الوحدات) ويقرأ نقاط نهاية Packagist بصيغة JSON، تمامًا كالأداة القديمة.

الإجراءات المُعدِّلة ليس لها مسار في react-api. يُنفَّذ التنزيل / التحديث / الإزالة أصليًا بواسطة ManageModal، الذي يُعيد تشغيل تنسيق JavaScript القديم باستدعاء المتحكّم القديم للوحدة مباشرةً (/melis/MelisMarketPlace/MelisMarketPlace/…): melisMarketPlaceProductDo (وحدة تحكّم مبثوثة)، وreDumpAutoload، وexecDbDeploy، وplugModule / unplugModule، وexecuteComposerScripts، وgetSetupModuleForm، وactivateModule، وisPackageDirectoryRemovable، وchangePackageDirectoryPermission، وgetModuleTables، وexportTables، إضافةً إلى /melis/MelisCore/Modules/getDependents لأجل فحص تبعيّات الإزالة.

الصلاحيات

مُعلَنة في config/react.capabilities.php، ومدموجة تحت melisReactToolCapabilities بواسطة MelisMarketPlace\Module::getConfig(). مفتاحها هو نفس melisKey المستخدم في البيان وحارس الوصول (melis_market_place_tool_display)، بما أن القسم قابل للنقر مباشرةً:

melis_market_place_tool_display
└─ actions: list · download · remove

list = تصفّح الشبكة؛ download = جلب Composer الذي يُثبِّت (Download) ويُحدِّث (Update) معًا؛ remove = إلغاء التثبيت. هذه بوّابات خاصة بـ React فقط (السماح افتراضيًا، تصريحية): يفرض المتحكّم الوصول فقط (denyUnlessAccess)، ولا يستدعي denyUnlessCan. في React تقرأها اللبِنة عبر useCaps('melis_market_place_tool_display') — يُبوِّب can('list') الشبكة، وcan('download') أزرار Download / Update، وcan('remove') زر Remove (المخفيّ أيضًا للوحدات المُعفاة).

الخدمات الرئيسية

الاسم المستعار للخدمةالدور
MelisMarketPlaceServiceمقارنة الإصدارات، والربط/فك الربط، وإرسال نموذج ما بعد الإعداد لكل وحدة.
MelisMarketPlaceSiteServiceإنشاء موقع ويب كامل من حزمة melisplatform-site.

MelisMarketPlaceService

يمتدّ من MelisGeneralService.

php
$mp = $serviceManager->get('MelisMarketPlaceService');

// Compare installed vs latest — returns one of the constants below.
$status = $mp->compareLocalVersionFromRepo('MelisCmsSlider', 'v5.1.3');
// MelisMarketPlaceService::NEED_UPDATE  (-1)
// MelisMarketPlaceService::UP_TO_DATE   (1)
// MelisMarketPlaceService::IN_ADVANCE   (2)  — running a dev-… build

// Toggle a module on/off (rewrites the active-module loader via asset-manager).
$mp->plugModule('MelisCmsSlider');
$mp->unplugModule('MelisCmsSlider');

يُطلِق compareLocalVersionFromRepo() زوج الأحداث melismarketplace_compare_local_version_from_repo_start / …_end بحيث يمكن للمستمِعين تجاوز الحالة المحسوبة.

اصطلاح ما بعد الإعداد لكل وحدة. يمكن للوحدة أن تشحن MelisSetupPostDownloadController و/أو MelisSetupPostUpdateController في مساحة الأسماء Controller\ الخاصة بها، مع كشف $showOnMarketplacePostSetup = true والإجراءات getFormAction وvalidateFormAction وsubmitAction. يُحوِّل MarketPlace إليها لعرض نموذج الإعداد ومعالجته.

MelisMarketPlaceSiteService

يمتدّ من MelisGeneralService. يُنشئ موقع ويب كاملًا من حزمة melisplatform-site: يُنشئ صفوف melis_cms_site / الصفحة الرئيسية / اللغات، ويُخصِّص نطاقات جديدة من page-id وplatform-id وtemplate-id، ويُنشئ جداول CMS الخاصة بالوحدة عبر Support\MelisMarketPlaceCmsTables / Support\MelisMarketPlaceSiteInstall.

php
$site = $serviceManager->get('MelisMarketPlaceSiteService');
$site->marketplaceInstallSite($request);   // reads POST: name, scheme, domain, module, action

استثناءات مُصنَّفة (في src/Exception/): EmptySiteException، وPlatformIdMaxRangeReachedException، وTemplateIdMaxRangeReachedException، وArrayKeyNotFoundException، وFileNotFoundException.

الأداة القديمة (عرض Old)

تظل الأداة الكلاسيكية متاحة خلف مُبدِّل New/Old ولا تزال تملك التدفّق المُعدِّل. melisMarketPlaceProductDoAction() هي نقطة النهاية الوحيدة لإجراءات الفهرس: فهي تُطلِق melis_marketplace_product_do_start، وتُبدِّل بحسب الإجراء (MelisComposerService::DOWNLOAD / UPDATE / REMOVE)، ثم تُطلِق melis_marketplace_product_do_finish لتوجيه ملاحظات flash-messenger. قبل الإزالة، تمرّ على تبعيّات الوحدة المستهدفة، وتبعيّات كل الوحدات الأخرى النشطة، وكتلة require في composer.json الخاص بجذر المشروع، لمنع إزالة تبعيّة مشتركة.

يتحكّم فحصان في قابلية استخدام المتجر (كلاهما في MelisMarketPlaceController):

  • isMarketplaceAccessible() — ما إذا كان خادم Packagist قابلًا للوصول وكانت الميزة مُفعَّلة.
  • allowUpdate() — يقرأ melis_core_platform.plf_update_marketplace للمنصّة الحالية (متغيّر البيئة MELIS_PLATFORM)؛ يمكن للمنصّة التي فيها plf_update_marketplace = 0 التصفّح لكن ليس التنزيل أو التحديث.

يتولّى MelisSetupController معالجة مسار /MelisMarketPlace/setup المستقل (إعداد كل وحدة خارج شجرة واجهة الواجهة الخلفية).

الأحداث

الحدثيُطلِقهالغرض
melismarketplace_compare_local_version_from_repo_start / _endcompareLocalVersionFromRepoربط نتيجة حالة الإصدار المحسوبة أو تجاوزها.
melis_marketplace_product_do_startmelisMarketPlaceProductDoقبل إجراء تنزيل أو تحديث أو إزالة.
melis_marketplace_product_do_finishmelisMarketPlaceProductDoبعد الإجراء — يوجّه ملاحظات flash-messenger.

جداول قاعدة البيانات

لا تُعرِّف MelisMarketPlace أي جداول خاصة بها. عندما تشحن وحدة مُنزَّلة تعديلات على قاعدة البيانات، تُطبَّق عبر execDbDeployAction() (melis-dbdeploy). أما عمليات تثبيت منتجات المواقع فتكتب في جداول CMS الموجودة أصلًا للمنصّة (المُخصَّصة عبر MelisMarketPlaceSiteService).

الملفات الرئيسية

الموضوعالمسار
بيان الوحدةvendor/melisplatform/melis-marketplace/composer.json
المسارات / الخدمات / react-api / المتحكّماتvendor/melisplatform/melis-marketplace/config/module.config.php
صلاحيات Reactvendor/melisplatform/melis-marketplace/config/react.capabilities.php
شجرة الأدوات، وأيقونة الرأس، وتهيئة Packagistvendor/melisplatform/melis-marketplace/config/app.interface.php
متحكّم واجهة React البرمجيةvendor/melisplatform/melis-marketplace/src/Controller/MelisMarketPlaceReactApiController.php
المتحكّم الرئيسي (القديم)vendor/melisplatform/melis-marketplace/src/Controller/MelisMarketPlaceController.php
خدمة التثبيت/التحديث/الربطvendor/melisplatform/melis-marketplace/src/Service/MelisMarketPlaceService.php
خدمة تثبيت المواقعvendor/melisplatform/melis-marketplace/src/Service/MelisMarketPlaceSiteService.php
مصادر لبِنة Reactvendor/melisplatform/melis-marketplace/ui-react/src/
اللبِنة المبنيّة + البيانvendor/melisplatform/melis-marketplace/public/ui-react/
الاستثناءاتvendor/melisplatform/melis-marketplace/src/Exception/

انظر أيضًا: melis-composerdeploy · melis-asset-manager · melis-dbdeploy · melis-core