Festi Framework Architecture
Overview
Festi Framework is a modular PHP framework designed for building flexible, plugin-based web applications. It follows a well-structured architecture that separates concerns and promotes reusable code through a plugin system.
Core Components
Every Festi Framework project consists of these essential components:
1. Core
The core provides fundamental functionality including:
- Database Access: Abstraction layer for database operations
- Configuration Management: Loading and managing application settings
- Plugin System: Infrastructure for loading and managing plugins
- Security Features: Input validation, output sanitization, and authentication foundations
- Error Handling: Comprehensive error catching and reporting
2. System Plugin
The system plugin serves as a foundation for all other plugins and provides:
- Base Controllers: Abstract controllers that other controllers can extend
- Request Handling: Processing HTTP requests and routing them to appropriate plugins
- Authentication: User authentication and session management
- Access Control: Permission management and role-based access control
- Admin Interfaces: Core admin panel functionality
- System Events: Event dispatching and handling for core system events
3. Plugins
Plugins are modular components that extend the framework with specific features:
- Structure: Each plugin follows a standard directory structure:
domain/
: Contains domain-specific classes that represent the business logic and entities of each context. These classes align with the domain model and encapsulate the core functionality of each business domain, promoting better organization and separation of concerns.install/
: Contains files used for plugin installation such as database dumps, static files, and configuration templatesstatic/
: Contains JavaScript and other asset filestblDfs/
: Contains Data Grid Store definition schemestemplates/
: Contains view templatestests/
: Contains UNIT tests for the plugininit.php
: Initialization file for the pluginREADME.md
: Base documentation about the pluginPluginNameObject.php
: DataAccessObject for working with the data access layer-
PluginNamePlugin.php
: Main Facade for implementing the plugin logic -
Registration: Plugins register with the core through a standardized mechanism
- Dependencies: Plugins can define dependencies on other plugins
- Hooks: Plugins can implement hooks to modify core functionality
You can find more details in Plugins
4. Templates
Templates control the presentation layer:
- Theme System: Support for multiple themes
- Layout Management: Defining page layouts and structure
- Asset Management: Handling CSS, JavaScript, and media files
You can find more details in Themes and Templates
Application Flow
- Bootstrap: The application initializes the core components
- Request Processing: Incoming requests are parsed and routed
- Plugin Loading: Required plugins are loaded based on the request
- Controller Execution: The appropriate controller action is executed
- View Rendering: The response is rendered using the template system
- Response Delivery: The final output is sent to the client
Request Lifecycle
- [Server] The user sends a request to the server (NGINX, Apache, etc.).
- [Server] The server calls the main file, such as
index.php
. - [Main] The core is initialized using
Core::getInstance($options);
.
3.1 [Core] Initialize localization files (.mo
/.po
) for the project and core.
3.2 [Core] Fire theCore::EVENT_ON_AFTER_INIT
event.
3.3 [Core] Initialize all plugins by includinginit.php
from each plugin in the project. - [Main] Set the system plugin (e.g., Jimbo) in the Core using
$core->setSystemPlugin
. -
[Main] Bind the request through
bindRequest
in theSystemPlugin
.
5.1 [SystemPlugin] Load all settings from the database.
5.2 [SystemPlugin] Identify the abstraction area (e.g., backend, API, admin, site, etc.). The default area isdefault
.
5.3 [SystemPlugin] Load all URL route rules for the area and append additional rules from$GLOBALS['urlRules']
.
5.4 [SystemPlugin] If theonBind
option is set in the core, call theonBind
callback.
5.5 [SystemPlugin] Load all event listeners from the database for the area.
5.6 [SystemPlugin] Load all permission sections from the database for the project.
5.7 [SystemPlugin] Load all permission sections for the current user.
5.8 [SystemPlugin] If the theme includesinclude.php
, it is included at this point.
5.9 [Core] Fire theCore::EVENT_ON_REQUEST
event.
5.10 [SystemPlugin] Retrieve the current request URL.
5.11 [SystemPlugin] Determine which plugin and method should be called based on URL rules.
5.12 [Response] Create aResponse
object instance.
5.13 [SystemPlugin] Verify if the user has permission to call the plugin method.- If the user does not have permission, fire
RequestExceptionEvent
through the core.
5.14 [Core] Retrieve or initialize the plugin instance.Core::GetPluginInstance
follows the Singleton approach.
5.15 [Core] FireISystemPlugin::EVENT_ON_BEFORE_REQUEST_PLUGIN_METHOD
through the core.
5.16 [Plugin] Call the plugin method.
5.16.1 [Plugin] Execute business logic (BI) within the method.
5.17 [SystemPlugin] If an exception occurs, it is intercepted, and the core executes theonException
option.
- If the user does not have permission, fire
-
[Response] Prepare the response.
6.1 [Response] If using the base classDisplayPlugin
(available in the Festi theme package), thedisplay
method is called.
6.1.1 [Plugin] CallgetInfo()
to retrieve all variables for the template and append core properties.
6.1.2 [Plugin] ExecuteonDisplay
.
6.1.3 [Plugin] ExecuteonBreadcrumb
.
6.1.4 [Plugin] ExecuteonMeta
.
6.1.5 [Plugin] Retrieve or initialize the theme instance (Singleton approach).
6.1.6 [Plugin] If the theme includesTheme.php
, it is loaded.
- IfTheme.php
exists, it must return a class name; otherwise, the default classDefaultTheme
is used.
- The theme class must implementITheme
.
6.1.7 [Theme] Retrieve the content from the template and apply it.
6.2 [Response] Flush the output stream. -
[Server] The server sends the response back to the user.
sequenceDiagram
participant User
participant Server
participant Main
participant Core
participant Database
participant SystemPlugin
participant Plugin
participant Response
participant Theme
User->>Server: Request to Server (NGINX, Apache, etc.)
Server->>Main: Call main file (index.php)
Main->>Core: Initialize Core (Core::getInstance())
Core->>Core: Load localization files (mo/po)
Core->>Core: Include init.php from each plugin
Core->>Core: Fire Core::EVENT_ON_AFTER_INIT
Main->>Core: Set system plugin ($core->setSystemPlugin)
Main->>SystemPlugin: Bind request through bindRequest
SystemPlugin->>Database: Load settings from database
Database->>SystemPlugin: Get settings from database
SystemPlugin->>SystemPlugin: Identify abstraction area (default)
SystemPlugin->>Database: Load URL route rules
Database->>SystemPlugin: Get URL route rules and append $GLOBALS['urlRules']
SystemPlugin->>SystemPlugin: Execute onBind callback if set
SystemPlugin->>Database: Load event listeners from database
Database->>SystemPlugin: Get event listeners
SystemPlugin->>Database: Load project permission sections
Database->>SystemPlugin: Get project permission sections
SystemPlugin->>Database: Load user-specific permission sections
Database->>SystemPlugin: Get user-specific permission sections
SystemPlugin->>Theme: Include theme (if include.php exists)
SystemPlugin->>Core: Fire Core::EVENT_ON_REQUEST
SystemPlugin->>SystemPlugin: Retrieve request URL
SystemPlugin->>SystemPlugin: Determine plugin & method by URL rules
SystemPlugin->>Response: Create Response instance
SystemPlugin->>SystemPlugin: Verify permission to call plugin method
SystemPlugin->>Core: Fire RequestExceptionEvent if permission denied
SystemPlugin->>Core: Get or initialize plugin instance (Singleton)
SystemPlugin->>Core: Fire ISystemPlugin::EVENT_ON_BEFORE_REQUEST_PLUGIN_METHOD
SystemPlugin->>Plugin: Execute plugin method
Plugin->>Response: Fill data or content
Plugin->>SystemPlugin: Return the result
SystemPlugin->>SystemPlugin: Handle exceptions (call Core onException option if set)
SystemPlugin->>Response: Prepare response
Response->>Plugin: Call display method (if DisplayPlugin is used)
Plugin->>Plugin: Retrieve template variables (getInfo)
Plugin->>Plugin: Execute onDisplay, onBreadcrumb, onMeta
Plugin->>Theme: Get or initialize theme instance (Singleton)
Theme->>Theme: Include Theme.php (or use DefaultTheme)
Theme->>Theme: Apply template content
Response->>Server: Flush output stream
Server->>User: Send response