Index

InstallTask

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

class

InstallTask

InstallTask.php:34

Create the target's folder layout, so every later task can assume it exists.

class MMO\admin\tasks\InstallTask extends MMO\admin\classes\aDeployTask
Namespace
MMO\admin\tasks
Extends
aDeployTask
See
linkWebRoot turns that path into a symlink onto {folder}/current/{publicPath} -- once, here, rather than on every deploy -- so from then on a shared webspace deploys and rolls back through exactly the same atomic current swap as a machine we own; - on this machine (Target::isLocal) the vhost would be the developer's own Apache, and postInstall a sudo run on their workstation.
Idempotent by construction (`mkdir -p`), so it is safe to keep it at the head of every pipeline rather than having a separate "is this target installed?" branch -- which is what the old script needed, and what made first-deploy a different, less-tested code path than every subsequent deploy. Anything site-specific (a web-server vhost, a systemd unit, a logrotate file) is configuration, not code: pass it as [`$templates`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/InstallTask.md#installtask-templates), a map of `local template file => remote destination`, and [`$postInstall`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/InstallTask.md#installtask-postinstall), the command that puts them to use. Each template's `{placeholders}` are resolved against the target ([`Target::resolveTemplate`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/entities/Target.md#target-resolvetemplate)). Both run on a server of ours: the first time, and then only when what they write or run has changed ([`STAMP`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/InstallTask.md#installtask-stamp)). Nowhere else: - on a host whose web server is not ours ([`Server::$managed`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/entities/Server.md#server-managed)) there IS no vhost to template, and no sudo to enable one: the document root is a fixed path chosen in a control panel. The plan says which of the two a target is, so a skipped vhost is never mistaken for an installed one. A target installed by an earlier version kept mmo.admin's own state in `shared/`, beside every release's tarball: [`moveLegacyState`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/InstallTask.md#installtask-movelegacystate) moves the state into `deploy/` and `backups/` and deletes the tarballs, once.

Index

LEGACYwhat an earlier version kept in shared/, relative to it: its own state, and the tarballs.
STAMPThe stamp, in the target's deploy/, of the templates and the command that last ran to the end on the target: a sha256 of what they wrote and ran, placeholders resolved.
postInstall
sharedMode
templates
apply($context)
getDescription()
getExclusion($context)
getLegacyState($context)
getStamp($context, $files)
getStampFilename($context)
isNeeded($context)Nothing to do once the layout is in place, the web root linked and the templates unchanged since they last ran -- which is the normal case on every deploy but the first.
isProvisionNeeded($context)
isRealFolder($context, $path)
isWebRootLinked($context)
linkWebRoot($context)Make the path the host serves resolve to the live release.
moveLegacyState($context)Move what an earlier version kept in shared/ where it now belongs, and delete the tarballs it kept there.
plan($context)
planProvision($context)
provision($context)Write the templates and run the postInstall where they belong, when they have to -- then stamp the target with what ran, so the next run can tell.
provisions()
readStamp($context)
render($context)
verify($context)
__construct($templates, $postInstall, $sharedMode)

Constants2

LEGACY

what an earlier version kept in shared/, relative to it: its own state, and the tarballs. moveLegacyState

const LEGACY = ['deployments.json', '.install', 'db/backups', 'artifacts']

STAMP

The stamp, in the target's deploy/, of the templates and the command that last ran to the end on the target: a sha256 of what they wrote and ran, placeholders resolved.

const STAMP = '.install'Neither leaves anything to look at afterwards -- the project template stages its vhost in /tmp, and its `postInstall` moves it away -- so `install` could not tell an installed vhost from a changed one, and used to run both on every release: the vhost rewritten, Apache reloaded, and a release that changed nothing journaled as a deployment. Written last, so a `postInstall` that failed runs again next time.

Properties3

postInstall

protected ?string $postInstall
Type
null | string

sharedMode

protected ?int $sharedMode
Type
null | int

templates

protected array $templates
Type
array

Methods20

getExclusion($context)

InstallTask.php:257
protected function getExclusion(MMO\admin\helpers\Context $context): ?string
$contextContext
returnsnull | stringwhy the templates and postInstall have no business on this target, null when they do.

getLegacyState($context)

InstallTask.php:149
protected function getLegacyState(MMO\admin\helpers\Context $context): array
$contextContext
returnsarraythe paths of LEGACY the target still has in shared/.

getStamp($context, $files)

InstallTask.php:338
protected function getStamp(MMO\admin\helpers\Context $context, array $files): string
$contextContext
$filesarray
returnsstringone hash of everything the templates and postInstall write and run on this target.

isNeeded($context)

InstallTask.php:64

Nothing to do once the layout is in place, the web root linked and the templates unchanged since they last ran -- which is the normal case on every deploy but the first.

function isNeeded(MMO\admin\helpers\Context $context): bool
$contextContext
returnsbool

isProvisionNeeded($context)

InstallTask.php:265
protected function isProvisionNeeded(MMO\admin\helpers\Context $context): bool
$contextContext
returnsboolwhether the templates and postInstall have to run on this target: never yet, changed since, or forced.

isRealFolder($context, $path)

InstallTask.php:208
protected function isRealFolder(MMO\admin\helpers\Context $context, string $path): bool
$contextContext
$pathstring
returnsboolwhether $path exists on the target and is NOT a symlink -- i.e. replacing it destroys something.

isWebRootLinked($context)

InstallTask.php:200
protected function isWebRootLinked(MMO\admin\helpers\Context $context): bool
$contextContext
returnsboolwhether the host-fixed document root already resolves to the live release (true when there is none to point).

linkWebRoot($context)

InstallTask.php:227

Make the path the host serves resolve to the live release.

protected function linkWebRoot(MMO\admin\helpers\Context $context): voidThe whole deployment model rests on `current` being swappable, and on a managed webspace the one thing that cannot be swapped is which path Apache is pointed at. Linking it here, once, is what restores the model: after this, `activate` and `rollback` move `current` and the served tree follows, with no control panel and no vhost involved. Whatever was at that path is MOVED, never deleted. It is very often the provider's `htdocs`, with a live site in it -- `rm -rf` on the one path a customer's domain resolves to is not a decision a deployment tool gets to make on its own, and a move is a decision a human can undo with one command.
$contextContext
returnsvoid

moveLegacyState($context)

InstallTask.php:165

Move what an earlier version kept in shared/ where it now belongs, and delete the tarballs it kept there.

protected function moveLegacyState(MMO\admin\helpers\Context $context): voidThe journal is what `rollback` and `status` read, and the record of the patches already applied: it is MOVED, archives included, never left behind -- and read again, since the plan read it at its new place, where it was not yet, and appending to that would have replaced the history. A file already at the new place is not overwritten. `shared/` goes once empty: a target that shares nothing has none -- and the `.htaccess` guarding it, uploaded by hand on a webspace, then guards `deploy/` instead, which holds what it did.
$contextContext
returnsvoid

planProvision($context)

InstallTask.php:271
protected function planProvision(MMO\admin\helpers\Context $context): array
$contextContext
returnsarraywhat the plan says about the templates and postInstall on this target -- skipped ones included.

provision($context)

InstallTask.php:299

Write the templates and run the postInstall where they belong, when they have to -- then stamp the target with what ran, so the next run can tell. STAMP

protected function provision(MMO\admin\helpers\Context $context): void
$contextContext
returnsvoid

provisions()

InstallTask.php:251
protected function provisions(): bool
returnsboolwhether there are templates to write or a command to run at all.

readStamp($context)

InstallTask.php:343
protected function readStamp(MMO\admin\helpers\Context $context): ?string
$contextContext
returnsnull | stringthe stamp the target holds, null when nothing ever ran to the end there.

render($context)

InstallTask.php:322
protected function render(MMO\admin\helpers\Context $context): array
$contextContext
returnsarraystring> each template's destination on the target => its content, placeholders resolved.
throwswhen a template is missing here.

__construct($templates, $postInstall, $sharedMode)

InstallTask.php:49
function __construct( array $templates = [], ?string $postInstall = null, ?int $sharedMode = null )
$templates = []array
$postInstall = nullnull | string
$sharedMode = nullnull | int
Inherited members (38)
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
verbosityaDeployTask
MethodsDeclared byDescription
alert($message, $context)aDeployTaskAction must be taken immediately.
backtraces($message, $context)aDeployTaskForce-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).
critical($message, $context)aDeployTaskCritical conditions. No-op if CRITICAL is currently filtered out by the verbosity mask.
debug($message, $context)aDeployTaskDetailed debug information.
debugName()aDeployTask
emergency($message, $context)aDeployTaskSystem is unusable. No-op if EMERGENCY is currently filtered out by the verbosity mask.
error($message, $context)aDeployTaskRuntime errors that do not require immediate action but should typically be logged and monitored.
getName()aDeployTask
getVerbosity()aDeployTask
info($message, $context)aDeployTaskInteresting events. No-op if INFO is currently filtered out by the verbosity mask.
isChange()aDeployTaskWhether running this task CHANGES anything.
isRollbackCritical()aDeployTask
log($level, $message, $context)aDeployTaskLogs with an arbitrary level.
notice($message, $context)aDeployTaskNormal but significant events.
rollback($context)aDeployTaskUndo this task. Called by the runner, in reverse order, for every task already applied when a later one failed.
setVerbosity($verb)aDeployTaskSet the current verbosity mask, replacing whatever it was before.
testVerbosity($level)aDeployTaskTest whether a given level (or set of levels) is currently enabled by this instance's verbosity mask.
warning($message, $context)aDeployTaskExceptional occurrences that are not errors.