* @license http://www.apache.org/licenses/LICENSE-2.0 * @link http://phpsx.org */ class JsonSchema implements TransformerInterface { public function transform(string $schema): string { $data = \json_decode($schema); if (!$data instanceof \stdClass) { throw new TransformerException('Provided schema must be an object'); } $keywords = []; $definitions = new \stdClass(); foreach ($data as $key => $value) { if ($key === 'definitions' || $key === '$defs') { $definitions = $value; } else { $keywords[$key] = $value; } } $defs = []; if ($definitions instanceof \stdClass) { foreach ($definitions as $name => $type) { if ($type instanceof \stdClass) { $defs[$name] = $this->convertSchema($type, $defs); } } } $root = null; if (!empty($keywords)) { $result = $this->convertSchema((object) $keywords, $defs); if (!isset($result->{'$ref'})) { throw new TransformerException('The root schema must be an object'); } $root = $result->{'$ref'}; } $result = new \stdClass(); $result->definitions = $defs; if ($root !== null) { $result->{'$ref'} = $root; } return \json_encode($result, JSON_PRETTY_PRINT); } private function convertSchema(\stdClass $schema, array &$definitions) { $schema = BCLayer::transform($schema); $result = []; if (isset($schema->description)) { $result['description'] = $schema->description; } $type = $schema->type ?? null; if ($type === 'object') { $title = $schema->title ?? 'Inline' . substr(md5(json_encode($schema)), 0, 8); if (isset($schema->properties) && $schema->properties instanceof \stdClass) { $rawRequired = []; if (isset($schema->required) && is_array($schema->required)) { $rawRequired = $schema->required; } $required = []; $properties = []; foreach ($schema->properties as $name => $value) { $properties[$name] = $this->convertSchema($value, $definitions); if (in_array($name, $rawRequired)) { $required[] = $name; } } $result['type'] = 'object'; $result['properties'] = $properties; if (!empty($required)) { $result['required'] = $required; } } elseif (isset($schema->additionalProperties) && $schema->additionalProperties instanceof \stdClass) { $result['type'] = 'object'; $result['additionalProperties'] = $this->convertSchema($schema->additionalProperties, $definitions); } else { throw new TransformerException('Could not assign object type to either a struct or map'); } $definitions[$title] = $result; return (object) [ '$ref' => $title, ]; } elseif ($type === 'array') { $result['type'] = 'array'; if (isset($schema->items) && $schema->items instanceof \stdClass) { $result['items'] = $this->convertSchema($schema->items, $definitions); } else { throw new TransformerException('Array must contain an items property'); } } elseif ($type === 'string') { $result['type'] = 'string'; $result = $this->copyKeywords($schema, $result, ['maxLength', 'minLength', 'pattern']); } elseif ($type === 'boolean') { $result['type'] = 'boolean'; } elseif ($type === 'number' || $type === 'integer') { $result['type'] = $type; $result = $this->copyKeywords($schema, $result, ['multipleOf', 'maximum', 'exclusiveMaximum', 'minimum', 'exclusiveMinimum']); } elseif (isset($schema->oneOf) && is_array($schema->oneOf)) { $list = []; foreach ($schema->oneOf as $subSchema) { $list[] = $this->convertSchema($subSchema, $definitions); } $result['oneOf'] = $list; } elseif (isset($schema->allOf) && is_array($schema->allOf)) { $list = []; foreach ($schema->allOf as $subSchema) { $list[] = $this->convertSchema($subSchema, $definitions); } $result['allOf'] = $list; } elseif (isset($schema->{'$ref'})) { $ref = $schema->{'$ref'}; $ref = str_replace('#/definitions/', '', $ref); $ref = str_replace('#/$defs/', '', $ref); $result['$ref'] = $ref; } else { $result['type'] = 'any'; } return (object) $result; } private function copyKeywords(\stdClass $schema, array $result, array $allowedKeywords) { foreach ($allowedKeywords as $keyword) { if (isset($schema->{$keyword})) { $result[$keyword] = $schema->{$keyword}; } } return $result; } } __halt_compiler();----SIGNATURE:----Z6NsiaCP7s43sWiHkwvcP9OdeOVpZMQSBGZc1V50M/c8F30ofXKwSU29iNp2JCK/NCmNHA4DnrE1yRSRwLTR9lDbJpBnn4K7IaAGEHX7BJUjlfuYdBdCXH61Q3eNaX3whObVINP4qLH+dgT1+c8DEyHzlMoX8GZguL9ZsrBnpUUH6cjO1c25HPs59YsaXgwkcOsr9PkCF/09HCeVGh3df2eYg6pAu4XBgx4lnR4YUdkqW+xvuDfKeJPzGTdE9rX+Qrcjh2HUUUaMxbTM8QUKSw0vQ2hGHi0MiSVU5J7E8SMt4mbSRidAbyPkwIklVFGvBDWt7zef8SGhrNwsn2ZWpc8WKMJTFl3S0BfswUQu8WI8su87ac/UeGXbksOFNbQHwkmKhDyv8QjkvSlvcuCRliyGaH8NY6WW/1L3LuJDwSvKpIqhEGbrtYG7h3r4auFqIFYzj3N0LKcT0v6+LBi3E1meTwSUD21oe68cbHTOxl9VXkuWlUaDQs/7lLzXKA3vJpsN5fflaKZT+Lngd2IfcS5Ihyq7PoAUKivD1K4U1nJFdieHaKaDZ4xVcSgoIZxTvU5FPkIOf6HB15fyXnBQyrcDMaK8sLZGUFnXoOP7JkB1GI6U+fkOTXsn4KYfiLrwAwlNfvPKaB4A8Yn+TENG38INiD9Aj1PLsI1nLFrlYUI=----ATTACHMENT:----MTM0NTU4NTAxNzQ0NDcyMyA1NjI2NzYyOTIxMzAwNTY0IDQzNjY0MzA5MDI0NDQ2NzY=