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 templates
  • static/: Contains JavaScript and other asset files
  • tblDfs/: Contains Data Grid Store definition schemes
  • templates/: Contains view templates
  • tests/: Contains UNIT tests for the plugin
  • init.php: Initialization file for the plugin
  • README.md: Base documentation about the plugin
  • PluginNameObject.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

  1. Bootstrap: The application initializes the core components
  2. Request Processing: Incoming requests are parsed and routed
  3. Plugin Loading: Required plugins are loaded based on the request
  4. Controller Execution: The appropriate controller action is executed
  5. View Rendering: The response is rendered using the template system
  6. Response Delivery: The final output is sent to the client

Request Lifecycle

  1. [Server] The user sends a request to the server (NGINX, Apache, etc.).
  2. [Server] The server calls the main file, such as index.php.
  3. [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 the Core::EVENT_ON_AFTER_INIT event.
    3.3 [Core] Initialize all plugins by including init.php from each plugin in the project.
  4. [Main] Set the system plugin (e.g., Jimbo) in the Core using $core->setSystemPlugin.
  5. [Main] Bind the request through bindRequest in the SystemPlugin.
    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 is default.
    5.3 [SystemPlugin] Load all URL route rules for the area and append additional rules from $GLOBALS['urlRules'].
    5.4 [SystemPlugin] If the onBind option is set in the core, call the onBind 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 includes include.php, it is included at this point.
    5.9 [Core] Fire the Core::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 a Response 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] Fire ISystemPlugin::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 the onException option.
  6. [Response] Prepare the response.
    6.1 [Response] If using the base class DisplayPlugin (available in the Festi theme package), the display method is called.
    6.1.1 [Plugin] Call getInfo() to retrieve all variables for the template and append core properties.
    6.1.2 [Plugin] Execute onDisplay.
    6.1.3 [Plugin] Execute onBreadcrumb.
    6.1.4 [Plugin] Execute onMeta.
    6.1.5 [Plugin] Retrieve or initialize the theme instance (Singleton approach).
    6.1.6 [Plugin] If the theme includes Theme.php, it is loaded.
    - If Theme.php exists, it must return a class name; otherwise, the default class DefaultTheme is used.
    - The theme class must implement ITheme.
    6.1.7 [Theme] Retrieve the content from the template and apply it.
    6.2 [Response] Flush the output stream.

  7. [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