XOOPS Architecture
This document provides a comprehensive overview of the XOOPS system architecture, explaining how the various components work together to create a flexible and extensible content management system.
Overview
Section titled “Overview”XOOPS follows a modular architecture that separates concerns into distinct layers. The system is built around several core principles:
- Modularity: Functionality is organized into independent, installable modules
- Extensibility: The system can be extended without modifying core code
- Abstraction: Database and presentation layers are abstracted from business logic
- Security: Built-in security mechanisms protect against common vulnerabilities
System Layers
Section titled “System Layers”graph TB subgraph Presentation["🎨 Presentation Layer"] Themes["Themes"] Templates["Smarty Templates"] Blocks["Blocks"] end
subgraph Application["⚙️ Application Layer"] Modules["Modules"] Preloads["Preloads"] Controllers["Controllers"] BlockHandlers["Block Handlers"] end
subgraph Domain["📦 Domain Layer"] XoopsObject["XoopsObject"] Handlers["Object Handlers"] Criteria["Criteria System"] end
subgraph Infrastructure["🔧 Infrastructure Layer"] Database["XoopsDatabase"] Cache["Cache System"] Session["Session Manager"] Security["Security Layer"] 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:#c2185b1. Presentation Layer
Section titled “1. Presentation Layer”The presentation layer handles user interface rendering using the Smarty template engine.
Key Components:
- Themes: Visual styling and layout
- Smarty Templates: Dynamic content rendering
- Blocks: Reusable content widgets
2. Application Layer
Section titled “2. Application Layer”The application layer contains business logic, controllers, and module functionality.
Key Components:
- Modules: Self-contained functionality packages
- Handlers: Data manipulation classes
- Preloads: Event listeners and hooks
3. Domain Layer
Section titled “3. Domain Layer”The domain layer contains core business objects and rules.
Key Components:
- XoopsObject: Base class for all domain objects
- Handlers: CRUD operations for domain objects
4. Infrastructure Layer
Section titled “4. Infrastructure Layer”The infrastructure layer provides core services like database access and caching.
Request Lifecycle
Section titled “Request Lifecycle”Understanding the request lifecycle is crucial for effective XOOPS development.
XOOPS 2.5.x Page Controller Flow
Section titled “XOOPS 2.5.x Page Controller Flow”The current XOOPS 2.5.x uses a Page Controller pattern where each PHP file handles its own request. Globals ($xoopsDB, $xoopsUser, $xoopsTpl, etc.) are initialized during bootstrap and available throughout execution.
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: Bootstrap Phase (mainfile.php) Entry->>Main: include mainfile.php Main->>Kernel: Initialize Core Kernel->>DB: Create XoopsDatabase (singleton) Kernel->>User: Load Session → $xoopsUser Kernel->>Tpl: Initialize Smarty → $xoopsTpl Main-->>Entry: Globals Ready end
rect rgb(255, 250, 240) Note over Entry,Handler: Page Controller Execution Entry->>Handler: xoops_getModuleHandler('myobject') Handler->>DB: query via Criteria DB-->>Handler: Result Set Handler-->>Entry: XoopsObject[] end
rect rgb(240, 255, 240) Note over Entry,Theme: Rendering Phase 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: Complete HTML Page endKey Globals in 2.5.x
Section titled “Key Globals in 2.5.x”| Global | Type | Initialized | Purpose |
|---|---|---|---|
$xoopsDB | XoopsDatabase | Bootstrap | Database connection (singleton) |
$xoopsUser | XoopsUser|null | Session load | Current logged-in user |
$xoopsTpl | XoopsTpl | Template init | Smarty template engine |
$xoopsModule | XoopsModule | Module load | Current module context |
$xoopsConfig | array | Config load | System configuration |
1. Bootstrap Phase
Section titled “1. Bootstrap Phase”// mainfile.php is the entry pointinclude_once XOOPS_ROOT_PATH . '/mainfile.php';
// Core initialization$xoops = Xoops::getInstance();$xoops->boot();Steps:
- Load configuration (
mainfile.php) - Initialize autoloader
- Set up error handling
- Establish database connection
- Load user session
- Initialize Smarty template engine
2. Routing Phase
Section titled “2. Routing Phase”// Request routing to appropriate module$module = $GLOBALS['xoopsModule'];$controller = $module->getController();$controller->dispatch($request);Steps:
- Parse request URL
- Identify target module
- Load module configuration
- Check permissions
- Route to appropriate handler
3. Execution Phase
Section titled “3. Execution Phase”// Controller execution$data = $handler->getObjects($criteria);$xoopsTpl->assign('items', $data);Steps:
- Execute controller logic
- Interact with data layer
- Process business rules
- Prepare view data
4. Rendering Phase
Section titled “4. Rendering Phase”// Template renderinginclude XOOPS_ROOT_PATH . '/header.php';$xoopsTpl->display('db:module_template.tpl');include XOOPS_ROOT_PATH . '/footer.php';Steps:
- Apply theme layout
- Render module template
- Process blocks
- Output response
Core Components
Section titled “Core Components”XoopsObject
Section titled “XoopsObject”The base class for all data objects in XOOPS.
<?phpclass 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); }}Key Methods:
initVar()- Define object propertiesgetVar()- Retrieve property valuessetVar()- Set property valuesassignVars()- Bulk assign from array
XoopsPersistableObjectHandler
Section titled “XoopsPersistableObjectHandler”Handles CRUD operations for XoopsObject instances.
<?phpclass 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); }}Key Methods:
create()- Create new object instanceget()- Retrieve object by IDinsert()- Save object to databasedelete()- Remove object from databasegetObjects()- Retrieve multiple objectsgetCount()- Count matching objects
Module Structure
Section titled “Module Structure”Every XOOPS module follows a standard directory structure:
modules/mymodule/├── class/ # PHP classes│ ├── MyModuleItem.php│ └── MyModuleItemHandler.php├── include/ # Include files│ ├── common.php│ └── functions.php├── templates/ # Smarty templates│ ├── mymodule_index.tpl│ └── mymodule_item.tpl├── admin/ # Admin area│ ├── index.php│ └── menu.php├── language/ # Translations│ └── english/│ ├── main.php│ └── modinfo.php├── sql/ # Database schema│ └── mysql.sql├── xoops_version.php # Module info├── index.php # Module entry└── header.php # Module headerDependency Injection Container
Section titled “Dependency Injection Container”Modern XOOPS development can leverage dependency injection for better testability.
Basic Container Implementation
Section titled “Basic Container Implementation”<?phpclass 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]); }}PSR-11 Compatible Container
Section titled “PSR-11 Compatible Container”<?phpnamespace 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]); }}Usage Example
Section titled “Usage Example”<?php// Service registration$container = new XoopsDependencyContainer();
$container->register('database', function () { return XoopsDatabaseFactory::getDatabaseConnection();});
$container->register('userHandler', function ($c) { return new XoopsUserHandler($c->resolve('database'));});
// Service resolution$userHandler = $container->resolve('userHandler');$user = $userHandler->get($userId);Extension Points
Section titled “Extension Points”XOOPS provides several extension mechanisms:
1. Preloads
Section titled “1. Preloads”Preloads allow modules to hook into core events.
<?phpclass MymoduleCorePreload extends XoopsPreloadItem{ public static function eventCoreHeaderEnd($args) { // Execute when header processing ends }
public static function eventCoreFooterStart($args) { // Execute when footer processing starts }}2. Plugins
Section titled “2. Plugins”Plugins extend specific functionality within modules.
<?phpclass MymoduleNotifyPlugin{ public function onItemCreate($item) { // Send notification when item is created }}3. Filters
Section titled “3. Filters”Filters modify data as it passes through the system.
<?php// Content filter example$myts = MyTextSanitizer::getInstance();$content = $myts->displayTarea($rawContent, 1, 1, 1);Best Practices
Section titled “Best Practices”Code Organization
Section titled “Code Organization”-
Use namespaces for new code:
namespace XoopsModules\MyModule;class Item extends \XoopsObject{// Implementation} -
Follow PSR-4 autoloading:
{"autoload": {"psr-4": {"XoopsModules\\MyModule\\": "class/"}}} -
Separate concerns:
- Domain logic in
class/ - Presentation in
templates/ - Controllers in module root
- Domain logic in
Performance
Section titled “Performance”- Use caching for expensive operations
- Lazy load resources when possible
- Minimize database queries using criteria batching
- Optimize templates by avoiding complex logic
Security
Section titled “Security”- Validate all input using
Xmf\Request - Escape output in templates
- Use prepared statements for database queries
- Check permissions before sensitive operations
Related Documentation
Section titled “Related Documentation”- Design-Patterns - Design patterns used in XOOPS
- Database Layer - Database abstraction details
- Smarty Basics - Template system documentation
- Security Best Practices - Security guidelines
#xoops #architecture #core #design #system-design