تخطَّ إلى المحتوى

معمارية XOOPS

يوفر هذا المستند نظرة شاملة على معمارية نظام XOOPS، مع شرح كيفية عمل المكونات المختلفة معاً لإنشاء نظام إدارة محتوى مرن وقابل للتوسع.

يتبع XOOPS معمارية معيارية تفصل الاهتمامات إلى طبقات متميزة. يتم بناء النظام حول عدة مبادئ أساسية:

  • المعيارية: يتم تنظيم الوظائف في وحدات مستقلة قابلة للتثبيت
  • قابلية التوسع: يمكن توسيع النظام بدون تعديل الكود الأساسي
  • التجريد: تم فصل قاعدة البيانات وطبقات التقديم عن منطق العمل
  • الأمان: آليات أمان مدمجة للحماية من الثغرات الشائعة
graph TB
subgraph Presentation["🎨 طبقة العرض"]
Themes["المواضيع"]
Templates["قوالب Smarty"]
Blocks["الكتل"]
end
subgraph Application["⚙️ طبقة التطبيق"]
Modules["الوحدات"]
Preloads["التحميل المسبق"]
Controllers["متحكمات"]
BlockHandlers["معالجات الكتل"]
end
subgraph Domain["📦 طبقة المجال"]
XoopsObject["XoopsObject"]
Handlers["معالجات الكائنات"]
Criteria["نظام المعايير"]
end
subgraph Infrastructure["🔧 طبقة البنية الأساسية"]
Database["XoopsDatabase"]
Cache["نظام الذاكرة المؤقتة"]
Session["مدير الجلسات"]
Security["طبقة الأمان"]
end
Presentation --> Application
Application --> Domain
Domain --> Infrastructure
style Presentation fill:#e8f5e9,stroke:#388e3c
style Application fill:#e3f2fd,stroke:#1976d2
style Domain fill:#fff3e0,stroke:#f57c00
style Infrastructure fill:#fce4ec,stroke:#c2185b

تتعامل طبقة العرض مع عرض واجهة المستخدم باستخدام محرك قوالب Smarty.

المكونات الرئيسية:

  • المواضيع: تصميم الجمال والتخطيط
  • قوالب Smarty: عرض المحتوى الديناميكي
  • الكتل: أداة إعادة استخدام محتوى

تحتوي طبقة التطبيق على منطق الأعمال والمتحكمات ووظائف الوحدات.

المكونات الرئيسية:

  • الوحدات: حزم الوظائف المستقلة
  • المعالجات: فئات معالجة البيانات
  • التحميل المسبق: مستمعي الأحداث والخطاطيف

تحتوي طبقة المجال على كائنات الأعمال الأساسية والقواعد.

المكونات الرئيسية:

  • XoopsObject: فئة أساسية لجميع كائنات المجال
  • المعالجات: عمليات CRUD لكائنات المجال

توفر طبقة البنية الأساسية خدمات أساسية مثل الوصول إلى قاعدة البيانات والتخزين المؤقت.

يعتبر فهم دورة حياة الطلب حاسماً لتطوير XOOPS الفعال.

تدفق متحكم الصفحة في XOOPS 2.5.x

Section titled “تدفق متحكم الصفحة في XOOPS 2.5.x”

يستخدم XOOPS 2.5.x الحالي نمط متحكم الصفحة حيث يتعامل كل ملف PHP مع طلبه الخاص. يتم تهيئة المتغيرات العامة ($xoopsDB، $xoopsUser، $xoopsTpl، إلخ) أثناء التمهيد وتتوفر في جميع أنحاء التنفيذ.

sequenceDiagram
participant Browser
participant Entry as modules/mymod/index.php
participant Main as mainfile.php
participant Kernel as XOOPS Kernel
participant DB as $xoopsDB
participant User as $xoopsUser
participant Handler as MyObjectHandler
participant Tpl as $xoopsTpl (Smarty)
participant Theme
Browser->>Entry: GET /modules/mymod/index.php
rect rgb(240, 248, 255)
Note over Entry,User: مرحلة التمهيد (mainfile.php)
Entry->>Main: include mainfile.php
Main->>Kernel: تهيئة النواة
Kernel->>DB: إنشاء XoopsDatabase (singleton)
Kernel->>User: تحميل الجلسة → $xoopsUser
Kernel->>Tpl: تهيئة Smarty → $xoopsTpl
Main-->>Entry: المتغيرات العامة جاهزة
end
rect rgb(255, 250, 240)
Note over Entry,Handler: تنفيذ متحكم الصفحة
Entry->>Handler: xoops_getModuleHandler('myobject')
Handler->>DB: الاستعلام عبر Criteria
DB-->>Handler: مجموعة النتائج
Handler-->>Entry: XoopsObject[]
end
rect rgb(240, 255, 240)
Note over Entry,Theme: مرحلة العرض
Entry->>Tpl: $xoopsTpl->assign('items', $objects)
Entry->>Theme: include header.php
Entry->>Tpl: $xoopsTpl->display('mymod_index.tpl')
Entry->>Theme: include footer.php
Theme-->>Browser: صفحة HTML كاملة
end

المتغيرات العامة الرئيسية في 2.5.x

Section titled “المتغيرات العامة الرئيسية في 2.5.x”
المتغير العامالنوعالمهيأةالغرض
$xoopsDBXoopsDatabaseالتمهيداتصال قاعدة البيانات (singleton)
$xoopsUserXoopsUser|nullتحميل الجلسةالمستخدم الحالي المسجل دخول
$xoopsTplXoopsTplتهيئة النموذجمحرك قوالب Smarty
$xoopsModuleXoopsModuleتحميل الوحدةسياق الوحدة الحالي
$xoopsConfigarrayتحميل التكوينتكوين النظام
// mainfile.php هو نقطة الدخول
include_once XOOPS_ROOT_PATH . '/mainfile.php';
// تهيئة النواة
$xoops = Xoops::getInstance();
$xoops->boot();

الخطوات:

  1. تحميل التكوين (mainfile.php)
  2. تهيئة محمل التحميل التلقائي
  3. إعداد معالجة الأخطاء
  4. إنشاء اتصال قاعدة البيانات
  5. تحميل جلسة المستخدم
  6. تهيئة محرك قوالب Smarty
// توجيه الطلب إلى الوحدة المناسبة
$module = $GLOBALS['xoopsModule'];
$controller = $module->getController();
$controller->dispatch($request);

الخطوات:

  1. تحليل عنوان URL للطلب
  2. تحديد الوحدة الهدف
  3. تحميل تكوين الوحدة
  4. التحقق من الأذونات
  5. التوجيه إلى المعالج المناسب
// تنفيذ المتحكم
$data = $handler->getObjects($criteria);
$xoopsTpl->assign('items', $data);

الخطوات:

  1. تنفيذ منطق المتحكم
  2. التفاعل مع طبقة البيانات
  3. معالجة قواعد الأعمال
  4. إعداد بيانات العرض
// عرض النموذج
include XOOPS_ROOT_PATH . '/header.php';
$xoopsTpl->display('db:module_template.tpl');
include XOOPS_ROOT_PATH . '/footer.php';

الخطوات:

  1. تطبيق تخطيط المظهر
  2. عرض نموذج الوحدة
  3. معالجة الكتل
  4. استجابة الإخراج

فئة أساسية لجميع كائنات البيانات في XOOPS.

<?php
class MyModuleItem extends XoopsObject
{
public function __construct()
{
$this->initVar('id', XOBJ_DTYPE_INT, null, false);
$this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255);
$this->initVar('content', XOBJ_DTYPE_TXTAREA, '', false);
$this->initVar('created', XOBJ_DTYPE_INT, time(), false);
}
}

الطرق الرئيسية:

  • initVar() - تحديد خصائص الكائن
  • getVar() - استرجاع قيم الخصائص
  • setVar() - تعيين قيم الخصائص
  • assignVars() - التخصيص الجماعي من المصفوفة

يتعامل مع عمليات CRUD لكائنات XoopsObject.

<?php
class MyModuleItemHandler extends XoopsPersistableObjectHandler
{
public function __construct(\XoopsDatabase $db)
{
parent::__construct($db, 'mymodule_items', 'MyModuleItem', 'id', 'title');
}
public function getActiveItems($limit = 10)
{
$criteria = new CriteriaCompo();
$criteria->add(new Criteria('status', 1));
$criteria->setSort('created');
$criteria->setOrder('DESC');
$criteria->setLimit($limit);
return $this->getObjects($criteria);
}
}

الطرق الرئيسية:

  • create() - إنشاء نموذج كائن جديد
  • get() - استرجاع الكائن حسب المعرف
  • insert() - حفظ الكائن في قاعدة البيانات
  • delete() - إزالة الكائن من قاعدة البيانات
  • getObjects() - استرجاع كائنات متعددة
  • getCount() - عد الكائنات المطابقة

تتبع كل وحدة XOOPS هيكل دليل قياسي:

modules/mymodule/
├── class/ # فئات PHP
│ ├── MyModuleItem.php
│ └── MyModuleItemHandler.php
├── include/ # ملفات التضمين
│ ├── common.php
│ └── functions.php
├── templates/ # قوالب Smarty
│ ├── mymodule_index.tpl
│ └── mymodule_item.tpl
├── admin/ # منطقة الإدارة
│ ├── index.php
│ └── menu.php
├── language/ # الترجمات
│ └── english/
│ ├── main.php
│ └── modinfo.php
├── sql/ # مخطط قاعدة البيانات
│ └── mysql.sql
├── xoops_version.php # معلومات الوحدة
├── index.php # دخول الوحدة
└── header.php # رأس الوحدة

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

<?php
class XoopsDependencyContainer
{
private array $services = [];
public function register(string $name, callable $factory): void
{
$this->services[$name] = $factory;
}
public function resolve(string $name): mixed
{
if (!isset($this->services[$name])) {
throw new \InvalidArgumentException("Service not found: $name");
}
$factory = $this->services[$name];
if (is_callable($factory)) {
return $factory($this);
}
return $factory;
}
public function has(string $name): bool
{
return isset($this->services[$name]);
}
}
<?php
namespace Xmf\Di;
use Psr\Container\ContainerInterface;
class BasicContainer implements ContainerInterface
{
protected array $definitions = [];
public function set(string $id, mixed $value): void
{
$this->definitions[$id] = $value;
}
public function get(string $id): mixed
{
if (!$this->has($id)) {
throw new \InvalidArgumentException("Service not found: $id");
}
$entry = $this->definitions[$id];
if (is_callable($entry)) {
return $entry($this);
}
return $entry;
}
public function has(string $id): bool
{
return isset($this->definitions[$id]);
}
}
<?php
// تسجيل الخدمة
$container = new XoopsDependencyContainer();
$container->register('database', function () {
return XoopsDatabaseFactory::getDatabaseConnection();
});
$container->register('userHandler', function ($c) {
return new XoopsUserHandler($c->resolve('database'));
});
// حل الخدمة
$userHandler = $container->resolve('userHandler');
$user = $userHandler->get($userId);

يوفر XOOPS عدة آليات توسع:

يسمح التحميل المسبق للوحدات بربط أحداث النواة.

modules/mymodule/preloads/core.php
<?php
class MymoduleCorePreload extends XoopsPreloadItem
{
public static function eventCoreHeaderEnd($args)
{
// تنفيذ عند انتهاء معالجة الرأس
}
public static function eventCoreFooterStart($args)
{
// تنفيذ عند بدء معالجة التذييل
}
}

تمتد الإضافات البرمجية الوظائف المحددة داخل الوحدات.

modules/mymodule/plugins/notify.php
<?php
class MymoduleNotifyPlugin
{
public function onItemCreate($item)
{
// إرسال إشعار عند إنشاء عنصر
}
}

تعدل المرشحات البيانات أثناء مرورها عبر النظام.

<?php
// مثال على مرشح المحتوى
$myts = MyTextSanitizer::getInstance();
$content = $myts->displayTarea($rawContent, 1, 1, 1);
  1. استخدم الأنماط البرمجية للكود الجديد:

    namespace XoopsModules\MyModule;
    class Item extends \XoopsObject
    {
    // التنفيذ
    }
  2. اتبع التحميل التلقائي PSR-4:

    {
    "autoload": {
    "psr-4": {
    "XoopsModules\\MyModule\\": "class/"
    }
    }
    }
  3. افصل الاهتمامات:

    • منطق المجال في class/
    • العرض في templates/
    • المتحكمات في جذر الوحدة
  1. استخدم التخزين المؤقت للعمليات المكلفة
  2. حمل الموارد بكسل عند الإمكان
  3. قلل استعلامات قاعدة البيانات باستخدام دفعات معايير
  4. حسّن النماذج بتجنب منطق معقد
  1. تحقق من جميع المدخلات باستخدام Xmf\Request
  2. هروب الإخراج في النماذج
  3. استخدم بيانات معدة مسبقاً لاستعلامات قاعدة البيانات
  4. تحقق من الأذونات قبل العمليات الحساسة

#xoops #معمارية #core #تصميم #نظام-التصميم