diff --git a/src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php b/src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php index 5e8bb72..13a18fe 100644 --- a/src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php +++ b/src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php @@ -5,9 +5,7 @@ namespace PHPModelGenerator\PropertyProcessor\ComposedValue; use PHPModelGenerator\Exception\SchemaException; -use PHPModelGenerator\Model\MethodInterface; use PHPModelGenerator\Model\Property\CompositionPropertyDecorator; -use PHPModelGenerator\Model\Property\Property; use PHPModelGenerator\Model\Property\PropertyInterface; use PHPModelGenerator\Model\Property\PropertyType; use PHPModelGenerator\Model\Schema; @@ -16,7 +14,6 @@ use PHPModelGenerator\Model\Validator\ComposedPropertyValidator; use PHPModelGenerator\Model\Validator\RequiredPropertyValidator; use PHPModelGenerator\PropertyProcessor\Decorator\Property\ObjectInstantiationDecorator; -use PHPModelGenerator\PropertyProcessor\Decorator\SchemaNamespaceTransferDecorator; use PHPModelGenerator\PropertyProcessor\Decorator\TypeHint\ClearTypeHintDecorator; use PHPModelGenerator\PropertyProcessor\Decorator\TypeHint\CompositionTypeHintDecorator; use PHPModelGenerator\PropertyProcessor\Property\AbstractValueProcessor; @@ -90,6 +87,10 @@ function () use (&$resolvedCompositions, $property, $compositionProperties, $pro $propertySchema ) : null; + + if ($this->mergedProperty) { + $property->setNestedSchema($this->mergedProperty->getNestedSchema()); + } } } ); @@ -175,6 +176,20 @@ protected function getCompositionProperties(PropertyInterface $property, JsonSch } }); + if ($compositionProperty->isResolved() + && $this instanceof OneOfProcessor + && count($compositionProperty->getJsonSchema()->getJson()) === 1 + && array_key_exists('example', $compositionProperty->getJsonSchema()->getJson()) + ) { + if ($this->schemaProcessor->getGeneratorConfiguration()->isOutputEnabled()) { + // @codeCoverageIgnoreStart + echo "Warning: example OneOf branch for {$property->getName()} may lead to unexpected results, skipping branch\n"; + // @codeCoverageIgnoreEnd + } + + continue; + } + $compositionProperties[] = $compositionProperty; } diff --git a/src/PropertyProcessor/Property/AbstractPropertyProcessor.php b/src/PropertyProcessor/Property/AbstractPropertyProcessor.php index f665913..c9cb154 100644 --- a/src/PropertyProcessor/Property/AbstractPropertyProcessor.php +++ b/src/PropertyProcessor/Property/AbstractPropertyProcessor.php @@ -217,6 +217,10 @@ protected function addComposedValueValidator(PropertyInterface $property, JsonSc ]) ); + if ($composedProperty->getNestedSchema()) { + $property->setNestedSchema($composedProperty->getNestedSchema()); + } + foreach ($composedProperty->getValidators() as $validator) { $property->addValidator($validator->getValidator(), $validator->getPriority()); } diff --git a/src/SchemaProcessor/SchemaProcessor.php b/src/SchemaProcessor/SchemaProcessor.php index bfb8c9c..4c6eee8 100644 --- a/src/SchemaProcessor/SchemaProcessor.php +++ b/src/SchemaProcessor/SchemaProcessor.php @@ -330,13 +330,15 @@ private function transferPropertiesToMergedSchema( $property->getNestedSchema()->onAllPropertiesResolved( function () use ($property, $schema, $mergedPropertySchema): void { foreach ($property->getNestedSchema()->getProperties() as $nestedProperty) { - $mergedPropertySchema->addProperty( + $attachProperty = clone $nestedProperty; + // don't validate fields in merged properties. All fields were validated before // corresponding to the defined constraints of the composition property. - (clone $nestedProperty)->filterValidators(static function (): bool { - return false; - }) - ); + $attachProperty->filterValidators(static function (): bool { + return false; + }); + + $mergedPropertySchema->addProperty($attachProperty); } } ); diff --git a/tests/Issues/Issue/Issue72Test.php b/tests/Issues/Issue/Issue72Test.php new file mode 100644 index 0000000..9593c98 --- /dev/null +++ b/tests/Issues/Issue/Issue72Test.php @@ -0,0 +1,46 @@ +generateClassFromFile('OneOfExample.json'); + + $object = new $className(['label' => 'Hannes']); + $this->assertSame('Hannes', $object->getLabel()); + } + + public function testNestedAllOf(): void + { + $this->markTestSkipped('Not functional yet'); + + $className = $this->generateClassFromFile('NestedAllOf.json'); + + $company = new $className([ + 'CEO' => [ + 'yearsInCompany' => 10, + 'name' => 'Hannes', + 'salary' => 10000, + 'assistance' => [ + 'yearsInCompany' => 4, + 'name' => 'Dieter', + 'salary' => 8000, + ], + ], + ]); + + $this->assertSame(10, $company->getCEO()->getYearsInCompany()); + $this->assertSame('Hannes', $company->getCEO()->getName()); + $this->assertSame(10000, $company->getCEO()->getSalary()); + } +} diff --git a/tests/Schema/Issues/72/NestedAllOf.json b/tests/Schema/Issues/72/NestedAllOf.json new file mode 100644 index 0000000..ac70b5a --- /dev/null +++ b/tests/Schema/Issues/72/NestedAllOf.json @@ -0,0 +1,60 @@ +{ + "definitions": { + "basic": { + "allOf": [ + { + "$ref": "#/definitions/identification" + }, + { + "type": "object", + "properties": { + "yearsInCompany": { + "type": "integer" + } + } + } + ] + }, + "identification": { + "allOf": [ + { + "$ref": "#/definitions/contract" + }, + { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + ] + }, + "contract": { + "type": "object", + "properties": { + "salary": { + "type": "integer" + } + } + } + }, + "type": "object", + "properties": { + "CEO": { + "allOf": [ + { + "$ref": "#/definitions/basic" + }, + { + "type": "object", + "properties": { + "assistance": { + "$ref": "#/definitions/basic" + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/tests/Schema/Issues/72/OneOfExample.json b/tests/Schema/Issues/72/OneOfExample.json new file mode 100644 index 0000000..abeae22 --- /dev/null +++ b/tests/Schema/Issues/72/OneOfExample.json @@ -0,0 +1,26 @@ +{ + "definitions": { + "name": { + "type": "object", + "properties": { + "label": { + "type": "string" + } + } + }, + "nameExample": { + "example": { + "label": "ABC" + } + } + }, + "type": "object", + "oneOf": [ + { + "$ref": "#/definitions/name" + }, + { + "$ref": "#/definitions/nameExample" + } + ] +} \ No newline at end of file