Index

JsonRepository

MMO\core\entities · 1 symbol · generated 5 Oct 2026

class

JsonRepository

JsonRepository.php:24

Collections container.

class MMO\core\entities\JsonRepository extends MMO\core\entities\Repository
Namespace
MMO\core\entities
Extends
Repository
A collection registers itself for commit when it is built ([`Collection::__construct`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/Collection.md#collection--construct)), so a change is saved by `commit()` with nothing to register by hand. [`Collection::registerCommit`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/Collection.md#collection-registercommit) turns that off. A [`Repository`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/Repository.md#repository) backed by one JSON file per collection ([`$filenames`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-filenames)) -- each file holds a `{"id": {...entity data...}, ...}` map (see [`loadCollections`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-loadcollections)/[`onCommit`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-oncommit)). An entity's uid names the folders of its repository (`file://3f2a9c1b/users.json#2`, [`uid`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-uid)), where the files name the entities they hold by their file's name alone (`<file://users.json#2>`, [`Reference`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-reference)). An id is never given twice ([`generateId`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-generateid)).
$repo = new JsonRepository(['users' => 'data/users.json'], ['users' => User::class]); $user = $repo->getCollection('users')->createEntity(['name' => 'Marc']); \MMO\commit($repo); // writes data/users.json

Index

LAST_IDthe key under which a file keeps the highest id it gave, when its entities no longer tell it (onCommit)
cachedUid
filenames
lastIds
collectionOf($url)
debugName()
dropCollection($collection)Delete a collection's underlying JSON file entirely.
generateId($collection)Same as Repository::generateId, above every id the collection's file ever gave: an id is never given twice.
getFilename($collection)
LastId($file) static
loadCollections()Load every collection's data from its JSON file (a no-op collection stays empty if its file doesn't exist yet).
onCommit($commit)Persist every changed entity from this commit: grouped by their collection's file, merged into that file's existing (re-read) content, new ids assigned above the highest id the file ever gave (@see…
onFetch($event)Same as aRepository::onFetch, for the uid of one of its entities (file://3f2a9c1b/users.json#2) and for a reference as the files hold it (file://users.json#2, Refere…
Reference($entity) staticHow the files name an entity they hold: by its file's name and its id (<file://users.json#2>;label="Ada"), relative to the repository reading them (onFetch) -- as they always did.
setCollections($cols)Same as aRepository::setCollections, also loading each collection's data (loadCollections) once reference-resolution (the Fetch listener) is ready -- deferred to @s…
uid()file:// and a tag of the folders its files are in: its entities' uids (file://3f2a9c1b/users.json#2) are its own, and the same in every request.
__construct($filenames, $collections)
__wakeup()Same as aRepository::__wakeup, also (re)loading every collection's data from its file (loadCollections).

Constants1

LAST_ID

the key under which a file keeps the highest id it gave, when its entities no longer tell it (onCommit)

const LAST_ID = '$lastId'

Properties3

cachedUid

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

filenames

array $filenames = []
Type
array

lastIds

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

Methods14

collectionOf($url)

JsonRepository.php:200
protected function collectionOf(string $url): ?MMO\core\interfaces\iCollection
$urlstringan entity's uid, or a reference as the files hold it
returnsnull | iCollectionthe collection of this repository it names: with its uid (file://3f2a9c1b/users.json#2), or with its file's name alone (file://users.json#2)

dropCollection($collection)

JsonRepository.php:233

Delete a collection's underlying JSON file entirely.

function dropCollection(MMO\core\interfaces\iCollection|string $collection): bool
$collectioniCollection | string
returnsbool

generateId($collection)

JsonRepository.php:165

Same as Repository::generateId, above every id the collection's file ever gave: an id is never given twice.

function generateId(MMO\core\interfaces\iCollection $collection): intWhat is keyed by the id of an entity removed (a scope `edms.files.12`, a link, a cache) would apply to the next one. The file keeps its highest id when its entities no longer tell it (`"$lastId": 12`, [`onCommit`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-oncommit)). NOTE: until 2026-09 an id was one more than the highest held: the id of the entity removed last was given again.
$collectioniCollection
returnsint
$repository->generateId($users); // 13, once the user 12 was removed

getFilename($collection)

JsonRepository.php:86
function getFilename(MMO\core\interfaces\iCollection|string $collection): string
$collectioniCollection | string
returnsstringthe resolved (absolute) JSON filename for a collection or its name.
throwsif unknown.

LastId($file)

staticJsonRepository.php:151
protected static function LastId(array $file): int
$filearraywhat a collection's file holds
returnsintthe highest id it gave: its highest id, or the one it keeps once that one was removed (onCommit)

loadCollections()

JsonRepository.php:108

Load every collection's data from its JSON file (a no-op collection stays empty if its file doesn't exist yet). Entities are built in two passes: first an empty, id-only instance for every record (so records can reference each other by entity, not just by id), then each one's real data is loaded in (re-invoking its own constructor) -- resolving those cross-references correctly regardless of file order.

protected function loadCollections(): void
returnsvoid

onCommit($commit)

JsonRepository.php:257

Persist every changed entity from this commit: grouped by their collection's file, merged into that file's existing (re-read) content, new ids assigned above the highest id the file ever gave (generateId), then the whole file re-written (only if it actually changed) via JsonPrinter::EncodeFile (pretty-printed in dev mode).

function onCommit(MMO\core\events\Commit $commit): voidAn entity removed leaves its file and its collection, and its id is not given again: when it was the highest, the file keeps it (`"$lastId": 12`), until a higher one is given. NOTE: until 2026-09 an entity removed stayed in its collection: [`Collection::getById`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/Collection.md#collection-getbyid) found it for the rest of the request.
$commitCommit
returnsvoid
throwsif a to-be-created entity somehow still has no id after id assignment.

onFetch($event)

JsonRepository.php:181

Same as aRepository::onFetch, for the uid of one of its entities (file://3f2a9c1b/users.json#2) and for a reference as the files hold it (file://users.json#2, Reference).

function onFetch(MMO\core\events\Fetch $event): voidA reference is answered by the repository reading it -- the Fetch's `repository` option, which an entity loaded or set gives -- when it has such a file: another one may hold a file of the same name, or be another instance on the same folder, built before it. Without that option (a uid of before 2026-09, `?uid=file://users.json%232`), the first repository holding the file answers.
$eventFetch
returnsvoid
\MMO\fetch($this, $user->uid()); // $user

Reference($entity)

staticJsonRepository.php:224

How the files name an entity they hold: by its file's name and its id (<file://users.json#2>;label="Ada"), relative to the repository reading them (onFetch) -- as they always did. Its uid would tie them to their folder (uid), which could then no longer move. An entity of another kind of repository is named by its uid.

static function Reference(MMO\core\entities\Entity $entity): string
$entityEntity
returnsstringits link (Entity::toLink), named that way
JsonRepository::Reference($ada); // '<file://users.json#2>;label="Ada"'

uid()

JsonRepository.php:67

file:// and a tag of the folders its files are in: its entities' uids (file://3f2a9c1b/users.json#2) are its own, and the same in every request. The tag does not tell the folders: an entity's uid is in every API response.

function uid(): stringTwo repositories on one folder share it (they hold the same files); moved, a folder gets another one. NOTE: it was `file:/` (until 2026-09), whatever the folder: two repositories each holding a `users.json` (two applications in one process, every test class) gave their entities the same uid, and \MMO\fetch() found the first one's. The files did not change: they name an entity by its file's name alone ([`Reference`](https://mcp.mmoframework.fr/documentation/mmo.core/php/entities/JsonRepository.md#jsonrepository-reference)).
returnsstring
$repository->uid(); // 'file://3f2a9c1b'
Inherited members (25)
PropertiesDeclared byDescription
collectionsaRepository
MethodsDeclared byDescription
addCollection($name, $collection)aRepositoryAdd collection
createCollection($name, $entityClass, $collectionId)aRepositoryCreate and register a plain Collection for entities of $entityClass.
createEntity($class, $data, $collection)RepositorySame as aRepository::createEntity, auto-assigning the next id (generateId) if $data has none.
createLog($type, $origin, $collection, $data, $filters, $sorts, $limit, $offset)aRepositoryBuild (but not dispatch) a LogQuery entity describing a data-mutating operation, stored in the repository's LogQuery collection (if one is registered).
executeQuery($query, $opts)RepositoryFind entities by content (delegates to the collection's own in-memory filtering -- see Collection::executeQuery).
forceCommit($origin, $entities)aRepository
getCollection($name)aRepository
getCollectionByClass($entityClass, $allowChildClass)aRepositoryFind the collection whose entities are (an exact match, or optionally a subclass of) $entityClass.
getCollectionName($collection)aRepository
getCollections()aRepository
getDistinct($collection, $key)aRepositoryEvery value one property takes across a collection, once each, in ascending order.
getEntities()aRepository
getIterator()aRepository\IteratorAggregate::getIterator -- iterates name => iCollection
hasCollection($collection)aRepository
hideLogData($collection, $data)aRepositoryWhat a repository logs is what it wrote (mmo.pdo's row, mmo.mongodb's document or its changes), hidden properties (ArrayProperty::isHidden) included, and a log is exported…
logDelete($origin, $collection, $data, $filters, $sorts, $limit, $offset)aRepositoryLog and dispatch a DELETE operation.
logInsert($origin, $collection, $data, $filters, $sorts, $limit, $offset)aRepositoryLog and dispatch an INSERT operation.
logStatus($origin, $collection, $data, $filters, $sorts, $limit, $offset)aRepositoryLog and dispatch a STATUS-change operation.
logUpdate($origin, $collection, $data, $filters, $sorts, $limit, $offset)aRepositoryLog and dispatch an UPDATE operation.
offsetExists($key)aRepository\ArrayAccess::offsetExists
offsetGet($key)aRepository\ArrayAccess::offsetGet
offsetSet($key, $value)aRepository\ArrayAccess::offsetSet -- equivalent to addCollection
offsetUnset($key)aRepository\ArrayAccess::offsetUnset
searchText($query, $text)aRepositoryFull-text search. Not implemented at this level -- a concrete repository backed by a search-capable store should override this.