<?php
 abstract class vB_Undo_Item implements JsonSerializable { use vB_Trait_NoSerialize; protected int $userid = 0; protected ?int $undoid = null; protected array $serializefields = [ 'userid', ]; public static function restoreFromData(int $undoid, string $data) : ?vB_Undo_Item { $dataArray = json_decode($data, true); if($dataArray === false) { return null; } $class = $dataArray['class']; if(!is_a($class, 'vB_Undo_Item', true)) { return null; } $item = new $class(); $item->fromData($dataArray['data']); $item->undoid = $undoid; return $item; } protected function __construct() {} public final function getData() : string { $data = [ 'class' => get_class($this), 'data' => $this, ]; return json_encode($data); } public final function getClass() : string { return get_class($this); } public final function getUserid() : int { return $this->userid ?? 0; } public final function getUndoid() : ?int { return $this->undoid; } public function jsonSerialize() : mixed { $item = []; foreach($this->serializefields AS $field) { $item[$field] = $this->{$field}; } return $item; } protected function fromData(mixed $item) : void { foreach($this->serializefields AS $field) { $this->{$field} = $item[$field]; } } abstract public function run() : mixed; } 