MMOframework
Why AI Playground Libraries Documentation Search Agency
FR EN
Index

DeveloperShellController

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

class

DeveloperShellController

DeveloperShellController.php:29

The developer mode from the command line (DeveloperController, DeveloperMode):

class MMO\admin\controllers\DeveloperShellController extends MMO\core\classes\aShellController
Namespace
MMO\admin\controllers
Extends
aShellController
See
ROLES on this instance (mmo.oauth), and gives them to users: run it on every project, every server; - developer pages [--write] gives the board's tickets their pages from what already names them; - developer pull --target=dev [--remote=<git url>] [--dry-run] brings a server's inbox onto the board of this machine; - developer test-accounts [--checklist=<name>] [--dry-run] makes the test accounts of the checklists' profiles (recipe.accounts, TestAccounts) this machine's database lacks; - developer test-data [--checklist=<name>] [--dry-run] [--archive] makes the test records of the checklists (recipe.testData, TestData) in this machine's database, or archives them. -m answers in json.
- `developer roles [--assign=marc:project lead,jeanne:tester] [--dry-run]` makes or brings up to date the roles of Listed by mmo.admin's bootstrap among core's AdminController's commands: `php admin.php developer ...`.
php admin.php developer roles --assign=god:project lead --dry-runphp admin.php developer pull --target=dev --dry-runphp admin.php developer test-accounts --checklist=my.oviepro-5.0.1 --dry-runphp admin.php developer test-data --checklist=my.oviepro-5.0.1 --dry-run

Index

ROLESThe roles of the developer mode: label => [description, scopes, modes].
groupsCollection
testAccountsFile
testDataFile
testDataRepository
developer()
json($route, $report)
recipes($only)
remoteOf($name, $folder)The server's inbox of a target of deploy.json: ssh://{alias}{shared}/{folder}, the folder ({db}/developer) read in its shared paths (db is one).
route_pages($route)
route_pull($route)
route_roles($route)
route_test_accounts($route)Make the test accounts of the checklists' profiles (recipe.accounts) this machine's database lacks: their roles, their groups, no password anyone knows -- they are opened by « Changer de compte »…
route_test_data($route)Make the test records of the checklists (recipe.testData, TestData): what each test account must see in its perimeter and must not see outside it, labelled TEST CLAUDE …, made through the …
testDataRecipe($only)
testDataRefusal($repository, $collections, $database, $mode, $config)Why test records may not be made: every collection they are made in -- and the accounts' -- must be in this machine's own database, the one configs/config.json declares, in development (Test…
testDifferences($user, $profile)
testGroups($user, $labels, $collection, $line)
testProfiles($only)

Constants1

ROLES

The roles of the developer mode: label => [description, scopes, modes]. A role's scopes not named here are left as they are (an administrator may have added some); the ones named are set.

const ROLES = […3 items]

Properties4

groupsCollection

string $groupsCollection = 'groupes'
Type
string

testAccountsFile

string $testAccountsFile = '{db}/developer/test-accounts.json'
Type
string

testDataFile

string $testDataFile = '{db}/developer/test-data.json'
Type
string

testDataRepository

string $testDataRepository = 'repository'
Type
string

Methods14

recipes($only)

DeveloperShellController.php:370
protected function recipes(string $only): array
$onlystringa checklist's name, '' for every one
returnsarraymixed> the recipes of the checklists (the ones the application declares, then their files), by name

remoteOf($name, $folder)

DeveloperShellController.php:426

The server's inbox of a target of deploy.json: ssh://{alias}{shared}/{folder}, the folder ({db}/developer) read in its shared paths (db is one).

protected function remoteOf(string $name, string $folder): array
$namestring
$folderstringthe inbox's folder, as the configuration says it ({db}/developer)
returnsarraystring, 1: string|null} the remote, and the ssh configuration to reach it

route_pages($route)

DeveloperShellController.php:386
#[MMO\core\attributes\Command([['const' => 'developer'], ['const' => 'pages']], 'give the board\'s tickets their pages, from their checks and their description: --write to save')] function route_pages(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_pull($route)

DeveloperShellController.php:396
#[MMO\core\attributes\Command([['const' => 'developer'], ['const' => 'pull']], 'bring a server\'s inbox (the tickets filed there) onto the board: --target=dev [--remote=] [--dry-run]')] function route_pull(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_roles($route)

DeveloperShellController.php:45
#[MMO\core\attributes\Command([['const' => 'developer'], ['const' => 'roles']], 'make or update the developer mode\'s roles (developer, tester, project lead), and give them: --assign=user:role,...')] function route_roles(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

route_test_accounts($route)

DeveloperShellController.php:100

Make the test accounts of the checklists' profiles (recipe.accounts) this machine's database lacks: their roles, their groups, no password anyone knows -- they are opened by « Changer de compte » (the checklists' « Open as »).

#[MMO\core\attributes\Command([['const' => 'developer'], ['const' => 'test-accounts']], 'make the test accounts of the checklists\' profiles (recipe.accounts) missing from this machine\'s own database: [--checklist=<name>] [--dry-run]')] function route_test_accounts(MMO\core\server\Route $route): voidOnly in the database `configs/config.json` declares, on this machine, in development ([`TestAccounts::DatabaseRefusal`](https://mmoframework.fr/en/documentation/mmo.admin/php/helpers/TestAccounts.md#testaccounts-databaserefusal)): never in a copy of a client's. An account that exists is left as it is, unless this command made it ([`$testAccountsFile`](https://mmoframework.fr/en/documentation/mmo.admin/php/controllers/DeveloperShellController.md#developershellcontroller-testaccountsfile)): its roles and groups are then brought back to its profile.
$routeRoute
returnsvoid

route_test_data($route)

DeveloperShellController.php:259

Make the test records of the checklists (recipe.testData, TestData): what each test account must see in its perimeter and must not see outside it, labelled TEST CLAUDE …, made through the application's entities as the account by names. Only in the database configs/config.json declares, on this machine, in development (TestAccounts::DatabaseRefusal, as test-accounts). A record it made is never made again ($testDataFile), a record it did not make is never changed; --archive archives what it made.

#[MMO\core\attributes\Command([['const' => 'developer'], ['const' => 'test-data']], 'make the test records of the checklists (recipe.testData) in this machine\'s own database: [--checklist=<name>] [--dry-run] [--archive]')] function route_test_data(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

testDataRecipe($only)

DeveloperShellController.php:341
protected function testDataRecipe(string $only): array
$onlystringa checklist's name, '' for every one
returnsarrayarray{prefix: string, by: ?string, records: array<string, array>, order: list<string>, expect: list<array>}, 1: list<string>} the test records of the checklists (TestData::Recipe), merged by key -- two checklists giving one key must give it the same record --, and what was refused

testDataRefusal($repository, $collections, $database, $mode, $config)

DeveloperShellController.php:306

Why test records may not be made: every collection they are made in -- and the accounts' -- must be in this machine's own database, the one configs/config.json declares, in development (TestAccounts::DatabaseRefusal).

function testDataRefusal( object $repository, array $collections, ?string &$database = null, ?string $mode = null, ?string $config = null ): ?string
$repositoryobjectthe application's
$collectionsarraythe records' collections
$database = nullnull | stringset to the database's name
$mode = nullnull | stringthe instance's (MMO_MODE by default)
$config = nullnull | stringconfigs/config.json as it is written (this instance's by default)
returnsnull | stringthe refusal, null when they may
$shell->testDataRefusal(\MMO\getInstance('repository'), ['contrats'], $database); // null, $database 'demo'

testDifferences($user, $profile)

DeveloperShellController.php:234
protected function testDifferences(object $user, array $profile): array
$userobject
$profilearray
returnsarraylist<string>, extraRoles?: list<string>, missingGroups?: list<string>, extraGroups?: list<string>} how an account's roles and groups differ from its profile's; empty when they do not

testGroups($user, $labels, $collection, $line)

DeveloperShellController.php:217
protected function testGroups( ?object $user, array $labels, ?MMO\core\interfaces\iCollection $collection, array &$line ): ?array
$usernull | objectthe account, null for one to make
$labelsarraythe groups a profile names
$collectionnull | iCollectionthe accounts' collection
$linearraythe report's line: its error set when a group cannot be given
returnsnull | arraythe groups, null when the profile names none

testProfiles($only)

DeveloperShellController.php:188
protected function testProfiles(string $only): array
$onlystringa checklist's name, '' for every one
returnsarrayarray<string, array{keys: list<string>, label: string, roles: list<string>, groups: list<string>}>, 1: list<string>} the profiles of the checklists (their files, and the ones the application declares), by username -- two profiles naming one account must give it the same roles and groups --, and what was refused
Inherited members (65)
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
index($route)aShellControllerThe built-in interactive REPL: shows the splash + command list, then loops reading a command name (with autocompletion, via ask) and dispatching it through callInteractive…
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.
onRoute($route)aShellControllerSame as aController::onRoute, plus: forces the response to shell/text output, and decides whether to fall back to the built-in interactive index command -- it stays active only if this is…
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…