\Drupal\strata\Capture PayloadCodec

Encodes and decodes an operation's payload, per realm.

Most realms hold a map of named values and JSON describes them exactly. State and the key-value collections do not: they hold arbitrary PHP values, and a value that round-tripped through JSON would come back as a different type - an object as an array, an integer-keyed list as an object

  • and be written back wrong on a restore. So those two are serialized instead.

Keeping both sides of that decision in one class is the point. The recorder and the replayer have to agree byte for byte, and a payload written by one release has to stay readable by every later one, so the choice cannot live in two places that can drift apart.

Objects are refused rather than reconstructed. Deserializing arbitrary classes out of a backup is how a restore becomes remote code execution, so no class is allowed through. A value that genuinely held an object comes back as unreadable, which makes the subject degraded and leaves the live value alone. Unknown beats incorrect, and a state key holding an object is a bug in whatever put it there.

Summary

Methods
Properties
Constants
encode
decode
isSerialized
No public properties found
VALUE
SERIALIZED_REALMS
No protected methods found
No protected properties found
No protected constants found
unserializeValue
holdsObject
No private properties found
No private constants found

Constant

VALUE

VALUE = 'value'

The key a single serialized value is presented under.

A replay merges field maps, so a realm holding one unnamed value needs a name for it.

SERIALIZED_REALMS

SERIALIZED_REALMS = [\Drupal\strata\Journal\Realm::STATE, \Drupal\strata\Journal\Realm::KEY_VALUE] : array&lt;int, <a href="classes/Drupal-strata-Journal-Realm.html"><abbr title="\Drupal\strata\Journal\Realm">Realm</abbr></a>&gt;

Realms whose payload is one arbitrary PHP value rather than a map of fields.

Methods

encode()

encode(\Drupal\strata\Journal\Realm  $realm, mixed  $value) : string

Encodes a value for storage.

Parameters

\Drupal\strata\Journal\Realm $realm

The realm the operation belongs to.

mixed $value

A field map for most realms; any value for state and key-value.

Throws

\JsonException

When a JSON realm holds a string that is not valid UTF-8. (string) false would otherwise store an empty payload that decodes to NULL, so the operation would claim to carry a value it does not.

Returns

string —

The payload bytes.

decode()

decode(\Drupal\strata\Journal\Realm  $realm, string  $payload) : array<string,mixed>|null

Decodes a payload back to the field map a replay merges.

Parameters

\Drupal\strata\Journal\Realm $realm

The realm the operation belongs to.

string $payload

The stored bytes.

Returns

array|null —

The field map, or NULL when the payload does not decode to one. A realm holding a single value presents it under PayloadCodec::VALUE.

isSerialized()

isSerialized(\Drupal\strata\Journal\Realm  $realm) : bool

Whether a realm's payload is a serialized value rather than a field map.

Parameters

\Drupal\strata\Journal\Realm $realm

The realm.

Returns

bool —

TRUE for state and key-value.

unserializeValue()

unserializeValue(string  $payload) : array<string,mixed>|null

Unserializes one stored value, refusing anything holding an object.

Parameters

string $payload

The stored bytes.

Returns

array|null —

The value under PayloadCodec::VALUE, or NULL when it cannot be reconstructed faithfully.

holdsObject()

holdsObject(mixed  $value, int  $depth = 0) : bool

Whether a decoded value contains a class that was refused.

Parameters

mixed $value

The decoded value.

int $depth

Recursion guard, since a stored value can nest arbitrarily.

Returns

bool —

TRUE when anything in it came back as an incomplete class.