MMOframework
Pourquoi l'IA Playground Bibliothèques Documentation Rechercher Agence
FR EN
Index

Store

MMO\admin\helpers · 1 symbole · générée le 27 Oct 2026

class

Store

Store.php:35

Everything the deployment tooling knows, as entities: which projects exist, which machines they run on, which targets live on those machines, and what has actually been deployed to each.

class MMO\admin\helpers\Store
Espace de noms
MMO\admin\helpers
Voir
Target collections. The store NEVER writes this file, and no deployment does. A deployment topology is reviewed source, not application state, and a tool that can rewrite it is a tool that can quietly change where a release goes. SetupWizard edits it -- only once a person has answered and read the diff. 2. The history -- a JsonRepository at .mmo/deploy.history.json in the project (HISTORY), filled by sync -- and after every deployment -- from each target's own journal. This one is ordinary, writable state, and it is what the dashboard reads for a fleet-wide view without connecting to 27 machines to draw a page. It is this machine's record, not the project's: git-ignored, and readable by you alone., Credentials, and every ssh alias through SshConfig, from files beside the declaration git ignores. deploy.json is checked for secret-shaped keys on load (assertNoSecrets) and refuses to parse if it has any, so the previous pipeline's failure -- a production password committed to 31 branches -- cannot be repeated by someone taking the obvious shortcut.
Two stores in one, deliberately: 1. **The declaration** -- `deploy.json`, committed and code-reviewed, read into [`Project`](https://mmoframework.fr/fr/documentation/mmo.admin/php/entities/Project.md#project) / [`Server`](https://mmoframework.fr/fr/documentation/mmo.admin/php/entities/Server.md#server) / Nothing it reads or writes is outside the project folder. Everything secret is resolved through
$store = Store::FromFile('{root}/deploy.json'); $store->getTargets()->getById('demo'); $store->getDeployments()->query(['target' => 'demo'], sort: ['-date']);

Index

HISTORYwhere a project keeps this machine's deployment history, relative to the folder of deploy.json.
SECRETSkeys that must never appear in the committed declaration, whatever level they appear at.
credentials
filename
history
historyFilename
projectName
projects
servers
sshConfig
targets
assertLoaded($entity, $what)Refuse an entity whose data did not survive being loaded.
assertNoSecrets($data, $path)Refuse a declaration carrying anything secret-shaped, at any depth.
assertRow($row, $class, $what)Refuse a record carrying a key the entity does not declare.
debugName()
FromFile($filename, $credentialsFilename, $history, $sshConfigFilename) static
getCredentials()
getDeployments()
getFilename()
getHistory($target, $count)
getHistoryFilename()
getHistoryRepository()
getProject($name)
getProjectName()
getProjects()
getServer($name)
getServers()
getSshConfig()
getTargets()
hasHistory()
loadProjects($data)
loadServers($data)
loadTargets($data)Every target as it is written: nothing is inherited, so reading a target is reading what it is.
mirror($entries)Merge a target's own journal into the local history, skipping what is already there.
saveHistory()Write what mirror added.
StateFilename($root) staticWhere a project's synced history lives on this machine: HISTORY, in the project.
stripComments($data)Drop every //-prefixed key, at any depth.
suggest($key, $known)
__construct($data, $filename, $credentials, $stateFilename, $sshConfig)

Constantes2

HISTORY

where a project keeps this machine's deployment history, relative to the folder of deploy.json.

const HISTORY = '.mmo/deploy.history.json'

SECRETS

keys that must never appear in the committed declaration, whatever level they appear at.

const SECRETS = […9 items]

Propriétés9

credentials

protected ?MMO\admin\helpers\Credentials $credentials = null
Type
null | Credentials

filename

protected ?string $filename = null
Type
null | string

history

protected ?MMO\core\entities\JsonRepository $history = null
Type
null | JsonRepository

historyFilename

protected ?string $historyFilename = null
Type
null | string

projectName

protected ?string $projectName = null
Type
null | string

projects

protected MMO\core\entities\Collection $projects
Type
Collection

servers

protected MMO\core\entities\Collection $servers
Type
Collection

sshConfig

protected ?MMO\admin\helpers\SshConfig $sshConfig = null
Type
null | SshConfig

targets

protected MMO\core\entities\Collection $targets
Type
Collection

Méthodes28

assertLoaded($entity, $what)

Store.php:310

Refuse an entity whose data did not survive being loaded.

protected function assertLoaded(object $entity, string $what): voidAn entity records a value it could not coerce in [`aEntity::getErrors`](https://mmoframework.fr/fr/documentation/mmo.core/php/classes/aEntity.md#aentity-geterrors) and carries on with the property at its default -- which, for a deployment declaration, is silence where there should be a stop. A `vars` map that failed to coerce leaves `{placeholders}` unresolved in a path; a `shared` list that failed leaves live data inside a release, to be deleted by the next prune. Neither is something to find out about on a server.
$entityobject
$whatstring
retournevoid
lève

assertNoSecrets($data, $path)

Store.php:444

Refuse a declaration carrying anything secret-shaped, at any depth.

protected function assertNoSecrets(array $data, string $path = ''): voidThis is the structural half of keeping credentials out of git: `.gitignore` and code review are both things a hurried person skips, and the previous pipeline shows what that costs. A tool that will not START with a password in its configuration cannot be talked into committing one.
$dataarray
$path = ''string
retournevoid
lève

assertRow($row, $class, $what)

Store.php:401

Refuse a record carrying a key the entity does not declare.

protected function assertRow(mixed $row, string $class, string $what): arraySilently ignoring unknown keys is what made the previous configuration dangerous rather than merely untidy: `"datbase"` produced a target with NO database, so `migrate` and `backup` quietly did nothing on it -- the tool reported success and the patches were simply never applied.
$rowmixed
$classstringthe entity class the record describes.
$whatstringhow to name it in an error.
retournearray$row, unchanged.
lève

FromFile($filename, $credentialsFilename, $history, $sshConfigFilename)

staticStore.php:99
static function FromFile( string $filename, ?string $credentialsFilename = null, bool $history = true, ?string $sshConfigFilename = null ): static
$filenamestringthe declaration, resolved through filename.
$credentialsFilename = nullnull | stringnull: deploy.credentials.json beside the declaration (Credentials::DefaultFilename).
$history = trueboolload/persist the synced deployment history as well.
$sshConfigFilename = nullnull | stringnull: deploy.ssh.config beside the declaration (SshConfig::DefaultFilename).
retournestatic
lèveif the declaration does not exist.

getDeployments()

Store.php:144
function getDeployments(): MMO\core\entities\Collection
retourneCollectionthe synced deployment history. @throws eNotFound when the store carries none.

getHistory($target, $count)

Store.php:249
function getHistory(?string $target = null, int $count = 20): array
$target = nullnull | stringonly this target's entries.
$count = 20int
retournearraythe most recent mirrored deployments, newest first.

getProject($name)

Store.php:185
function getProject(?string $name = null): ?MMO\admin\entities\Project
$name = nullnull | string
retournenull | Projectthe named project, or the single implicit one.

loadTargets($data)

Store.php:332

Every target as it is written: nothing is inherited, so reading a target is reading what it is.

protected function loadTargets(array $data): void
$dataarray
retournevoid
lève

mirror($entries)

Store.php:224

Merge a target's own journal into the local history, skipping what is already there.

function mirror(iterable $entries): intThe target's journal is the truth -- it is written on the machine the deployment happened to, by the run that happened -- so this only ever adds. It never edits, never deletes, and never writes back to the target: a mirror that can change its source is not a mirror.
$entriesiterableDeployment, from Journal::all.
retourneinthow many entries were new.

saveHistory()

Store.php:161

Write what mirror added.

function saveHistory(): voidThe file is created private -- its folder 0700, itself 0600 -- before anything is written in it: who deployed what, when and from where is this machine's business, and it is not shared through git either.
retournevoid

StateFilename($root)

staticStore.php:129

Where a project's synced history lives on this machine: HISTORY, in the project.

static function StateFilename(string $root): string
$rootstringthe project's folder -- the one holding deploy.json.
retournestring

stripComments($data)

Store.php:379

Drop every //-prefixed key, at any depth.

protected function stripComments(array $data): arrayJSON has no comments, and a file that decides which machine a release lands on is exactly the kind of file that needs them. The convention costs nothing (`"//shared": "why these paths"` beside `"shared"`) and it means the strict key check below can stay strict: a key that is not a comment and not a declared property is a typo, and typos in this file are how a target quietly stops being backed up.
$dataarray
retournearray

suggest($key, $known)

Store.php:421
protected function suggest(string $key, array $known): string
$keystring
$knownarray
retournestring' Did you mean [x]?' when a close-enough key exists, '' otherwise.

__construct($data, $filename, $credentials, $stateFilename, $sshConfig)

Store.php:66
function __construct( array $data = [], ?string $filename = null, ?MMO\admin\helpers\Credentials $credentials = null, ?string $stateFilename = null, ?MMO\admin\helpers\SshConfig $sshConfig = null )
$data = []arraythe decoded declaration ({project, projects, servers, targets}).
$filename = nullnull | stringfor error messages only.
$credentials = nullnull | Credentialsresolved secrets, injected into every server.
$stateFilename = nullnull | stringwhere the synced history lives (null: no history).
$sshConfig = nullnull | SshConfigthe project's ssh aliases, injected into every server.