\d\d)/schema#?~i'; const SUPPORTED_DRAFTS = ['06', '07']; const BASE_ID_PROP = '$_base_id'; const PATH_PROP = '$_path'; const VARS_PROP = '$vars'; const FILTERS_PROP = '$filters'; const FUNC_NAME = '$func'; const ID_PROP = '$id'; const MAP_PROP = '$map'; const WALK_IGNORE_PROPERTIES = [ 'default', 'const', 'enum', self::FILTERS_PROP, self::VARS_PROP, self::MAP_PROP ]; /** @var string */ protected $id; /** @var string */ protected $draft; /** @var array */ protected $internal = []; /** * Schema constructor. * @param \stdClass|boolean $data * @param string|null $id */ public function __construct($data, string $id = null) { if (is_object($data)) { if (property_exists($data, static::ID_PROP)) { $id = $data->{static::ID_PROP}; } } elseif (!is_bool($data)) { throw new InvalidSchemaException($data); } if ($id === null) { $id = uniqid("json-schema-id:/"); } $id = URI::merge($id, $id); if (substr($id, -1) !== '#') { throw new InvalidSchemaIdException($id); } $this->id = $id; if (is_object($data)) { if (!property_exists($data, '$schema')) { $data->{'$schema'} = 'http://json-schema.org/draft-07/schema#'; } elseif (!is_string($data->{'$schema'})) { throw new InvalidSchemaDraftException($data); } if (!preg_match(static::SCHEMA_REGEX, $data->{'$schema'}, $m)) { throw new InvalidSchemaDraftException($data); } $this->draft = $m['draft']; unset($m); if (!in_array($this->draft, static::SUPPORTED_DRAFTS)) { throw new SchemaDraftNotSupportedException($data, $this->draft); } $data->{static::ID_PROP} = $id; static::walk($this->internal, $data, $id); if (isset($data->{'$ref'}) && is_string($data->{'$ref'})) { $this->internal[$id] = $data; } } else { $this->internal[$id] = $data; } } /** * @inheritDoc */ public function id(): string { return $this->id; } /** * @inheritDoc */ public function draft(): string { return $this->draft; } /** * @inheritDoc */ public function resolve(string $id = null) { if ($id === null) { $id = $this->id; } return $this->internal[$id] ?? null; } /** * @param array $container * @param mixed $schema * @param string $id * @param array $path * @throws DuplicateSchemaException */ public static function walk(array &$container, &$schema, string $id, array $path = []) { if (is_array($schema)) { foreach ($schema as $name => &$value) { $path[] = $name; static::walk($container, $value, $id, $path); array_pop($path); unset($value); } return; } if (!is_object($schema)) { return; } $has_ref = isset($schema->{'$ref'}) && is_string($schema->{'$ref'}); if (isset($schema->{static::ID_PROP}) && is_string($schema->{static::ID_PROP})) { // Set the base id $schema->{static::BASE_ID_PROP} = $id; // Add current path $schema->{static::PATH_PROP} = $path; $id = URI::merge($schema->{static::ID_PROP}, $id); if (array_key_exists($id, $container)) { throw new DuplicateSchemaException($id, $schema, $container); } $container[$id] = $schema; // Do not process $ref if ($has_ref) { return; } } elseif ($has_ref) { // Set the base id $schema->{static::BASE_ID_PROP} = $id; // Add current path $schema->{static::PATH_PROP} = $path; // Do not process $ref return; } unset($has_ref); foreach ($schema as $name => &$value) { if (is_null($value) || is_scalar($value)) { continue; } if (in_array($name, static::WALK_IGNORE_PROPERTIES)) { continue; } $path[] = $name; static::walk($container, $value, $id, $path); array_pop($path); } } /** * @param string $json * @param string|null $id * @return Schema */ public static function fromJsonString(string $json, string $id = null): self { return new self(json_decode($json, false), $id); } }__halt_compiler();----SIGNATURE:----qi2sbw1Owg78MaV6oclDRmjawc36cjjZvCx9XRU+P8kQ5WdnJSuSdFwngcG0Z9xm6eftk/mWvGW7gByODQ2B2cyXIwEAPJB8JvH5PgCDZRQP9Nu+daDL8TY0fEWWbSHyL5It81b4rrQnmotiy1YotqjXHEmPJpZXairEzrSxo+eo3K5zlTcwwoV2xggtweBmiojtmAu56uM4318GqbvyzKGlG4G/U6hIkfSG7AG0u623E0/WemhK9fuDTAzhy21WpgYuLLG5co/J6GcHCsMOGkiegQhyGgWQVX72sr8kgyT2P3CPy78BL5VkpkKKdKko5PZNKkY5g+X45z1pzoa/odtg6m/7K4GD2W3X17M1bAp5KCz93sj86iYflpQ5WhZjb+jkfDtr5KM2sYMsPQ50y1q5TSP19Yj9y+AGWGzBeGQaGzK/Y9st5UUYu4FkAnFVA2xbt0kurYfcLgPREFXfBsE6pOAbz2SR8j4wnHNHuoGyUE4b9O4As8guMzOPZmULlsFx6noGoxyHzDXwcsbf+9m4mFdvXR/ck9jtZAkIYUG1tqM/n+X2WL+xKk7gXYDkWcEK9B2OFwU2mf43IHV0KG1a4C/ZGf7xyWxYcbreg33PgTLRCyBrJlwI7nEDCDbO/48/p0EBlCi9xDF+dV9rW5aAAvUxvLlD+Azv5xlSD0o=----ATTACHMENT:----NTA2NDIwNTYxMDU1NzUyNiAzODYyNTg4NDkyMTM3Mjc4IDEzODY3MDUxOTc4OTk1NTM=