Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"php": ">=7.1.0",
"ext-json": "*",
"symfony/yaml": "^3.4 || ^4 || ^5 || ^6 || ^7.0",
"justinrainbow/json-schema": "^5.2 || ^6.0"
"justinrainbow/json-schema": "^5.2 || ^6.0",
"salsify/json-streaming-parser": "^8.3"
},
"require-dev": {
"cebe/indent": "*",
Expand Down
26 changes: 15 additions & 11 deletions src/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use cebe\openapi\json\JsonPointer;
use cebe\openapi\spec\OpenApi;
use Symfony\Component\Yaml\Yaml;
use JsonStreamingParser\Parser;
use JsonStreamingParser\Listener\InMemoryListener;

/**
* Utility class to simplify reading JSON or YAML OpenAPI specs.
Expand All @@ -26,17 +28,25 @@ class Reader
* @phpstan-template T of SpecObjectInterface
* @phpstan-param class-string<T> $baseType
* @phpstan-return T
* @param string $json the JSON string to decode.
* @param string $filename the JSON string to decode.
* @param string $baseType the base Type to instantiate. This must be an instance of [[SpecObjectInterface]].
* The default is [[OpenApi]] which is the base type of a OpenAPI specification file.
* You may choose a different type if you instantiate objects from sub sections of a specification.
* @return SpecObjectInterface|OpenApi the OpenApi object instance.
* The type of the returned object depends on the `$baseType` argument.
* @throws TypeErrorException in case invalid spec data is supplied.
*/
public static function readFromJson(string $json, string $baseType = OpenApi::class): SpecObjectInterface
public static function readFromJson(string $filename, string $baseType = OpenApi::class): SpecObjectInterface
{
return new $baseType(json_decode($json, true));
$fp = fopen($filename, 'r');
$listener = new InMemoryListener();
$parser = new Parser($fp, $listener);
$parser->parse();
fclose($fp);

$data = $listener->getJson();

return new $baseType($data);
}

/**
Expand Down Expand Up @@ -83,21 +93,15 @@ public static function readFromYaml(string $yaml, string $baseType = OpenApi::cl
*/
public static function readFromJsonFile(string $fileName, string $baseType = OpenApi::class, $resolveReferences = true): SpecObjectInterface
{
$fileContent = file_get_contents($fileName);
if ($fileContent === false) {
$e = new IOException("Failed to read file: '$fileName'");
$e->fileName = $fileName;
throw $e;
}
$spec = static::readFromJson($fileContent, $baseType);
$spec = static::readFromJson($fileName, $baseType);
$context = new ReferenceContext($spec, $fileName);
$spec->setReferenceContext($context);
if ($resolveReferences !== false) {
if (is_string($resolveReferences)) {
$context->mode = $resolveReferences;
}
if ($spec instanceof DocumentContextInterface) {
$spec->setDocumentContext($spec, new JsonPointer(''));
// $spec->setDocumentContext($spec, new JsonPointer('')); # TODO
}
$spec->resolveReferences();
}
Expand Down
21 changes: 21 additions & 0 deletions tests/IssueTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use cebe\openapi\Reader;
use cebe\openapi\spec\OpenApi;

class IssueTest extends \PHPUnit\Framework\TestCase
{
Expand All @@ -10,4 +11,24 @@ public function test175UnableToReferenceOtherLocalJsonFile()
$openapi = Reader::readFromJsonFile(__DIR__.'/data/issue/175/spec.json');
$this->assertInstanceOf(\cebe\openapi\SpecObjectInterface::class, $openapi);
}

// https://github.com/cebe/php-openapi/issues/224
public function test224FailsOnLargeDefinitions()
{
$openapi = Reader::readFromJsonFile(__DIR__.'/data/issue/224/cloudflare.json');
$this->readLargeFiles($openapi);

// $openapiYml = Reader::readFromYamlFile(__DIR__.'/data/issue/224/cloudflare.yml');
// $this->readLargeFiles($openapiYml);
}

private function readLargeFiles(OpenApi $openapi): void
{
$this->assertInstanceOf(\cebe\openapi\SpecObjectInterface::class, $openapi);
$this->assertSame($openapi->openapi, '3.0.3');
$this->assertSame(
$openapi->paths->getPath('/memberships')->getOperations()['get']->responses['4XX']->content['application/json']->schema->properties['success']->description,
'Whether the API call was successful.'
);
}
}
Loading
Loading