Index

JsonEditor

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

class

JsonEditor

JsonEditor.php:33

Change a JSON file the way a person would: only the values that change, where they are, keeping every comment, the order of the keys and the layout of everything else.

class MMO\admin\helpers\JsonEditor
Namespace
MMO\admin\helpers
`deploy.json` is reviewed like code, and commented: its comments are the documentation of its keys a developer has in front of them. Decoding it, changing a value and encoding it again would drop every comment and rewrite every line -- a diff nobody can review. So the text is read into a tree that remembers where each value starts and ends, and every change is a splice of the text at that place: - a changed value replaces the text of the old one, and nothing else; - a new key goes after the last key of its object, indented like it -- an object written on one line stays so; - a removed key takes its lines with it, and the comment lines right above it, which are about it. It reads what [`jsonDecode`](https://mcp.mmoframework.fr/documentation/mmo.core/php/strings.md#jsondecode) reads -- `//` and ` *\/` comments, trailing commas -- and a key starting with `//` is a comment too ([`Store::stripComments`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/helpers/Store.md#store-stripcomments)): [`update`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/helpers/JsonEditor.md#jsoneditor-update) never removes one. After an update the text is decoded again, by this class and by jsonDecode(), and compared with what was asked for, so a text that mmo.admin would read differently is never handed out.
$json = new JsonEditor(\MMO\core\files\get('deploy.json')); $json->set(['targets', 'demo', 'url'], 'https://demo.example.com'); $json->remove(['targets', 'old']); $json->update($declaration); // or: make the whole file hold this, changing only what differs \MMO\core\files\set('deploy.json', $json->getText());

Index

comments
pos
root
text
unit
comment($path, $text)Write a comment right above the key at $path, indented like it: one // line per line of $text.
commentsAbove($pos)
debugName()
decode($node)
detectUnit()The text's own indentation: the one of the root's first key written on a line of its own.
encode($value, $indent, $inline)
encodeKey($key)
fail($message)
find($path)
firstOnLine($pos)
get($path, $default)
getData()
getText()
has($path)
hasComment($path)
indentAt($pos)
insertMember($object, $key, $value)
isObject($value)
lineEnd($pos)
lineStart($pos)
member($object, $key)
memberAt($path)
merge($path, $data)
parse()
parseArray()
parseObject()
parseString()
parseValue()
plain($value)
remove($path)Remove the key at $path, with its lines and the comment lines right above it.
removeMember($object, $index)
rename($path, $key)Give the key at $path another name, leaving where it is, its value and its comments as they are.
same($a, $b)
set($path, $value)Put a value at $path: in place of the one there, or as a new key of its object -- created, with its parents, when it does not exist.
skip()Skip whitespace and comments.
splices($splices)Replace parts of the text, then read it again.
unfold($path)Write the object at $path one member per line, when it is written on one line -- so that each member can have a comment of its own.
update($data)Make the document hold $data, changing only what differs: a key it lacks is added, a key $data lacks is removed, a value that differs is replaced -- and an object present on both sides is updated k…
withoutComments($value)
__construct($text)

Properties5

comments

protected int $comments = 0
Type
int

pos

protected int $pos = 0
Type
int

root

protected array $root = []
Type
array

text

protected string $text
Type
string

unit

protected string $unit = ' '
Type
string

Methods40

comment($path, $text)

JsonEditor.php:225

Write a comment right above the key at $path, indented like it: one // line per line of $text.

function comment(array $path, string $text): static
$patharray
$textstring
returnsstatic
throwswhen there is no such key, or it shares its line with another: a // comment would take the rest.

commentsAbove($pos)

JsonEditor.php:654
protected function commentsAbove(int $pos): int
$posint
returnsintwhere the comment lines right above the line of $pos start (the start of its own line when there are none).

detectUnit()

JsonEditor.php:445

The text's own indentation: the one of the root's first key written on a line of its own.

protected function detectUnit(): void
returnsvoid

encode($value, $indent, $inline)

JsonEditor.php:412
protected function encode(mixed $value, string $indent, bool $inline = false): string
$valuemixed
$indentstringthe indentation of the line the value starts on.
$inline = falsebooleverything on one line.
returnsstringthe value as JSON: objects one member per line, lists of scalars on one line.

firstOnLine($pos)

JsonEditor.php:648
protected function firstOnLine(int $pos): bool
$posint
returnsboolwhether only spaces come before $pos on its line.

get($path, $default)

JsonEditor.php:78
function get(array $path, mixed $default = null): mixed
$patharray
$default = nullmixed
returnsmixedthe value there, decoded, or $default when there is none.

getData()

JsonEditor.php:65
function getData(): mixed
returnsmixedthe whole document, decoded (objects as arrays, comment keys included).

has($path)

JsonEditor.php:71
function has(array $path): bool
$patharraykeys (strings for an object, ints for an array) from the root.
returnsboolwhether a value exists there.

hasComment($path)

JsonEditor.php:209
function hasComment(array $path): bool
$patharraya key's path.
returnsboolwhether a comment is about it: comment lines right above it, or a comment after it on its line.

indentAt($pos)

JsonEditor.php:643
protected function indentAt(int $pos): string
$posint
returnsstringthe spaces and tabs the line holding $pos starts with.

insertMember($object, $key, $value)

JsonEditor.php:292
protected function insertMember(array $object, string $key, mixed $value): void
$objectarraythe object's node.
$keystring
$valuemixed
returnsvoid

isObject($value)

JsonEditor.php:667
protected function isObject(mixed $value): bool
$valuemixed
returnsboolwhether $value is written as an object: a stdClass, or an array with keys ([] is either).

lineEnd($pos)

JsonEditor.php:637
protected function lineEnd(int $pos): int
$posint
returnsintwhere the line holding $pos ends: its \n, or the end of the text.

lineStart($pos)

JsonEditor.php:631
protected function lineStart(int $pos): int
$posint
returnsintwhere the line holding $pos starts.

member($object, $key)

JsonEditor.php:480
protected function member(array $object, string $key): ?array
$objectarray
$keystring
returnsnull | arrayits member named $key -- the last one, as a decoder keeps it.

plain($value)

JsonEditor.php:672
protected function plain(mixed $value): mixed
$valuemixed
returnsmixed$value with every stdClass turned into an array.

remove($path)

JsonEditor.php:135

Remove the key at $path, with its lines and the comment lines right above it. Nothing happens when there is none.

function remove(array $path): static
$patharray
returnsstatic

removeMember($object, $index)

JsonEditor.php:338
protected function removeMember(array $object, int $index): void
$objectarraythe object's node.
$indexintwhich member.
returnsvoid

rename($path, $key)

JsonEditor.php:158

Give the key at $path another name, leaving where it is, its value and its comments as they are.

function rename(array $path, string $key): static
$patharray
$keystringthe new name
returnsstatic
throwswhen there is no such key, or its object already has one named $key.

same($a, $b)

JsonEditor.php:692
protected function same(mixed $a, mixed $b): bool
$amixed
$bmixed
returnsboolwhether $a and $b are the same JSON value: types compared strictly, the order of a list's items counted, the order of an object's keys not.

set($path, $value)

JsonEditor.php:96

Put a value at $path: in place of the one there, or as a new key of its object -- created, with its parents, when it does not exist.

function set(array $path, mixed $value): staticThe new value is written whole, so what was inside the old one goes, comments included: to change a few keys of an object and keep the rest, set those keys, or [`update`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/helpers/JsonEditor.md#jsoneditor-update). Write an empty object as `new \stdClass()`: `[]` is an empty list.
$patharray
$valuemixed
returnsstatic
throwswhen a parent on the way is not an object (or, for an int key, an array).

splices($splices)

JsonEditor.php:396

Replace parts of the text, then read it again.

protected function splices(array $splices): void
$splicesarray[start, end, text], none overlapping another.
returnsvoid

unfold($path)

JsonEditor.php:248

Write the object at $path one member per line, when it is written on one line -- so that each member can have a comment of its own. What is inside its members stays as it is written. An object holding a comment is left as it is: it would not survive.

function unfold(array $path): static
$patharray
returnsstatic

update($data)

JsonEditor.php:186

Make the document hold $data, changing only what differs: a key it lacks is added, a key $data lacks is removed, a value that differs is replaced -- and an object present on both sides is updated key by key, so that what did not change inside it, comments included, stays as it is. A key starting with // is a comment, never removed.

function update(array $data): static
See
jsonDecode, which is how mmo.admin reads it. Then nothing is to be written.
$dataarraythe whole document; the root must be an object.
returnsstatic
throwswhen the root is not an object.
throwswhen the text would not read back as $data -- by this class, or by

__construct($text)

JsonEditor.php:53
function __construct(string $text = '{} ')
$text = '{} 'stringthe JSON; an empty text is an empty object.
throwswhen it is not JSON, comments and trailing commas aside.