Adminhtml& UI.
إزاي تبني في الـ admin: controllers، صلاحيات الـ ACL، الـ system config، والـ UI Components اللي بتعمل الـ grids والـ forms. الجزء اللي بيبان في أي custom module حقيقي.
جزء الأدمن في أي module بيتبني من admin routes و controllers بتورّث من Backend\App\Action، وصلاحيات بتتعرّف في acl.xml، وعناصر قايمة في menu.xml، وإعدادات في system.xml. والـ grids والـ forms بتتبني بـ UI Components معرّفة في XML ومربوطة بـ data provider، فمعظم الواجهة بتتوصف بدل ما تتكتب HTML بإيدك.
Request Flow & Routing
قبل ما تفهم الـ controllers، افهم رحلة الـ request. سؤال نظري متكرر جدًا.
من أول ما الـ URL يوصل لحد ما الصفحة ترجع، بيمر بمراحل ثابتة:
الـ frontend routes بتتحط في frontend/routes.xml، والـ admin routes في adminhtml/routes.xml تحت الـ router id بتاع admin.
<config> <router id="admin"> <route id="vendor" frontName="vendor"> <module name="Vendor_Module"/> </route> </router> </config>
Admin Controllers
الـ admin action بيختلف عن الـ frontend: بيورّث من Backend Action وبيفرض الـ ACL.
الـ admin controller بيورّث من Backend\App\Action، وبيعرّف constant اسمه ADMIN_RESOURCE اللي بيربطه بصلاحية الـ ACL.
class Index extends Backend\App\Action { // Links this action to an ACL resource const ADMIN_RESOURCE = 'Vendor_Module::view'; public function __construct( Context $context, private readonly PageFactory $resultPageFactory ) { parent::__construct($context); } public function execute() { return $this->resultPageFactory->create(); } }
ACL & Permissions
نظام الصلاحيات. بيحدد أي admin role يقدر يشوف/يعمل إيه.
بتعرّف شجرة الصلاحيات في acl.xml. الـ resources دي بتظهر في System > Permissions > User Roles عشان الـ admin يوزّعها.
<config> <acl> <resources> <resource id="Magento_Backend::admin"> <resource id="Vendor_Module::main" title="Vendor Module"> <resource id="Vendor_Module::view" title="View Logs"/> </resource> </resource> </resources> </acl> </config>
System Configuration
صفحات الإعدادات تحت Stores > Configuration. إزاي تضيف حقولك وتقراها في الكود.
الـ system.xml بيرسم الحقول في الـ admin، والـ config.xml بيحط القيم الافتراضية.
<section id="vendor_module" translate="label" sortOrder="100" showInStore="1"> <group id="general" translate="label"> <field id="enabled" type="select" translate="label" sortOrder="10"> <label>Enable Module</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> </group> </section>
public function isEnabled(): bool { return (bool) $this->scopeConfig->getValue( 'vendor_module/general/enabled', ScopeInterface::SCOPE_STORE ); }
Menu & ACL wiring
إزاي تضيف عنصر في قائمة الـ admin وتربطه بالصلاحية.
بيضيف عنصر في الـ admin sidebar، وبيربطه بـ action (action) وصلاحية (resource).
<menu> <add id="Vendor_Module::logs" title="Logs" module="Vendor_Module" parent="Magento_Backend::system" action="vendor/log/index" resource="Vendor_Module::view" sortOrder="50"/> </menu>
UI Component Grids
الجداول الحديثة في الـ admin (زي جدول الـ products). مبنية بالكامل من XML + data provider.
- listing XML — في view/adminhtml/ui_component/ بيعرّف الأعمدة والفلاتر.
- DataProvider — بيجيب الـ data (عادةً من collection أو repository via SearchResult).
- Columns — كل عمود، مع الـ actions (edit/delete) والـ filters.
<listing> <dataSource name="vendor_log_listing_data_source"> <dataProvider class="...\Ui\DataProvider\LogDataProvider" name="vendor_log_listing_data_source"> <settings> <requestFieldName>id</requestFieldName> <primaryFieldName>entity_id</primaryFieldName> </settings> </dataProvider> </dataSource> </listing>
UI Component Forms
صفحات الـ add/edit في الـ admin. نفس فكرة الـ grid: XML + DataProvider.
الـ form XML بيعرّف الحقول والـ fieldsets، والـ DataProvider بيحمّل بيانات الـ record اللي بيتعدّل ويجهّزها للحقول.
public function execute() { $data = $this->getRequest()->getPostValue(); if ($data) { $model = $this->logFactory->create(); $model->setData($data); $this->logRepository->save($model); $this->messageManager->addSuccessMessage('Saved.'); } return $this->resultRedirectFactory->create() ->setPath('*/*/'); }
اليوم التالت خلص ✓
دلوقتي تقدر تبني custom module كامل في الـ admin: من الـ routing للـ controller للـ ACL للـ config للـ grid والـ form. دي أكتر حاجة بيطلبوا منك تعملها عمليًا.
اللي جاي (آخر يوم): مراجعة سريعة، أسئلة سلوكية، وأسئلة سيناريو حقيقية للإنترفيو.
خلّصت الدرس؟علّمه عشان تتابع تقدّمك في الكورس.
أسئلة شائعة
إزاي أعمل admin controller في Magento 2؟
بتعرّف الـ route في etc/adminhtml/routes.xml تحت router id=\"admin\"، وبعدين تعمل class في Controller/Adminhtml بيورّث من Backend\App\Action. الـ class بيعرّف ADMIN_RESOURCE للصلاحية، والـ execute() بيرجّع result زي page من الـ PageFactory.
إيه دور ADMIN_RESOURCE في Magento 2؟
الـ constant ده بيربط الـ admin action بمورد ACL معيّن زي Vendor_Module::view. Magento بيتأكد أوتوماتيك إن الـ admin user عنده الصلاحية دي قبل ما ينفّذ execute()، ولو مش عنده بيرجّع 403.
ما الفرق بين system.xml و config.xml في Magento 2؟
system.xml بيرسم شكل حقول الإعدادات اللي بتظهر في Stores > Configuration، وconfig.xml بيحدد القيم الافتراضية لنفس الحقول قبل ما الـ admin يغيّرها. في الكود بتقرا القيمة النهائية بـ scopeConfig->getValue() مع الـ path زي vendor_module/general/enabled.
إزاي Magento 2 بيختار قيمة الإعداد بين default و website و store view؟
القيمة الأكثر تحديدًا هي اللي بتكسب: الـ store view بيتجاوز الـ website، والـ website بيتجاوز الـ default. ده اللي بيسمح إن كل متجر أو لغة يبقى ليها إعدادات مختلفة، وبتقرا القيمة حسب الـ scope زي ScopeInterface::SCOPE_STORE.
ليه عنصر الـ menu مش ظاهر في admin Magento 2؟
غالبًا الـ resource اللي حاطه في menu.xml مش معرّف في acl.xml، أو الـ admin role مالوش الصلاحية دي. الربط بين الـ menu والـ ACL إجباري، لأن نفس الـ ACL resource بيتستخدم في الـ controller والـ menu.xml والـ system.xml.
إزاي الـ UI Component grid بيجيب بياناته في Magento 2؟
الـ grid بيتعرّف في listing XML جوّه view/adminhtml/ui_component/، وفيه dataSource بيشاور على DataProvider. الـ DataProvider بيرجّع الـ data كـ array من collection أو repository، والـ grid بيعمل render للأعمدة والفلاتر والـ pagination أوتوماتيك.
إزاي أحفظ بيانات UI Component form في Magento 2؟
الـ form بيبعت الـ data لـ Save controller، اللي بياخدها بـ getRequest()->getPostValue() ويحطها في model جديد من الـ factory. الحفظ نفسه يكون دايمًا عن طريق الـ repository (service contract) مش $model->save() المباشر، وبعدها تضيف success message وتعمل redirect.