Modules

Extend Forge with self-contained modules for services, routes, views, etc.

Module System Overview

Package functionality into reusable components. Modules provide services, controllers, views, CLI commands, and more.

Key Features

Auto-discovery and loading
Dependency management
Lifecycle hooks
Service registration
Route registration
View integration

Publishing Modules

Share modules with the community through the Forge registry.

Creating a Module Version

# Create a new version of your module
php modules.php create-version MyModule@1.2.0

# This will:
# 1. Zip your module folder
# 2. Calculate integrity hash
# 3. Update the modules manifest
# 4. Commit changes to the registry

Publishing to Registry

# Push your module to the remote registry
php modules.php publish

# List all available modules and versions
php modules.php list-versions

Module Registry: The Forge module registry uses a Git-based system for version control and distribution. Each module version is packaged as a ZIP file with integrity verification.

Module Lifecycle

Execute code at specific points during application boot.

Available Lifecycle Hooks

After Boot

Executed after the application has booted

After Module Load

Executed after all modules are loaded

After Module Register

Executed after a module is registered

After Config Loaded

Executed after configuration is loaded

App Booted

Executed when the application is fully booted

Before Request

Executed before each HTTP request

After Request

Executed after each HTTP request

After Response

Executed after HTTP response is sent

Using Lifecycle Hooks

use Forge\Core\Module\Attributes\LifecycleHook;
use Forge\Core\Module\LifecycleHookName;

#[LifecycleHook(hook: LifecycleHookName::AFTER_MODULE_REGISTER)]
public function onAfterModuleRegister(): void
{
    // Your code here
}

#[LifecycleHook(hook: LifecycleHookName::APP_BOOTED)]
public function onAppBooted(): void
{
    // Initialize services, register listeners, etc.
}

Official Modules

ForgeAuth

Authentication system with login, registration, and session management.

Authentication Sessions

ForgeUI

Beautiful UI components and utilities for building modern web interfaces.

Components UI

ForgeWire

Lightweight Livewire-like reactive components for building dynamic interfaces without JavaScript or WebSockets.

Reactive Components

ForgeStorage

Multi-driver storage system supporting local, S3, and other cloud storage providers.

Storage Cloud

ForgeDebugBar

Comprehensive debugging toolbar with query logging, performance metrics, and more.

Debug Development

ForgeTesting

Complete testing suite with unit tests, integration tests, and test utilities.

Testing Quality

ForgeMarkDown

Markdown processing and rendering with syntax highlighting support.

Markdown Parser

ForgeLogger

Advanced logging and monitoring with multiple drivers and channels.

Logging Monitoring

ForgeTailwind

Tailwind CSS integration with build tools and asset management.

CSS Styling

ForgeErrorHandler

Comprehensive error handling and exception management for production applications.

Error Exception

ForgeEvents

Event system with listeners, queues, and event-driven architecture support.

Events Queues

ForgePackageManager

Package and module management system with registry support and integrity verification.

Package Manager Registry

Installing Modules

Use Forge CLI or manually place modules in the modules directory.

Using Forge CLI

# Install a module
php forge.php install:module ForgeAuth

# Install a specific version
php forge.php install:module ForgeAuth@1.2.0

# Force refresh cache during installation
php forge.php install:module ForgeAuth force

# List available modules
php forge.php list:modules

Manual Installation

# Clone module to modules directory
cd modules/
git clone https://github.com/forge-modules/ForgeAuth.git

# Or download and extract
wget https://github.com/forge-modules/ForgeAuth/archive/main.zip
unzip main.zip -d ForgeAuth/

Auto-Discovery: Modules auto-load when placed in the modules directory.

Creating Custom Modules

Encapsulate functionality and share across projects.

# Generate a new module
php forge.php make:module MyCustomModule

# Generate with specific options
php forge.php make:module BlogModule --type=cms --with-controllers --with-views

This creates a complete module structure in modules/MyCustomModule/:

modules/MyCustomModule/
├── forge.json              # Module configuration
├── src/                    # Module source code
│   ├── MyCustomModule.php  # Module class
│   ├── Controllers/        # Module controllers
│   ├── Services/          # Module services
│   ├── Models/            # Module models
│   ├── Commands/          # CLI commands
│   └── Contracts/         # Interfaces and contracts
├── config/                 # Module configuration files
├── resources/              # Module resources
│   ├── views/             # Module views
│   └── assets/            # CSS, JS, images
└── tests/                  # Module tests

Module Structure

Module Configuration (forge.json)

{
    "$schema": "./../../engine/Core/Schema/module-schema.json",
    "name": "MyCustomModule",
    "version": "1.0.0",
    "description": "A custom module for my application",
    "type": "generic",
    "order": 100,
    "cli": {
        "commands": []
    },
    "tags": [],
    "config": {
        "defaults": {}
    },
    "author": "Your Name",
    "license": ""
}

Module Class

<?php

declare(strict_types=1);

namespace App\Modules\MyCustomModule;

use Forge\Core\DI\Container;
use Forge\Core\Module\Attributes\Module;
use Forge\Core\Module\Attributes\Service;
use Forge\Core\Module\Attributes\Compatibility;
use App\Modules\MyCustomModule\Services\CustomService;
use App\Modules\MyCustomModule\Contracts\CustomInterface;
use Forge\Core\Module\Attributes\LifecycleHook;
use Forge\Core\Module\LifecycleHookName;

#[Module(name: 'MyCustomModule', description: 'A custom module for my application', order: 100)]
#[Service]
#[Compatibility(framework: '>=0.1.0', php: '>=8.3')]
final class MyCustomModule
{
    public function register(Container $container): void
    {
        // Register services
        $container->bind(CustomInterface::class, CustomService::class);
    }

    #[LifecycleHook(hook: LifecycleHookName::AFTER_MODULE_REGISTER)]
    public function onAfterModuleRegister(): void
    {
        // Module registration complete
    }
}

Module Service

<?php

namespace MyCustomModule\Services;

use Forge\Core\DI\Attributes\Service;
use MyCustomModule\Contracts\CustomInterface;

#[Service]
class CustomService implements CustomInterface
{
    public function __construct(
        private LoggerInterface $logger
    ) {}
    
    public function initialize(): void
    {
        $this->logger->info('CustomService initialized');
    }
    
    public function processData(array $data): array
    {
        // Your custom logic here
        return array_map('strtoupper', $data);
    }
    
    public function onUserCreated(UserCreatedEvent $event): void
    {
        $this->logger->info('User created: ' . $event->user->email);
    }
}

Lifecycle Hooks

Modules can hook into the application lifecycle at various points to perform initialization, cleanup, and other tasks.

Available Hooks

register
Called when the module is first loaded. Register services and bindings here.
boot
Called after all modules are registered. Perform initialization logic here.
shutdown
Called when the application is shutting down. Cleanup resources here.
<?php

class Bootstrap implements ModuleInterface
{
    public static function register(Container $container): void
    {
        // Early registration - services, bindings, configuration
        $container->bind(PaymentService::class);
        $container->singleton(CacheManager::class);
    }
    
    public static function boot(Container $container): void
    {
        // Late initialization - event listeners, middleware, routes
        $router = $container->get('router');
        $router->group(['prefix' => 'api/payments'], function($router) {
            require __DIR__ . '/Routes/api.php';
        });
        
        // Register middleware
        $middleware = $container->get('middleware');
        $middleware->register('payment.auth', PaymentAuthMiddleware::class);
    }
    
    public static function shutdown(Container $container): void
    {
        // Cleanup - close connections, save state, etc.
        $paymentService = $container->get(PaymentService::class);
        $paymentService->closeConnections();
    }
}

Publishing Modules

Share modules with the community via package repositories.

Preparing for Publication

# Validate module structure
php forge.php module:validate MyCustomModule

# Run module tests
php forge.php module:test MyCustomModule

# Build module package
php forge.php module:build MyCustomModule

Publishing Checklist

  • Complete forge.json with all metadata
  • Write comprehensive documentation
  • Include unit and integration tests
  • Follow semantic versioning
  • Add proper license file
  • Test compatibility with different Forge versions

Best Practices

Do

  • • Use descriptive module names
  • • Follow PSR-4 autoloading standards
  • • Include comprehensive tests
  • • Document your public API
  • • Use semantic versioning
  • • Handle dependencies gracefully

Don't

  • • Modify core framework files
  • • Create tight coupling between modules
  • • Ignore error handling
  • • Skip version constraints
  • • Hardcode configuration values
  • • Forget to clean up resources