MMOframework
Why AI Playground Libraries Documentation Search Agency
FR EN
Index

RepositoryController

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

class

RepositoryController

RepositoryController.php:47

Controller used to handle entities through the repositories

class MMO\core\controllers\RepositoryController extends MMO\core\classes\aController implements MMO\core\interfaces\iRoutable
Namespace
MMO\core\controllers
Extends
aController
Implements
iRoutable
WARNING: all date MUST be sent as ISO 8601 (javascript function date.toISOString()): YYYY-MM-DDTHH:mm:ss.ccc(+|-)HH:mm ## Route `data` Collections can be accessed through the url `data/{repository}/{collection}.{format}` - {repository} the repository's name - {collection} the collection's name in the repository - {format} is the output format of the answer (supported: json|csv) - GET: list the entities - POST: insert/update entities - PUT: update entities by id - DELETE: delete entities ### Supported query - pagination : ?page[offset]=0&page[limit]=10 - sorting : ?sort=-created,title - fields : ?fields=articles.title,-articles.body,people.name - filters : ?filters[age][$>]=20&filters[age][$<]=50&filters[author.status]=active - list only id : ?onlydIds - search : ?search[type]=$text&search[text]=test: will do a search of type `$text` using the value text = 'test' ## Route `schemas` GET|data/schemas.json This route return all the schemas for every available entity class served by the repositories: {class: Schema} Its url carries the version of its content (`?v=`, [`SchemaUrl`](https://mmoframework.fr/en/documentation/mmo.core/php/controllers/RepositoryController.md#repositorycontroller-schemaurl)): asked with it, the browser keeps it.

Index

API_PARAMETERS_INFO
query
repositories
xlsxTplFilename
checkItems($entity, $data)Refuse a write one of whose values holds an item that could not be converted (an unknown uid in a list): the entity kept that property's previous value -- a new list item's parent, an empty list --…
checkKnownProperties($collection, $entries)Refuse to create an entity from an entry none of whose keys is a property of its class: loadArray() drops an unknown key (logged only), so a body in another format -- wrapped ({"data": {...}}), a…
checkUnique($route, $collection, $data)Refuse to create an entity that has the values of an existing one on one of its class's @unique groups (its own, its parent classes' and their traits': classUniqueGroups): …
checkUniqueChanges($route, $collection, $entity)Refuse an update that gives an entity the values another entity of its collection has on one of its class's @unique groups (an archived one included): a list sent again without id, found by one…
ClassFiles($class) static
CollectionUrl($collection, $repository, $extension, $query) static
ConnectRoutes($routes, $config) staticCalled once when routes are registered: adds the actual list of configured repository/collection names as an enum constraint onto every route's repository/collection API parameter info (so ge…
createEntity($collection, $data, $status)Create an entity of $collection with $data, its status set through its setStatus() -- the one asked, or its class's default: born a draft, it goes through the guards a draft leaving the draft goes …
extractStatus($route, $data)Take the status out of an entry, to set it with iEntity::setStatus once the rest is loaded: loaded with it, it skipped the entity's own setStatus() and its guards (a declaration only leaves th…
getCollection($name, $repository)
getCollectionOf($class)Where the entities of $class are listed from: the collection of a repository served whose class it is, or, for a class no collection holds (an abstract one), the one collection holding a class of i…
getPatchValues($route, $entity, $data)What a PATCH's entry asks, checked before anything changes: its status, or the items it pushes onto list properties.
getQuery()
getRepositories()
getRepository($name)
getRepositoryName($repo)
getSchemaClasses()
getSchemaDefs()The $defs of the schemas document (routeSchemas): the schema of every class served, and of every class they use, each class held by a collection of a repository served given its `$collection…
getUrlId($route)
getWriteEntities($route, $collection, $entries)The entities a write's entries name, all found before anything changes: one id that names no entity refuses the whole request, as an entry naming none clearly does (getWriteEntries).
getWriteEntries($route, $needsId)The entries of a write's body (PUT, POST, PATCH, DELETE), each naming the entity it is for without ambiguity, all checked before anything changes: one that does not refuses the whole request.
hasCollection($collection, $repository)
isListed($entity)Tell if a query of $entity's collection, dispatched as a listing's (routeGet), keeps it: its listeners decide (mmo.oauth's AccessController, an application's filter by client)
onRoute($route)
routeDelete($route)Delete entities by id -- archives an active entity (iEntity::archive), or permanently removes an already-archived one.
routeEntity($route)Fetch a single entity by its global uid (fetch), regardless of which repository/collection it's in.
routeGet($route)List entities from one collection: pagination, sort, field selection, filters, and text/property search (the class docblock's "Supported query" section), plus first/prev/next/last pagination l…
routePatch($route)Partially update entities by id -- either sets a new cStatus (via a 'status' key), or pushes one or more values onto array properties (any other key, optionally a `path/to/n…
routePost($route)Insert or update entity with similar data (using groups or id)
routeSchemas($route)Asked with its version (?v=, the url SchemaUrl gives), the document is kept by the browser for a year: another version is another url.
routeUpdate($route)Update entity only by id
SchemasVersion() staticA fingerprint of the schemas document (routeSchemas): the hash of its content.
SchemaUrl($entity) staticThe url of the schemas document, versioned (?v=, SchemasVersion): the browser keeps it (routeSchemas) until the schemas change, and an entity changed, a release or another language make…
setRepositories($repositories)Replace every registered repository (Serialize -- this is the injection target for the repositories config key, e.g.
uniqueConflict($route, $collection, $keys, $other)
writeAll($fn)Run a write's $fn: when it throws, the entities it changed are ignored, the commit of something else later in the request (a journal, a log) not saving half of a write refused

Constants1

API_PARAMETERS_INFO

const API_PARAMETERS_INFO = ['parameters' => […10 items]]

Properties3

query

protected ?MMO\core\entities\Query $query = null
Type
null | Query

repositories

#[MMO\core\attributes\Serialize(unserialize: 'setRepositories')] protected array $repositories = []
Type
array

xlsxTplFilename

?string $xlsxTplFilename = null
Type
null | string

Methods36

checkItems($entity, $data)

RepositoryController.php:502

Refuse a write one of whose values holds an item that could not be converted (an unknown uid in a list): the entity kept that property's previous value -- a new list item's parent, an empty list -- and the write answered 200 as if all had been saved (my.oviepro #228). A value that cannot be set as a whole (a draft's empty date) is still taken, and said in the entity's errors.

protected function checkItems(MMO\core\interfaces\iEntity $entity, array $data): void
$entityiEntityjust loaded with $data
$dataarraywhat the client sent for it
returnsvoid
throws(422) naming each item from the entity, and why: nothing is changed
PUT `{"id": "12", "suiviDossier": {"arrets": [{"uid": "unknown"}]}}`: 422, `[suiviDossier/arrets/0] unknown entity identifier [unknown].`

checkKnownProperties($collection, $entries)

RepositoryController.php:482

Refuse to create an entity from an entry none of whose keys is a property of its class: loadArray() drops an unknown key (logged only), so a body in another format -- wrapped ({"data": {...}}), another entity's -- created an empty entity and answered 200 (my.oviepro #334). An entry with no key at all ({"id": null}, a status only, [{}]) still creates an entity of default values; one holding a known key beside unknown ones is still taken.

protected function checkKnownProperties(MMO\core\interfaces\iCollection $collection, array $entries): void
$collectioniCollection
$entriesarray
returnsvoid
throws(422) naming the unknown keys: nothing is changed
POST entreprises.json `{"data": {"label": "ACME"}}`: 422 « Nothing to create in [entreprises]: [data] is no property of its entries. »

checkUnique($route, $collection, $data)

RepositoryController.php:522

Refuse to create an entity that has the values of an existing one on one of its class's @unique groups (its own, its parent classes' and their traits': classUniqueGroups): one created by the same request included, an archived one too.

protected function checkUnique( MMO\core\server\Route $route, MMO\core\interfaces\iCollection $collection, array $data ): voidNOTE: until 2026-10 `@unique` only found the entity a POST without `id` updates: one with `"id": null` created a second account of the same username (my.oviepro #268)
$routeRoute
$collectioniCollection
$dataarray
returnsvoid
throws(409 Conflict) naming the fields of the group: nothing is changed
POST googleUsers.json `{"id": null, "username": "ada@x.com"}` when ada@x.com exists: 409 « Une fiche avec cette valeur de « Email » existe déjà. »

checkUniqueChanges($route, $collection, $entity)

RepositoryController.php:543

Refuse an update that gives an entity the values another entity of its collection has on one of its class's @unique groups (an archived one included): a list sent again without id, found by one group (a matricule) and carrying another's value of a second one (an address), or a PUT changing a unique value to one already used.

protected function checkUniqueChanges( MMO\core\server\Route $route, MMO\core\interfaces\iCollection $collection, MMO\core\interfaces\iEntity $entity ): voidOnly the groups the update changed are checked, and a group with an empty value identifies nothing. NOTE: until 2026-10 only a creation was checked ([`checkUnique`](https://mmoframework.fr/en/documentation/mmo.core/php/controllers/RepositoryController.md#repositorycontroller-checkunique)): an update gave two accounts the same username, or the matricule of another account to the one its address named (my.oviepro #350)
$routeRoute
$collectioniCollection
$entityiEntity
returnsvoid
throws(409 Conflict) naming the fields of the group: nothing is changed (writeAll)
POST googleUsers.json `{"eid": "1", "username": "bob@x.com"}` when bob@x.com is another's: 409

ClassFiles($class)

staticRepositoryController.php:221
protected static function ClassFiles(string $class): array
$classstring
returnsarraythe files $class is written in: its own, its parents', its interfaces' and its traits'

CollectionUrl($collection, $repository, $extension, $query)

staticRepositoryController.php:140
static function CollectionUrl( string $collection, string $repository = 'main', string $extension = 'json', MMO\core\helpers\FilterGroup|array|string $query = '' ): string
$collectionstring
$repository = 'main'string
$extension = 'json'string
$query = ''FilterGroup | array | stringa query string, or filters to encode into one (apiQuery).
returnsstringthe URL for routeGet on this collection.

ConnectRoutes($routes, $config)

staticRepositoryController.php:79

Called once when routes are registered: adds the actual list of configured repository/collection names as an enum constraint onto every route's repository/collection API parameter info (so generated API docs/validation know the real allowed values, instead of just 'string').

static function ConnectRoutes(array &$routes, array $config): void
$routesarray
$configarrayunused directly -- get is used instead to read this controller's own configured repositories.
returnsvoid

createEntity($collection, $data, $status)

RepositoryController.php:453

Create an entity of $collection with $data, its status set through its setStatus() -- the one asked, or its class's default: born a draft, it goes through the guards a draft leaving the draft goes through.

protected function createEntity( MMO\core\interfaces\iCollection $collection, array $data, ?MMO\core\entities\cStatus $status ): MMO\core\interfaces\iEntityA status other than the default stays a change of the entity created: the commit's listeners check the right to set it (mmo.oauth's AccessController: `data#final`, `data#validated`), as for an entity changed. NOTE: until 2026-10 the status was loaded with the data, never checked: a declaration created by the api was active, incomplete (#142), and a client without the right to validate created an entity validated.
$collectioniCollection
$dataarray
$statusnull | cStatus
returnsiEntity
throwswhat setStatus() throws (eInvalid 422 for an incomplete declaration): the entity is then ignored
$this->createEntity($collection, ['numero' => '12'], cStatus::ACTIVE);

extractStatus($route, $data)

RepositoryController.php:433

Take the status out of an entry, to set it with iEntity::setStatus once the rest is loaded: loaded with it, it skipped the entity's own setStatus() and its guards (a declaration only leaves the draft complete and valid)

protected function extractStatus(MMO\core\server\Route $route, array &$data): ?MMO\core\entities\cStatus
$routeRoute
$dataarray
returnsnull | cStatusthe status asked, by its value or its name, whatever its case (draft, DRAFT); null for none
throws(400 Bad Request) for a status that is none of cStatus
$this->extractStatus($route, $data); // cStatus::DRAFT for ['status' => 'draft', ...]

getCollection($name, $repository)

RepositoryController.php:319
function getCollection(string $name, ?string $repository = null): MMO\core\interfaces\iCollection
$namestring
$repository = nullnull | stringif given, only look in that repository; if null, search every registered one.
returnsiCollection
throwsif no matching collection is found.

getCollectionOf($class)

RepositoryController.php:260

Where the entities of $class are listed from: the collection of a repository served whose class it is, or, for a class no collection holds (an abstract one), the one collection holding a class of its kind. A client lists the entities a reference can point to from it (mmo.client's <mmo-search>).

function getCollectionOf(string $class): ?arrayNOTE: until 2026-10 the schemas did not tell it, and mmo.client guessed it from the class's name (`Contrat` in `contrats`), which an abstract class (`aGroupe`) or a collection named otherwise defeated (my.oviepro #279)
$classstring
returnsnull | arraystring, collection: string} null when no collection, or several, may hold it
$controller->getCollectionOf(Contrat::class); // ['repository' => 'main', 'collection' => 'contrats']

getPatchValues($route, $entity, $data)

RepositoryController.php:986

What a PATCH's entry asks, checked before anything changes: its status, or the items it pushes onto list properties.

protected function getPatchValues( MMO\core\server\Route $route, MMO\core\interfaces\iEntity $entity, array $data ): arrayEach key other than `id` and `status` names a list property of the entity, or of an entity inside it (`path/to/list`, `commentaires` or `suiviDossier/arrets`); its value is one item, or a list of items.
$routeRoute
$entityiEntity
$dataarray
returnsarray?cStatus, pushes: list<array{entity: iEntity, key: string, path: string, items: list<mixed>}>} the status asked (the entry's other keys are then ignored, as they always were), or what to push where
throws(400 Bad Request) for an unknown status, a key whose path leads to no entity, or that names no list property: a PATCH only pushes items, a PUT sets a value
$this->getPatchValues($route, $entity, ['id' => '12', 'tags' => 'x']); // ['status' => null, 'pushes' => [[$entity, 'tags', 'tags', ['x']]]]

getSchemaDefs()

RepositoryController.php:239

The $defs of the schemas document (routeSchemas): the schema of every class served, and of every class they use, each class held by a collection of a repository served given its $collection (getCollectionOf).

function getSchemaDefs(): array
returnsarraySchema|array<string, mixed>>
$controller->getSchemaDefs()['App\User']['$collection']; // ['repository' => 'main', 'collection' => 'users']

getUrlId($route)

RepositoryController.php:348
protected function getUrlId(MMO\core\server\Route $route): ?string
$routeRoute
returnsnull | stringthe entity the url names (?id=), or null when it names none
throws(400 Bad Request) for an id that is not a single value
$this->getUrlId($route); // '12' for `PUT data/main/users.json?id=12`

getWriteEntities($route, $collection, $entries)

RepositoryController.php:411

The entities a write's entries name, all found before anything changes: one id that names no entity refuses the whole request, as an entry naming none clearly does (getWriteEntries).

protected function getWriteEntities( MMO\core\server\Route $route, MMO\core\interfaces\iCollection $collection, array $entries ): arrayNOTE: until 2026-10 an unknown id was skipped and logged, the request answering 200 with the other entries written (#141)
$routeRoute
$collectioniCollection
$entriesarray
returnsarraythe entity of each entry, at its index; null for an entry without an id (a POST's creation)
throwsnaming every unknown id: nothing is changed
$this->getWriteEntities($route, $collection, [['id' => '12']]); // [the entity 12], or a 404

getWriteEntries($route, $needsId)

RepositoryController.php:370

The entries of a write's body (PUT, POST, PATCH, DELETE), each naming the entity it is for without ambiguity, all checked before anything changes: one that does not refuses the whole request.

protected function getWriteEntries(MMO\core\server\Route $route, bool $needsId = true): array- `?id=` in the url names one entity: the body then holds that one only, its `id` left out (it is the url's) or the same. A DELETE or a PATCH... with no body is for that entity; - otherwise every entry of a PUT, a PATCH or a DELETE gives its `id`; a POST's entry without one creates an entity (or finds one with the same data: [`routePost`](https://mmoframework.fr/en/documentation/mmo.core/php/controllers/RepositoryController.md#repositorycontroller-routepost)). NOTE: until 2026-10 the url's `?id=` was ignored and an entry without an `id` skipped, the request answering 200: a client that had taken the wrong entity's data for its own (a listing's first, its `?id=` being ignored too) changed that one, believing it was naming the entity of its url (#141)
$routeRoute
$needsId = trueboolfalse for a POST
returnsarraymixed>> the entries, an entry named by the url holding its id
throws(400 Bad Request) for a body that is not a list of objects, an entry without an id (when $needsId), an id that is not a value, a body of several entries or naming another entity than the url
$this->getWriteEntries($route); // [['id' => '12', 'name' => 'Ada']] for `PUT users.json?id=12` {"name": "Ada"}

hasCollection($collection, $repository)

RepositoryController.php:332
function hasCollection( MMO\core\interfaces\iCollection|string $collection, ?string $repository = null ): bool
$collectioniCollection | string
$repository = nullnull | stringif given, only check that repository; if null, check every registered one.
returnsbool

isListed($entity)

RepositoryController.php:638

Tell if a query of $entity's collection, dispatched as a listing's (routeGet), keeps it: its listeners decide (mmo.oauth's AccessController, an application's filter by client)

protected function isListed(mixed $entity): bool
$entitymixed
returnsboolfalse for a value that is not an entity of a collection
$this->isListed(\MMO\fetch($this, 'file://users.json#1')); // false if a listing of users would leave it out

onRoute($route)

RepositoryController.php:288
function onRoute(MMO\core\server\Route $route): bool
See
iRoutable::onRoute -- prepares the response for this route's extension before the route's own handler runs: JSON (default), CSV, or Xlsx (optionally from a template, $xlsxTplFilename), each with a Content-Disposition: attachment filename derived from today's date and the {repository}/{collection} URL.
$routeRoute
returnsbool

routeDelete($route)

RepositoryController.php:956

Delete entities by id -- archives an active entity (iEntity::archive), or permanently removes an already-archived one.

#[MMO\core\attributes\APIRoute('DELETE|data/{repository}/{collection}.{extension}', ['parameters' => […10 items]], mediaTypes: ['json', 'csv'])] function routeDelete(MMO\core\server\Route $route): array
$routeRoutethe request body: a single {id: ...} object, or a list of them; or none, the url naming the entity (?id=): getWriteEntries.
returnsarrayevery entity archived/removed.
throwsif repository/collection doesn't resolve.
throwsif the collection is readonly.
throws(400 Bad Request) when an entry does not name its entity (getWriteEntries): nothing is changed.
throwsfor an id that names no entity (getWriteEntities): nothing is changed.

routeEntity($route)

RepositoryController.php:659

Fetch a single entity by its global uid (fetch), regardless of which repository/collection it's in.

#[MMO\core\attributes\APIRoute('GET|data.json?uid={uid}', ['parameters' => […10 items]], mediaTypes: ['json'])] function routeEntity(MMO\core\server\Route $route): arrayWhat a listing would not show is refused ([`isListed`](https://mmoframework.fr/en/documentation/mmo.core/php/controllers/RepositoryController.md#repositorycontroller-islisted)): the entity the uid names, and one of another collection that its path leads to (`...#12/author`; an embedded one, `...#12/address/0`, is its entity's). NOTE: until 2026-09 nothing was, \MMO\fetch() dispatching no query: `data.json?uid=file://users.json#1` gave any client the user that `data/main/users.json` refused it.
$routeRoute
returnsarray[the entity].
throwsif no entity matches, or a listing would leave it out.
GET data.json?uid=file://users.json#1 // [the user], if a listing of users would show it

routeGet($route)

RepositoryController.php:688

List entities from one collection: pagination, sort, field selection, filters, and text/property search (the class docblock's "Supported query" section), plus first/prev/next/last pagination links (NOTE: see the caveat on 'data.total'/'page.total'/'last' below -- task_03489439).

#[MMO\core\attributes\APIRoute('GET|data/{repository}/{collection}.{extension}', ['parameters' => […10 items]], mediaTypes: ['json', 'csv', 'xlsx'])] function routeGet(MMO\core\server\Route $route): array
$routeRoute
returnsarraythe matching entities for this page.
throwsif repository or collection doesn't resolve.

routePatch($route)

RepositoryController.php:1032

Partially update entities by id -- either sets a new cStatus (via a 'status' key), or pushes one or more values onto array properties (any other key, optionally a path/to/nested/prop for a nested entity, via iArrayProperties::setArrayPropertyOffset).

#[MMO\core\attributes\APIRoute('PATCH|data/{repository}/{collection}.{extension}', ['parameters' => […3 items]], mediaTypes: ['json', 'csv'])] function routePatch(MMO\core\server\Route $route): array
$routeRoutethe request body: a single {id, ...} object, or a list of them; the url can name the one entity of the body (?id=): getWriteEntries.
returnsarrayevery entity actually changed (an archived/final target is skipped and logged, not thrown).
throwsif repository/collection doesn't resolve.
throwsif the collection is readonly.
throws(400 Bad Request) when an entry does not name its entity (getWriteEntries), asks an unknown status, or holds a key that is no list property of the entity at its path (getPatchValues): nothing is changed.
throws(422) what the entity's setStatus() refuses, an item the list does not take: nothing is changed.
throwsfor an id that names no entity (getWriteEntities): nothing is changed. NOTE: until 2026-10 the route required an id in the body: PATCH ...json?id=12 matched no route and answered the html 404 page; a key naming a property that is not a list was a 500 (array_is_list() given a string); an unknown status, a path leading nowhere or an item refused were skipped and logged, the request answering 200 (my.oviepro #262)

routePost($route)

RepositoryController.php:889

Insert or update entity with similar data (using groups or id)

#[MMO\core\attributes\APIRoute('POST|data/{repository}/{collection}.{extension}', ['parameters' => […10 items]], mediaTypes: ['json', 'csv'])] function routePost(MMO\core\server\Route $route): array
$routeRoutethe request body: a single entity object, or a list of them. Per entity: an 'id' key with a value updates that entity; an 'id' key present but explicitly null forces creation of a new entity; no 'id' key at all looks for (or creates) an entity with matching content (Collection::getOrCreateEntity).
returnsarrayevery entity actually created or changed (an archived/final entity being updated is skipped and logged, not thrown; an unchanged existing entity is silently omitted).
throwsif repository/collection doesn't resolve.
throwsif the collection is readonly. The url can name the one entity of the body (?id=, getWriteEntries). A status goes through the entity's setStatus() once the rest is loaded; an entity created is born a draft and given the status asked, or its class's default, the same way (createEntity).
throwsif nothing ended up being inserted/updated.
throws(400 Bad Request) for an entry naming no entity clearly (getWriteEntries), or an unknown status: nothing is changed.
throws(422) what the entity's setStatus() refuses (a declaration created active but incomplete), or an entry to create none of whose keys is a property of the entity (checkKnownProperties): nothing is changed.
throwsfor an id that names no entity (getWriteEntities): nothing is changed.

routeSchemas($route)

RepositoryController.php:614

Asked with its version (?v=, the url SchemaUrl gives), the document is kept by the browser for a year: another version is another url. Without it, or with a version that is no longer the current one (a page loaded before a release), it is not kept.

#[MMO\core\attributes\APIRoute('GET|data/schemas.json', 'Get schemas for all the entities in the application', mediaTypes: ['json'])] function routeSchemas(MMO\core\server\Route $route): array
$routeRoute
returnsarraya JSON Schema document ($id/$defs) covering every entity class served by every registered repository/collection.

routeUpdate($route)

RepositoryController.php:829

Update entity only by id

#[MMO\core\attributes\APIRoute('PUT|data/{repository}/{collection}.{extension}', ['parameters' => […10 items]], mediaTypes: ['json', 'csv'])] function routeUpdate(MMO\core\server\Route $route): array
$routeRoutethe request body: a single entity object, or a list of them; each MUST have an 'id', or the url names the one entity of the body (?id=): getWriteEntries. A status goes through the entity's setStatus(), once the rest is loaded.
returnsarraythe entities that were actually changed (an archived/final entity, or no actual changes, is skipped and logged, not thrown).
throwsif repository/collection doesn't resolve.
throwsif the collection is readonly.
throws(400 Bad Request) when an entry does not name its entity (getWriteEntries), or for an unknown status: nothing is changed.
throws(422) what the entity's setStatus() refuses (an incomplete declaration validated): nothing is changed.
throwsfor an id that names no entity (getWriteEntities): nothing is changed.

SchemasVersion()

staticRepositoryController.php:175

A fingerprint of the schemas document (routeSchemas): the hash of its content. Building it costs (20 to 30 ms for my.oviepro), so it is kept in a file of {tmp}, with the mtime of every file its classes are written in; it is built again when one of them changes, or when the packages' versions, the classes served (and their collections) or the translations of the current language are others (each its own file).

static function SchemasVersion(): stringOn the command line (a test, a script) it is kept for the process only: each run serves other classes or translations, and every one left its file in `{tmp}` (my.oviepro #268).
returnsstring16 hexadecimal characters
RepositoryController::SchemasVersion(); // '3f2a9c0d81b7e645'

SchemaUrl($entity)

staticRepositoryController.php:159

The url of the schemas document, versioned (?v=, SchemasVersion): the browser keeps it (routeSchemas) until the schemas change, and an entity changed, a release or another language make another url.

static function SchemaUrl( MMO\core\interfaces\iEntity|MMO\core\interfaces\iCollection|null $entity = null ): stringNOTE: until 2026-10 the url was not versioned and the document (300 Ko for my.oviepro) not cachable: every page loaded it again before its forms and lists could show their values (my.oviepro #147).
$entity = nulliEntity | iCollection | nullif given, the URL points at that specific entity's/collection's $defs entry; if null, at the root schemas document (routeSchemas).
returnsstring
RepositoryController::SchemaUrl($users); // http://localhost/app/data/schemas.json?v=3f2a...#$defs/App\User

setRepositories($repositories)

RepositoryController.php:121

Replace every registered repository (Serialize -- this is the injection target for the repositories config key, e.g. RepositoryController::class => ['repositories' => ['main' => ...]]).

function setRepositories(array $repositories): void
$repositoriesarrayname => iRepository.
returnsvoid
throwsif any value isn't an iRepository.

uniqueConflict($route, $collection, $keys, $other)

RepositoryController.php:574
protected function uniqueConflict( MMO\core\server\Route $route, MMO\core\interfaces\iCollection $collection, array $keys, MMO\core\interfaces\iEntity $other ): MMO\core\exceptions\eServer
$routeRoute
$collectioniCollection
$keysarraythe @unique group whose values $other has
$otheriEntity
returnseServerthe 409 Conflict of checkUnique and checkUniqueChanges: a user's message (the error window of mmo.client shows it as it is), the fields by their title, translated; the collection and the entity that holds the values are logged (my.oviepro #282)

writeAll($fn)

RepositoryController.php:596

Run a write's $fn: when it throws, the entities it changed are ignored, the commit of something else later in the request (a journal, a log) not saving half of a write refused

protected function writeAll(callable $fn): array
$fncallable
returnsarraywhat $fn returns
Inherited members (55)
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
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).
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
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.
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.
serialize($path, $serializer)aModule\MMO\core\interfaces\iSerializable::serialize -- exports every property (via
setVerbosity($verb)aModuleSet the current verbosity mask, replacing whatever it was before.
Shared()aModuleGet the shared instance, creating (and configuring) it on first call.
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…