Back to October

System Module

modules/system/README.md

4.4.011.2 KB
Original Source

System Module

The System module is October CMS's core infrastructure layer, built on top of Laravel. It manages plugin lifecycle, database migrations, mail templates, settings, asset compilation, image resizing, multisite configuration, and the Twig markup engine. It bootstraps before all other modules and is required for the entire CMS to function. The System module is what makes October CMS a true plugin-based platform -- every feature beyond core infrastructure is delivered as a self-contained plugin with its own migrations, permissions, settings, and navigation, all discovered and managed automatically.

Architecture Overview

The System module is responsible for:

  • Plugin management - discovering, loading, registering, and booting plugins
  • Update management - running migrations and communicating with the marketplace
  • Mail system - Twig-based email templates with database overrides
  • Settings system - plugin and module settings stored in the database
  • Asset compilation - combining, minifying, and preprocessing CSS/JS
  • Image resizing - on-demand thumbnail generation with caching
  • Multisite - per-site configuration, routing, and content isolation
  • Twig engine - the markup engine with custom functions, filters, and security

Key Services

ServiceClassDescription
system.pluginsSystem\Classes\PluginManagerPlugin discovery, loading, and lifecycle
system.updaterSystem\Classes\UpdateManagerMigrations and marketplace updates
system.versionsSystem\Classes\VersionManagerPlugin version tracking
system.mailerSystem\Classes\MailManagerEmail template rendering
system.settingsSystem\Classes\SettingsManagerSettings page registry
system.sitesSystem\Classes\SiteManagerMultisite management
system.combinerSystem\Classes\CombineAssetsCSS/JS asset compilation
system.resizerSystem\Classes\ResizeImagesImage resize and thumbnailing
system.markupSystem\Classes\MarkupManagerTwig extension registry
system.manifestSystem\Classes\ManifestCacheManifest file caching

Plugin System

Plugin Lifecycle

Plugins are self-contained packages that live in plugins/{author}/{name}/ and have a Plugin.php registration file extending System\Classes\PluginBase. Each plugin brings its own migrations, models, controllers, components, permissions, settings, and navigation -- installed by dropping it in a directory or running a single command. No service provider wiring, no manual route registration, no config publishing.

Phase 1 - Discovery: PluginManager scans the plugins/ directory for Plugin.php files, respects the disabled list, and sorts by dependency order.

Phase 2 - Registration: For each plugin, the manager loads the composer autoloader, registers config/views/language namespaces, and calls register().

Phase 3 - Boot: After all plugins are registered, the manager calls boot() on each plugin.

PluginBase Methods

MethodDescription
register()Register services, listeners, and bindings
boot()Boot logic after all plugins are registered
registerComponents()CMS components
registerMarkupTags()Twig functions and filters
registerNavigation()Backend menu items
registerPermissions()Permission definitions
registerSettings()Settings pages
registerMailTemplates()Mail template definitions
registerMailPartials()Mail partials
registerMailLayouts()Mail layouts
registerFormWidgets()Form field widgets
registerFilterWidgets()List filter widgets
registerReportWidgets()Dashboard report widgets
registerContentFields()Tailor content fields
registerSchedule($schedule)Scheduled tasks
registerConsoleCommand($key, $class)Artisan commands

Plugin Dependencies

Plugins declare dependencies with the $require property:

php
public $require = ['Acme.User', 'Acme.Billing'];

The PluginManager resolves and sorts by dependency order automatically.

Mail System

The mail system intercepts Laravel's mailer to render emails using Twig templates stored in the database.

How it Works

  1. Plugins register mail template codes mapped to view files
  2. MailTemplate::syncAll() imports plugin templates into the database
  3. Administrators can customize templates in the backend
  4. When mail is sent, MailManager intercepts the content and renders the Twig template with the database-stored version (if customized)

Components

ComponentDescription
MailTemplateEmail template content (subject, body, code)
MailLayoutWrapper template (default, system, or custom)
MailPartialReusable email components (header, footer, button, panel)
MailSettingSMTP/mail driver configuration

Registering Templates

php
public function registerMailTemplates()
{
    return [
        'acme.blog:new-post' => 'acme.blog::mail.new-post',
    ];
}

Features include CSS inlining for email clients and full Twig syntax support with custom token parsers.

Settings System

SettingModel

System\Models\SettingModel is the base class for plugin settings. Settings are stored in the system_settings table with per-site isolation for multisite.

php
<?php namespace Acme\Blog\Models;

class Settings extends \System\Models\SettingModel
{
    public $settingsCode = 'acme_blog_settings';

    public $settingsFields = 'fields.yaml';
}

Read and write settings:

php
Settings::get('api_key');
Settings::set('api_key', 'new-value');

SettingsManager

The SettingsManager organizes settings pages into categories. Plugins register settings pages with registerSettings():

php
public function registerSettings()
{
    return [
        'settings' => [
            'label' => 'Blog Settings',
            'description' => 'Configure the blog plugin',
            'category' => 'Blog',
            'icon' => 'icon-pencil',
            'class' => \Acme\Blog\Models\Settings::class,
            'order' => 500,
        ],
    ];
}

Asset Compilation

The CombineAssets class combines and minifies CSS/JS files:

  • Combining - groups multiple files into a single request
  • Minification - optional whitespace removal
  • Preprocessing - LESS, SCSS, and Sass support
  • Caching - ETags and deep hashing for change detection
  • Bundles - pre-compiled asset groups defined in config

Image Resizing

The ResizeImages class generates thumbnails on demand:

  • URL-based resizing with safe encoding to prevent abuse
  • Options: mode (auto/crop/exact), quality, sharpen, interlace
  • Cached to storage/app/resources/resize/

Multisite

The SiteManager handles multisite routing and configuration:

  • SiteDefinition - per-site config (domain, language, locale, URL prefix)
  • Routing - automatic site detection from hostname or URL prefix
  • Settings - per-site setting values via SettingModel
  • Content - per-site content isolation in Tailor and CMS

Twig / Markup Engine

The MarkupManager registers Twig extensions from modules and plugins.

Built-in Functions

Over 40 functions including: input(), post(), get(), url(), route(), asset(), config(), env(), session(), trans(), str_*(), md() (markdown), html_*(), time_since(), time_tense(), collect(), carbon(), dump()

Adding Custom Markup

Plugins register Twig functions and filters via registerMarkupTags():

php
public function registerMarkupTags()
{
    return [
        'functions' => [
            'myFunction' => [$this, 'myFunctionHandler'],
        ],
        'filters' => [
            'myFilter' => [$this, 'myFilterHandler'],
        ],
    ];
}

Security Policy

The Twig security policy (System\Twig\SecurityPolicy) prevents dangerous operations in templates, controlling which methods and properties can be accessed.

Console Commands

System Commands

CommandDescription
october:migrateRun all pending migrations
october:updateCheck for and apply updates
october:freshReset the demo theme
october:upBring the application online
october:downPut the application into maintenance mode
october:passwdChange an admin password
october:mirrorMirror public files for symlink-free hosting
october:optimizeOptimize the application
october:utilUtility commands
october:aboutDisplay application information

Plugin Commands

CommandDescription
plugin:installInstall a plugin
plugin:removeRemove a plugin
plugin:enableEnable a disabled plugin
plugin:disableDisable a plugin
plugin:refreshRe-run a plugin's migrations
plugin:seedRun a plugin's seeder
plugin:listList installed plugins
plugin:checkCheck plugin dependencies
plugin:testRun a plugin's tests

Models

ModelDescription
FileFile attachments (used by $attachOne / $attachMany)
MailTemplateEmail template content
MailLayoutEmail layout wrappers
MailPartialReusable email components
MailSettingMail driver configuration
ParameterInternal key-value store
EventLogSystem event and error log
PluginVersionPlugin version tracking
SiteDefinitionMultisite configuration

Important Traits

TraitDescription
AssetMakerRegister CSS/JS assets in controllers and widgets
ViewMakerRender partials and views with variable injection
ConfigMakerParse YAML configuration files
ResponseMakerCreate AJAX and redirect responses
EventEmitterFire and listen to local events on objects

Key Database Tables

TableDescription
system_filesFile attachments
system_settingsPlugin and module settings
system_parametersInternal parameters
system_plugin_versionsInstalled plugin versions
system_plugin_historyMigration history per plugin
system_mail_templatesEmail templates
system_mail_layoutsEmail layouts
system_mail_partialsEmail partials
system_event_logsError and event log
system_request_logsHTTP request log
system_site_definitionsMultisite definitions
system_site_groupsSite groups
deferred_bindingsTemporary model relationships

Extension Points

Events

EventDescription
system.settings.extendItemsExtend settings pages
system.updater.migrateAfter migrations complete
mailer.beforeAddContentOverride email content rendering
exception.beforeReportBefore an exception is reported
exception.beforeRenderBefore an exception is rendered
backend.ajax.beforeRunHandlerBefore AJAX handler execution
console.scheduleRegister scheduled tasks

Module Bootstrap Order

  1. System module registers and loads all other modules
  2. All plugins are registered (in dependency order)
  3. System module boots
  4. All plugins are booted