Index

ProductionController

MMO\admin\controllers · 1 symbol · generated 5 Oct 2026

class

ProductionController

ProductionController.php:54

The command-line surface of mmo.admin: build, ship, activate, roll back, back up, restore and migrate one or more deployment targets.

class MMO\admin\controllers\ProductionController extends MMO\core\classes\aShellController
Namespace
MMO\admin\controllers
Extends
aShellController
See
aDeployTask, and hands both to a Runner. Every command is therefore the same three lines, and anything you can do interactively you can do from a script, identically., $protectedTags has to be confirmed deliberately (confirmProtected), and a fan-out across several of them deploys to the first one alone and stops for a look before continuing (runFanOut).
It owns no deployment logic of its own -- it selects targets ([`Targets`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/helpers/Targets.md#targets)), assembles a pipeline of **Non-interactive first.** Every mutating command needs an explicit selection -- `--targets=a,b`, `--tags=prod`, or `--all`. Nothing defaults to "every target": the previous script did, which meant a mistyped argument reached the whole fleet. When run with no selection at all AND a human is present -- the dashboard, or a command typed at a terminal ([`onRoute`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/controllers/ProductionController.md#productioncontroller-onroute)) -- the command asks; when run from a script, it refuses. **It reports failure properly.** Every mutating command sets the process exit code from the run's outcome ([`getExitCode`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/controllers/ProductionController.md#productioncontroller-getexitcode)). Nothing here used to: a `release` that failed on every target exited 0, so no script and no CI job could tell a deployment from a disaster. **Production is not just another tag.** A selection touching a target tagged with one of Common options, accepted by every command: - `--targets=a,b` / `--tags=prod` / `--all` which targets (required for anything that writes) - `--include-disabled` also act on targets declared `"enabled": false` - `--dry-run` describe everything, change nothing - `--yes` do not ask for confirmation - `--i-understand` the non-interactive form of the protected-target confirmation - `--no-canary` fan out to every protected target at once, without stopping - `--force` rebuild, re-ship, break a stale lock - `--continue` keep going after a target fails
php admin.php status --all php admin.php release --targets=demo --dry-run php admin.php release --tags=prod --yes --i-understand php admin.php rollback --targets=demo --to=4.0.20

Index

allowed
buildCommands
buildFolder
buildOptions
credentialsFile
dashboardCommand
exclude
exitCode
forbidden
git
healthIsFatal
healthTimeout
include
installTemplates
manifest
patchFolder
postInstall
protectedTags
reports
repository
requiredTools
sshConfigFile
store
targets
targetsFile
templateFolder
versionLibraries
versionMessage
versionOnRelease
bumpVersion($part, $dryRun, $library)
confirmProtected($route, $targets, $verb)Make changing a production target a deliberate act.
doctor()Check the files, then every server and target: what doctor prints.
getExitCode()
getGit()
getLibraryVersions($all)
getOptions($route)
getProjectFolder()
getProjectVersion()
getProtected($targets)
getProtectedTags()
getReadiness()
getReleaseTasks()The full pipeline: everything a release needs, in the only order that is safe.
getReports()
getRepository()
getRunner($route)
getStore()
getTargets()
getVersionOptions($route)
index($route)No command: the dashboard -- the project, its targets and what was deployed where, beside the actions this project can do, one key each.
mirror($targets, $quiet)Read the journal of each target into this machine's history (Store::HISTORY).
newActivateTask()
newAssertTask()
newBuildTask()
newInstallTask()
newMigrateTask()
onRoute($route)A command typed on the command line asks, at a terminal, what the same command asks in the dashboard.
prepareVersions($targets, $options, $dryRun)Before a release: increase the version of every package with commits since its version last changed -- each library's patch, then the project's, which records the libraries with it -- so a release …
printCheck($label, $ok, $detail, $indent)
printDeployment($entry)
printSkippedVersions($skipped)
printStatus($target)What a target actually has, read from the target and compared with what the journal claims.
printStatusLine($label, $value, $ok)
printTargetTools($target, $shell)Report which of $requiredTools the target actually has.
printVersion($version, $part, $why)One line of prepareVersions: a package, its version and the next one, and why.
printWebRoot($target, $shell)Report the host-fixed document root, when the target declares one.
route_activate($route)
route_backup($route)
route_build($route)
route_cmd($route)
route_doctor($route)
route_history($route)
route_init($route)
route_install($route)
route_migrate($route)
route_plan($route)
route_prune($route)
route_release($route)
route_restore($route)
route_rollback($route)
route_setup($route)Write deploy.json -- and what else deploying needs -- by answering questions: a guide as much as a form, which explains every step and shows every change before making it.
route_ship($route)
route_status($route)
route_sync($route)
route_targets($route)
route_version($route)Increase the version in the project's mmo.json -- or a library's, with --library -- and commit it: a release is named after the project's version and packages each library under its own, so new c…
run($route, $targets, $tasks, $verb, $extra)Run a pipeline over a selection, with the protected-target guards, and record the outcome as this invocation's exit code.
runFanOut($route, $runner, $targets, $tasks, $options)Deploy to one protected target, stop, and only continue once that one is known good.
runSetup($step, $offerDoctor, $dryRun)Run SetupWizard: every step, or one step and the review of what it changes.
selectTargets($route, $title, $max)Which targets this invocation acts on.
setDashboardCommand($command)

Properties29

allowed

protected array $allowed = []
Type
array

buildCommands

protected array $buildCommands = []
Type
array

buildFolder

protected string $buildFolder = '{root}/build'
Type
string

buildOptions

protected array $buildOptions = []
Type
array

credentialsFile

protected ?string $credentialsFile = null
Type
null | string

dashboardCommand

#[MMO\core\attributes\Serialize(false)] protected ?string $dashboardCommand = null
Type
null | string

exclude

protected array $exclude = […7 items]
Type
array

exitCode

#[MMO\core\attributes\Serialize(false)] protected int $exitCode = 0
Type
int

forbidden

protected array $forbidden = []
Type
array

git

protected ?MMO\git\helpers\Repository $git = null
Type
null | Repository

healthIsFatal

protected bool $healthIsFatal = true
Type
bool
Leave it true wherever the probe can actually observe the release. Setting it false is for the case where the probe cannot be trusted to be about the release at all -- a public url behind a cache or a proxy you do not control -- because a probe that is red for reasons of its own rolls back good releases, and a rollback is its own outage.

healthTimeout

protected int $healthTimeout = 20
Type
int

include

protected array $include = ['www/bin']
Type
array

installTemplates

protected array $installTemplates = []
Type
array

manifest

protected ?string $manifest = null
Type
null | string

patchFolder

protected string $patchFolder = '{root}/db/patches'
Type
string

postInstall

protected ?string $postInstall = null
Type
null | string

protectedTags

protected array $protectedTags = ['prod', 'production']
Type
array

reports

#[MMO\core\attributes\Serialize(false)] protected array $reports = []
Type
array

repository

protected ?MMO\core\interfaces\iRepository $repository = null
Type
null | iRepository

requiredTools

protected array $requiredTools = […3 items]
Type
array
This exists because of shared hosting. On a machine we install these are a given; on a webspace they are the provider's choice, and the first time `tar` turns out to be missing should not be halfway through a release, with an artifact already uploaded and the lock held. [`printTargetTools`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/controllers/ProductionController.md#productioncontroller-printtargettools)

sshConfigFile

protected ?string $sshConfigFile = null
Type
null | string

store

#[MMO\core\attributes\Serialize(false)] protected ?MMO\admin\helpers\Store $store = null
Type
null | Store

targets

#[MMO\core\attributes\Serialize(false)] protected ?MMO\admin\helpers\Targets $targets = null
Type
null | Targets

targetsFile

protected string $targetsFile = '{root}/deploy.json'
Type
string

templateFolder

protected string $templateFolder = '{mmo.admin}/templates'
Type
string

versionLibraries

protected array|bool $versionLibraries = true
Type
array | bool

versionMessage

protected string $versionMessage = 'version {version}'
Type
string

versionOnRelease

protected bool $versionOnRelease = true
Type
bool

Methods61

bumpVersion($part, $dryRun, $library)

ProductionController.php:786
function bumpVersion(?string $part = null, bool $dryRun = false, ?string $library = null): ?string
$part = nullnull | stringmajor, minor or patch; null: ask at a terminal, the patch otherwise.
$dryRun = falseboolsay what would change, change nothing.
$library = nullnull | stringa library the project packages (null: the project).
returnsnull | stringthe new version; null when nothing was changed (a dry run, or no answer).
throwswhen mmo.json is not committed as it is, or its version is not major.minor.patch.

confirmProtected($route, $targets, $verb)

ProductionController.php:431

Make changing a production target a deliberate act.

protected function confirmProtected(MMO\core\server\Route $route, array $targets, string $verb = 'change'): void`--yes` deliberately does NOT satisfy this. `--yes` means "do not ask me about the plan", which people pass habitually; this asks a different question -- "do you know these are production?" -- and answering it has to be a separate decision, spelled `--i-understand` in a script. The interactive form asks for something that cannot be typed from muscle memory: the target's own name, or how many of them there are.
$routeRoute
$targetsarray
$verb = 'change'string
returnsvoid
throwswhen the confirmation is refused or unavailable.

getExitCode()

ProductionController.php:220
function getExitCode(): int
returnsint0 when everything this invocation did succeeded, 1 otherwise. The entry script is expected to exit() with this -- templates/scripts/admin.php.

getLibraryVersions($all)

ProductionController.php:840
function getLibraryVersions(bool $all = false): array
$all = falseboolevery library packaged from a git checkout; false: those of $versionLibraries.
returnsarrayVersion> name => the version of each library the project packages from a git checkout -- a phar, or a folder that is none, has no commit to name.

getOptions($route)

ProductionController.php:284
function getOptions(MMO\core\server\Route $route): array
$routeRoute
returnsarraythe per-run options tasks read from the context (--force, --to=, --file=).

getProjectFolder()

ProductionController.php:199
function getProjectFolder(): string
returnsstringthe project: the folder holding deploy.json, where everything deploying needs is kept.

getProjectVersion()

ProductionController.php:831
function getProjectVersion(): MMO\admin\helpers\Version
returnsVersionthe project's: its mmo.json, in the repository releases are built from.

getReadiness()

ProductionController.php:188
function getReadiness(): MMO\admin\helpers\Readiness
returnsReadinesswhether this project is set up to deploy, read from its files now: never cached.

getReleaseTasks()

ProductionController.php:497

The full pipeline: everything a release needs, in the only order that is safe.

function getReleaseTasks(): array
returnsarray

index($route)

ProductionController.php:538

No command: the dashboard -- the project, its targets and what was deployed where, beside the actions this project can do, one key each. Until setup is done, the steps of setup are all it offers. Dashboard

#[MMO\core\attributes\Command([], 'dashboard', order: 1000)] function index(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

mirror($targets, $quiet)

ProductionController.php:335

Read the journal of each target into this machine's history (Store::HISTORY).

protected function mirror(array $targets, bool $quiet = false): int
$targetsarray
$quiet = falseboola deployment's own mirror: a target that cannot be read is said in one line, and fails nothing -- the deployment is what the exit code is about.
returnsinthow many entries were new.

onRoute($route)

ProductionController.php:522

A command typed on the command line asks, at a terminal, what the same command asks in the dashboard.

function onRoute(MMO\core\server\Route $route): bool
See
aShellController::onRoute makes only the dashboard (no command typed) interactive, so a command typed in full never asked anything: release --targets=demo applied its plan without "Apply this plan on [demo] ?", and a protected target was refused as if from a script -- even to someone sitting at a terminal. Whether anyone can answer is a property of the input, not of how the command was chosen: a terminal has someone at it; cron, CI and a pipe do not, are never asked anything, and so never wait for an answer that cannot come.
$routeRoute
returnsbool

prepareVersions($targets, $options, $dryRun)

ProductionController.php:872

Before a release: increase the version of every package with commits since its version last changed -- each library's patch, then the project's, which records the libraries with it -- so a release never names new code with an old version. A library a project version names is the code of that version, and a release of the project is told from the previous one by its name alone.

function prepareVersions(array $targets, array $options = [], bool $dryRun = false): arrayNothing is increased when nothing was committed since: releasing the same commit to staging, then to production, increases the version once. Nor when the release could not be built from what would be committed: a target released from another ref than the branch this checkout is on, or a working tree with uncommitted changes (the build refuses both, and says why). The libraries go up by a patch; the project by `--part`, the patch when there is none -- at a terminal it asks, `none` releasing with the versions as they are. `--no-version`, or [`$versionOnRelease`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/controllers/ProductionController.md#productioncontroller-versiononrelease), skips the step. Every commit is local: nothing is pushed.
$targetsarraythe release's.
$options = []array
$dryRun = falseboolsay what would be increased, change nothing.
returnsarraystring> name => the new version, of what was increased.

printCheck($label, $ok, $detail, $indent)

ProductionController.php:1262
protected function printCheck(string $label, ?bool $ok, string $detail = '', int $indent = 2): void
$labelstring
$oknull | booltrue: good. false: needs fixing. NULL: not applicable -- optional and absent. The third state matters: a project whose servers all use the ssh agent has no credentials file and needs none, and marking that with the same red circle as an unreachable server teaches people to ignore the red circles.
$detail = ''string
$indent = 2int
returnsvoid

printStatus($target)

ProductionController.php:1185

What a target actually has, read from the target and compared with what the journal claims.

protected function printStatus(MMO\admin\entities\Target $target): void
$targetTarget
returnsvoid

printWebRoot($target, $shell)

ProductionController.php:685

Report the host-fixed document root, when the target declares one.

protected function printWebRoot(MMO\admin\entities\Target $target, MMO\core\server\ShellRunner $shell): void
$targetTarget
$shellShellRunner
returnsvoid

route_activate($route)

ProductionController.php:988
#[MMO\core\attributes\InteractiveCommand('activate', 'switch a target onto an already shipped release')] function route_activate(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_backup($route)

ProductionController.php:1008
#[MMO\core\attributes\InteractiveCommand('backup', 'dump a target\'s database')] function route_backup(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_build($route)

ProductionController.php:744
#[MMO\core\attributes\InteractiveCommand('build', 'build a release artifact, without shipping it')] function route_build(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_cmd($route)

ProductionController.php:1047
#[MMO\core\attributes\InteractiveCommand('cmd', 'run a command on the targets', [['exec' => 'string', 'description' => 'the command to run']])] function route_cmd(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_doctor($route)

ProductionController.php:561
#[MMO\core\attributes\InteractiveCommand('doctor', 'check the declaration, the credentials and the reachability of each target')] function route_doctor(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_history($route)

ProductionController.php:704
#[MMO\core\attributes\InteractiveCommand('history', 'show a target\'s deployment history')] function route_history(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_init($route)

ProductionController.php:1137
#[MMO\core\attributes\InteractiveCommand('init', 'write the deployment templates into a fresh project')] function route_init(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_install($route)

ProductionController.php:998
#[MMO\core\attributes\InteractiveCommand('install', 'create the folder layout on a new target')] function route_install(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_migrate($route)

ProductionController.php:1042
#[MMO\core\attributes\InteractiveCommand('migrate', 'apply the pending database patches')] function route_migrate(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_plan($route)

ProductionController.php:728
#[MMO\core\attributes\InteractiveCommand('plan', 'show what a release would do, without doing it')] function route_plan(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_prune($route)

ProductionController.php:1003
#[MMO\core\attributes\InteractiveCommand('prune', 'delete old releases on a target')] function route_prune(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_release($route)

ProductionController.php:737
#[MMO\core\attributes\InteractiveCommand('release', 'build, ship, migrate and activate a release')] function route_release(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_restore($route)

ProductionController.php:1022
#[MMO\core\attributes\InteractiveCommand('restore', 'restore a target\'s database from a dump', [['file' => 'string', 'description' => 'the dump to restore']])] function route_restore(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_rollback($route)

ProductionController.php:993
#[MMO\core\attributes\InteractiveCommand('rollback', 'point a target back at its previous release')] function route_rollback(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_setup($route)

ProductionController.php:1091

Write deploy.json -- and what else deploying needs -- by answering questions: a guide as much as a form, which explains every step and shows every change before making it. SetupWizard

#[MMO\core\attributes\InteractiveCommand('setup', 'write deploy.json and what deploying needs, step by step: every question explained, every change shown first', [[…2 items]])] function route_setup(MMO\core\server\Route $route): voidIt is the only command that writes deploy.json, and it does so only once a person has read the diff: a deployment never does, and neither does anything run without a human answering.
$routeRoutesetup [--step=targets] [--dry-run]
returnsvoid
php scripts/admin.php setupphp scripts/admin.php setup --step=targets

route_ship($route)

ProductionController.php:983
#[MMO\core\attributes\InteractiveCommand('ship', 'upload a release without activating it')] function route_ship(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_status($route)

ProductionController.php:697
#[MMO\core\attributes\InteractiveCommand('status', 'what is actually live on each target')] function route_status(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_sync($route)

ProductionController.php:717
#[MMO\core\attributes\InteractiveCommand('sync', 'mirror each target\'s journal into the local store')] function route_sync(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_targets($route)

ProductionController.php:543
#[MMO\core\attributes\InteractiveCommand('targets', 'list the declared targets')] function route_targets(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_version($route)

ProductionController.php:771

Increase the version in the project's mmo.json -- or a library's, with --library -- and commit it: a release is named after the project's version and packages each library under its own, so new code needs a new one.

#[MMO\core\attributes\InteractiveCommand('version', 'increase the version in mmo.json and commit it', [[…2 items], […2 items]])] function route_version(MMO\core\server\Route $route): void`release` does it by itself for whatever changed since its version did ([`prepareVersions`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/controllers/ProductionController.md#productioncontroller-prepareversions)): this is for a minor or a major, or a version wanted without a release. At a terminal it asks which part to increase -- ENTER is the patch; from a script it increases `--part`, the patch when there is none. Only mmo.json goes into the commit, on the branch its repository is on: whatever else is staged stays staged.
$routeRouteversion [--part=major|minor|patch] [--library=mmo.client] [--dry-run]
returnsvoid
php scripts/admin.php versionphp scripts/admin.php version --part=minorphp scripts/admin.php version --library=mmo.client --part=minor

run($route, $targets, $tasks, $verb, $extra)

ProductionController.php:309

Run a pipeline over a selection, with the protected-target guards, and record the outcome as this invocation's exit code.

protected function run( MMO\core\server\Route $route, array $targets, array $tasks, string $verb = 'change', array $extra = [] ): arrayThis is the single funnel every mutating command goes through, so none of them can forget the guard, and none of them can succeed silently while a target failed.
$routeRoute
$targetsarray
$tasksarray
$verb = 'change'stringwhat is about to happen, for the confirmation.
$extra = []arrayper-run options a command resolved itself (an interactively chosen dump, ...).
returnsarraythe per-target reports.

runFanOut($route, $runner, $targets, $tasks, $options)

ProductionController.php:379

Deploy to one protected target, stop, and only continue once that one is known good.

protected function runFanOut( MMO\core\server\Route $route, MMO\admin\helpers\Runner $runner, array $targets, array $tasks, array $options ): arrayA fan-out is the one place where a tool amplifies a mistake: the same bad release reaches twenty machines in the time it takes to reach one. The canary costs one confirmation and removes that amplification, so it is the default whenever more than one protected target is selected.
$routeRoute
$runnerRunner
$targetsarray
$tasksarray
$optionsarray
returnsarray

runSetup($step, $offerDoctor, $dryRun)

ProductionController.php:1106

Run SetupWizard: every step, or one step and the review of what it changes.

function runSetup(?string $step = null, bool $offerDoctor = true, bool $dryRun = false): bool
$step = nullnull | stringone of SetupWizard::STEPS (null: all of them).
$offerDoctor = trueboolask, once something is written, whether to check it with doctor.
$dryRun = falseboolask everything, write nothing.
returnsboolwhether anything was written.

selectTargets($route, $title, $max)

ProductionController.php:237

Which targets this invocation acts on.

function selectTargets( MMO\core\server\Route $route, string $title = 'Select targets', ?int $max = null ): arrayThere is no implicit "all": a selection must be named (`--targets=`), matched (`--tags=`), asked for (`--all`), or picked by a human from the menu. A script with no selection gets an error, not the fleet.
$routeRoute
$title = 'Select targets'stringshown when asking interactively.
$max = nullnull | int
returnsarray
throwswhen nothing was selected and nobody can be asked.
Inherited members (63)
ConstantsDeclared byDescription
ALERTiLogLevelAlert: Action must be taken immediately.
ALLiLogLevelMask for all
ALL_PLUSiLogLeveldebug everything
BACKTRACEiLogLevel
CRITICALiLogLevelCritical: Critical conditions.
DEBUGiLogLevelDebug: Detailed debug information.
DEEPiLogLeveldebug everything with arguments
EMERGENCYiLogLevelEmergency: System is unusable.
ERRORiLogLevelError: Runtime errors that do not require immediate action but should typically be logged and monitored.
ERROR_PLUSiLogLevelMask for all error
FATALiLogLevelMask for all fatal error
INFOiLogLevelInfo: Interesting events.
INFO_PLUSiLogLevelMask for all errors/warning/notices/info
MEMORYiLogLevelinclude backtrace object
NOTICEiLogLevelNotice: Normal but significant events.
NOTICE_PLUSiLogLevelMask for all errors/warning/notices/info
TRACEiLogLevelinclude backtrace as origins
WARNINGiLogLevelWarning: Exceptional occurrences that are not errors.
WARNING_PLUSiLogLevelMask for all errors and warnings
PropertiesDeclared byDescription
interactiveaShellController
verbosityaModule
MethodsDeclared byDescription
alert($message, $context)aModuleAction must be taken immediately.
backtraces($message, $context)aModuleForce-log a message at INFO level together with a full stack trace/memory snapshot (iLogLevel::BACKTRACE), bypassing the verbosity mask entirely (any non-zero verbosity is enough to trigger it).
callInteractiveCommand($route, $cmd)aShellControllerInvoke the method behind $cmd (looked up via InteractiveCommands), or print an "unknown command" message if $cmd doesn't match any registered interactive command.
Configure($config)aModuleMerge $config into this module's configuration in the shared Configuration.
critical($message, $context)aModuleCritical conditions. No-op if CRITICAL is currently filtered out by the verbosity mask.
debug($message, $context)aModuleDetailed debug information.
debugName()aModuleHuman-readable identifier used as the default {origin} in this instance's log messages.
DefaultConfig()aModuleThe config a module starts from before anything loaded via Configuration is merged in.
emergency($message, $context)aModuleSystem is unusable. No-op if EMERGENCY is currently filtered out by the verbosity mask.
error($message, $context)aModuleRuntime errors that do not require immediate action but should typically be logged and monitored.
ExtractRoutes($config)aControllerExtract all the APIRoute from this class, regardless of the fact they are registered in the application
getVerbosity()aModule
hasOtherCommand($route)aShellControllerTell if another shell controller matched a command of its own (anything but its index) for $route
HasRoutes()aControllerTells if any APIRoute are registered in the application
info($message, $context)aModuleInteresting events. No-op if INFO is currently filtered out by the verbosity mask.
Instantiate($config)aModule(Re)create the shared instance immediately, configured with $config merged into the class's existing config.
InteractiveCommands()aShellControllerEvery #[InteractiveCommand(...)]-decorated method on this class, keyed by its command name.
IsShared()aModule
Link($method, $data)aControllerBuild a Link (URL + label/icon/description/title, taken from the route's APIRoute metadata) for a registered route.
log($level, $message, $context)aModuleLogs with an arbitrary level.
notice($message, $context)aModuleNormal but significant events.
offsetExists($key)aModule\ArrayAccess::offsetExists -- tells whether $key is a declared property at all, regardless of whether it is currently readable/writable through array access.
offsetGet($key)aModule\ArrayAccess::offsetGet -- reads a property directly, unless it has a #[Serialize(serialize: 'methodName')] attribute, in which case that zero-argument method is called instead (e.g.
offsetSet($key, $value)aModule\ArrayAccess::offsetSet -- sets a property directly, unless it has a #[Serialize(unserialize: 'methodName')] attribute, in which case that method is called with $value instead (e.g.
offsetUnset($key)aModule\ArrayAccess::offsetUnset -- equivalent to $module[$key] = null.
Route($method)aControllerGet a registered APIRoute WARNING: if this class was not registered in the application, it will return null.
Routes()aControllerGet a list of registered APIRoutes (from this class) in the application WARNING: if this class was not registered in the application, it will return an empty array.
route_help($route)aShellControllerPrint CLI usage for every 'SHELL'-method route on this controller: the command line to type, each argument's name/required-ness/description, and any declared usage examples.
serialize($path, $serializer)aModule\MMO\core\interfaces\iSerializable::serialize -- exports every property (via
setInteractive($interactive)aShellController
setVerbosity($verb)aModuleSet the current verbosity mask, replacing whatever it was before.
Shared()aModuleGet the shared instance, creating (and configuring) it on first call.
showInteractiveCommands()aShellControllerPrint the list of available interactive commands, plus the [ENTER]/[ESC]/q hints.
showSplash()aShellControllerPrint the application's icon/version/title/description banner.
testVerbosity($level)aModuleTest whether a given level (or set of levels) is currently enabled by this instance's verbosity mask.
traitUnshare($serialize)aModuleRemove the shared instance, so the next Shared() call creates a fresh one.
unserialize($data, $path, $instances)aModule\MMO\core\interfaces\iSerializable::unserialize -- merges $data onto DefaultConfig, runs it through the (possibly overridden) constructor, then applies each resulting value to its property (via
Unshare($serialize)aModuleLike tSingleton::Unshare, but also disconnects this module's instance from every event it was listening to (via Event::DisconnectListeners) before dropping it.
Url($method, $data)aControllerBuild the URL for a registered route, filling in any {placeholder} from $data.
warning($message, $context)aModuleExceptional occurrences that are not errors.
__construct($config)aModuleprotected constructor, so it is not possible to do new Module(...) called by the serialization process just before being injected with data.
__wakeup()aControllerCalled automatically right after the controller's shared instance is built (aModule::unserialize): registers onRoute as a Route listener with a low priority (-10), so it…