From 99dd8bed208c74788eded1dea2e729f2ac8b919b Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 20 Sep 2024 19:27:52 +0530 Subject: [PATCH] Implement --- TODO.taskpaper | 4 +- src/Reader.php | 2 + src/SpecBaseObject.php | 72 ++++++++++++++++++++++++++++++ tests/spec/SchemaTest.php | 60 ++++++------------------- tests/spec/data/resolve_all_of.yml | 49 ++++++++++++++++++++ 5 files changed, 138 insertions(+), 49 deletions(-) create mode 100644 tests/spec/data/resolve_all_of.yml diff --git a/TODO.taskpaper b/TODO.taskpaper index 48920c8..24d3151 100644 --- a/TODO.taskpaper +++ b/TODO.taskpaper @@ -1,10 +1,10 @@ TODO.taskpaper - ☐ undo commit - ☐ undo commit ☐ create failing test ☐ implement the solution ☐ fix failing tests if any ☐ resolve TODOs if any + ☐ undo commit https://github.com/cebe/php-openapi/pull/208/commits/27e2618787ac21275cb2137e06bd35f202b51b6b + ☐ undo commit https://github.com/cebe/php-openapi/pull/208/commits/b4c19c7599154029dc2035d42282b05237124d79 ☐ review Merge Request ☐ delete this file and submit Merge Request diff --git a/src/Reader.php b/src/Reader.php index 99ee5c3..5687699 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -147,6 +147,8 @@ public static function readFromYamlFile(string $fileName, string $baseType = Ope } $spec->resolveReferences(); } + $spec->resolveAllOf(); + $spec->resolveAllOf2(); // TODO rename + refactor if possible return $spec; } } diff --git a/src/SpecBaseObject.php b/src/SpecBaseObject.php index 1de429b..781ab44 100644 --- a/src/SpecBaseObject.php +++ b/src/SpecBaseObject.php @@ -12,6 +12,7 @@ use cebe\openapi\json\JsonPointer; use cebe\openapi\json\JsonReference; use cebe\openapi\spec\Reference; +use cebe\openapi\spec\Schema; use cebe\openapi\spec\Type; /** @@ -525,4 +526,75 @@ public function getExtensions(): array } return $extensions; } + + public function getProperties(): array + { + return $this->_properties; + } + + public function mergeProperties($properties) + { + $this->_properties = array_merge($this->_properties, $properties); + } + + public function resolveAllOf($parent = null) + { + foreach ($this->_properties as $property => $value) { + if ($property === 'allOf' && !empty($value)) { + $this->_properties[$property] = $this->mergeAllAllOfsInToSingleObj($value); + } elseif ($value instanceof SpecObjectInterface && method_exists($value, 'resolveAllOf')) { + $value->resolveAllOf($this->_properties[$property]); + } elseif (is_array($value)) { + foreach ($value as $k => $item) { + if ($k === 'allOf' && !empty($item)) { + $this->_properties[$property][$k] = $this->mergeAllAllOfsInToSingleObj($item); + } elseif ($item instanceof SpecObjectInterface) { + $item->resolveAllOf($this->_properties[$property][$k]); + } + } + } + } + } + + public function mergeAllAllOfsInToSingleObj($allOfs): self + { + $allOfs = $this->allOf; + /** @var static $first */ + $first = $this->allOf[0]; + unset($allOfs[0]); + foreach ($allOfs as $allOf) { + /** @var Schema $allOf */ + $first->mergeProperties($allOf->getProperties()); + } + return $first; + } + + public function resolveAllOf2() // TODO + { + foreach ($this->_properties as $property => $value) { + if ($property === 'properties' && !empty($value)) { + foreach ($value as $k => $v) { + if (!empty($v->allOf)) { + $temp = $v->allOf; + $this->_properties[$property][$k] = $temp; + } + } + } elseif ($value instanceof SpecObjectInterface && method_exists($value, 'resolveAllOf2')) { + $value->resolveAllOf2(); + } elseif (is_array($value)) { + foreach ($value as $k2 => $item) { + if ($k2 === 'properties' && !empty($item)) { + foreach ($item as $kIn => $vIn) { // TODO rename var names + if (!empty($vIn->allOf)) { + $tempIn = $vIn->allOf; + $this->_properties[$property][$value][$k2][$kIn] = $tempIn; + } + } + } elseif ($item instanceof SpecObjectInterface) { + $item->resolveAllOf2(); + } + } + } + } + } } diff --git a/tests/spec/SchemaTest.php b/tests/spec/SchemaTest.php index 5c80de5..815e677 100644 --- a/tests/spec/SchemaTest.php +++ b/tests/spec/SchemaTest.php @@ -422,61 +422,27 @@ public function testPropertyNameRef() } // https://github.com/cebe/yii2-openapi/issues/165 + // TODO cleanup public function test165ResolveAllOf() { - $openApi = Reader::readFromYaml(<<<'YAML' - - -openapi: 3.0.3 - -info: - title: Add validation rules by attribute name or pattern \#30 - version: 1.0.0 - -components: - schemas: - User: - type: object - required: - - id - - name - properties: - id: - type: integer - name: - type: string - Post: - type: object - properties: - id: - type: integer - content: - type: string - user: - allOf: - - $ref: '#/components/schemas/User' - - x-faker: false - -paths: - '/': - get: - responses: - '200': - description: OK - - -YAML - ); - - $openApi->resolveReferences(new \cebe\openapi\ReferenceContext($openApi, 'file:///tmp/openapi.yaml')); +// $openApi->resolveReferences(new \cebe\openapi\ReferenceContext($openApi, 'file:///tmp/openapi.yaml')); + $openApi = Reader::readFromYamlFile(__DIR__ . '/data/resolve_all_of.yml'); $result = $openApi->validate(); +// $openApi->resolveAllOf(); $this->assertTrue($result); $this->assertEquals([], $openApi->getErrors()); // $this->assertTrue($openApi->components->schemas['Post']->getSerializableData()); +// $openApi->components->schemas['Post']->properties['user']->allOf = ['abc' => 'def']; +// $openApi->components->schemas['Post']->properties['user']->__set('allOf', ['abc' => 'def']); // $openApi->components->schemas['Post']->resolveReferences(); - $this->assertTrue($openApi->components->schemas['Post']->getSerializableData()); - // $this->assertTrue($openApi->components->schemas['Post']->properties['user']->properties); +// $this->assertTrue($openApi->components->schemas['Post']); +// $this->assertTrue($openApi->components->schemas['Post']->getSerializableData()); + $this->assertSame( + json_decode(json_encode($openApi->components->schemas['Post']->getSerializableData()), true) + + , [] + ); } } diff --git a/tests/spec/data/resolve_all_of.yml b/tests/spec/data/resolve_all_of.yml new file mode 100644 index 0000000..8c81afe --- /dev/null +++ b/tests/spec/data/resolve_all_of.yml @@ -0,0 +1,49 @@ + +openapi: 3.0.3 + +info: + title: Resolve allOf + version: 1.0.0 + +components: + schemas: + User: + type: object + required: + - id + - name + properties: + id: + type: integer + name: + type: string +# User2: +# type: object +# required: +# - id2 +# - name +# properties: +# id2: +# type: integer +# name: +# type: array + Post: + type: object + properties: + id: + type: integer + content: + type: string + user: + allOf: + - $ref: '#/components/schemas/User' +# - $ref: '#/components/schemas/User2' + - x-faker: false + - x-faker2: true + +paths: + '/': + get: + responses: + '200': + description: OK