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