diff --git a/Examples/Readme.md b/Examples/Readme.md index c0e7bbc4c..5c296e4ee 100644 --- a/Examples/Readme.md +++ b/Examples/Readme.md @@ -35,6 +35,7 @@ Collection of code/annotation examples and their corresponding OpenAPI specs gen * using traits: [source](using-traits) / [spec](using-traits/using-traits.yaml) * using refs: [source](using-refs) / [spec](using-refs/using-refs.yaml) * nested schemas and class hierachies: [source](nesting) / [spec](nesting/nesting.yaml) + * polymorphism using `@OA\Discriminator`: [source](polymorphism) / [spec](polymorphism/polymorphism.yaml) ## Custom processors diff --git a/Examples/polymorphism/AbstractResponsible.php b/Examples/polymorphism/AbstractResponsible.php new file mode 100644 index 000000000..26192d98b --- /dev/null +++ b/Examples/polymorphism/AbstractResponsible.php @@ -0,0 +1,38 @@ +type = static::TYPE; + } +} diff --git a/Examples/polymorphism/Controller.php b/Examples/polymorphism/Controller.php new file mode 100644 index 000000000..d5d30cd72 --- /dev/null +++ b/Examples/polymorphism/Controller.php @@ -0,0 +1,25 @@ +annotations)) { - foreach ($definition['context']->annotations as $annotation) { - if (get_class($annotation) === Schema::class) { + foreach (array_reverse($definition['context']->annotations) as $annotation) { + if (get_class($annotation) === Schema::class && !$annotation->_aux) { return $annotation; } } diff --git a/src/Annotations/AbstractAnnotation.php b/src/Annotations/AbstractAnnotation.php index b7cbac0ee..806be141b 100644 --- a/src/Annotations/AbstractAnnotation.php +++ b/src/Annotations/AbstractAnnotation.php @@ -33,6 +33,11 @@ abstract class AbstractAnnotation implements \JsonSerializable */ public $attachables = Generator::UNDEFINED; + /** + * @var bool + */ + public $_aux = false; + /** * @var Context */ @@ -88,7 +93,7 @@ abstract class AbstractAnnotation implements \JsonSerializable * * @var array */ - public static $_blacklist = ['_context', '_unmerged', 'attachables']; + public static $_blacklist = ['_context', '_unmerged', '_analysis', '_aux', 'attachables']; public function __construct(array $properties) { diff --git a/src/Annotations/Flow.php b/src/Annotations/Flow.php index f05b6432b..08863df30 100644 --- a/src/Annotations/Flow.php +++ b/src/Annotations/Flow.php @@ -57,11 +57,6 @@ abstract class AbstractFlow extends AbstractAnnotation */ public static $_required = ['scopes', 'flow']; - /** - * @inheritdoc - */ - public static $_blacklist = ['_context', '_unmerged']; - /** * @inheritdoc */ diff --git a/src/Annotations/OpenApi.php b/src/Annotations/OpenApi.php index 2fd7eb681..15d4ff445 100644 --- a/src/Annotations/OpenApi.php +++ b/src/Annotations/OpenApi.php @@ -98,11 +98,6 @@ class AbstractOpenApi extends AbstractAnnotation */ public $_analysis = Generator::UNDEFINED; - /** - * @inheritdoc - */ - public static $_blacklist = ['_context', '_unmerged', '_analysis']; - /** * @inheritdoc */ diff --git a/src/Processors/AugmentProperties.php b/src/Processors/AugmentProperties.php index fe2137a95..d670ca5d8 100644 --- a/src/Processors/AugmentProperties.php +++ b/src/Processors/AugmentProperties.php @@ -124,8 +124,9 @@ protected function augmentType(Property $property, Context $context, array $refs $refKey = $this->toRefKey($context, $type); $property->oneOf = [ new Schema([ - '_context' => $property->_context, 'ref' => $refs[$refKey], + '_context' => $property->_context, + '_aux' => true, ]), ]; $property->nullable = true; @@ -135,6 +136,7 @@ protected function augmentType(Property $property, Context $context, array $refs [ 'type' => $property->type, '_context' => new Context(['generated' => true], $context), + '_aux' => true, ] ); if ($property->ref !== Generator::UNDEFINED) { @@ -204,8 +206,9 @@ protected function applyRef(Property $property, string $ref): void if ($property->nullable === true) { $property->oneOf = [ new Schema([ - '_context' => $property->_context, 'ref' => $ref, + '_context' => $property->_context, + '_aux' => true, ]), ]; } else { diff --git a/src/Processors/AugmentSchemas.php b/src/Processors/AugmentSchemas.php index 2052f9bbd..8ed3966ff 100644 --- a/src/Processors/AugmentSchemas.php +++ b/src/Processors/AugmentSchemas.php @@ -63,7 +63,10 @@ public function __invoke(Analysis $analysis) } if ($schema === null) { - $schema = new Schema(['_context' => $annotation->_context]); + $schema = new Schema([ + '_context' => $annotation->_context, + '_aux' => true, + ]); $annotation->allOf[] = $schema; } @@ -104,7 +107,11 @@ public function __invoke(Analysis $analysis) } } if (!$allOfPropertiesSchema) { - $allOfPropertiesSchema = new Schema(['_context' => $schema->_context, 'properties' => []]); + $allOfPropertiesSchema = new Schema([ + 'properties' => [], + '_context' => $schema->_context, + '_aux' => true, + ]); $schema->allOf[] = $allOfPropertiesSchema; } $allOfPropertiesSchema->properties = array_merge($allOfPropertiesSchema->properties, $schema->properties); diff --git a/src/Processors/BuildPaths.php b/src/Processors/BuildPaths.php index c11591853..f44e88fd6 100644 --- a/src/Processors/BuildPaths.php +++ b/src/Processors/BuildPaths.php @@ -45,6 +45,7 @@ public function __invoke(Analysis $analysis) [ 'path' => $operation->path, '_context' => new Context(['generated' => true], $operation->_context), + '_aux' => true, ] ); $analysis->annotations->attach($paths[$operation->path]); diff --git a/src/Processors/MergeJsonContent.php b/src/Processors/MergeJsonContent.php index e7ef1c299..b26d7362d 100644 --- a/src/Processors/MergeJsonContent.php +++ b/src/Processors/MergeJsonContent.php @@ -43,6 +43,7 @@ public function __invoke(Analysis $analysis) 'example' => $jsonContent->example, 'examples' => $jsonContent->examples, '_context' => new Context(['generated' => true], $jsonContent->_context), + '_aux' => true, ]); if (!$parent instanceof Parameter) { $parent->content['application/json']->mediaType = 'application/json'; diff --git a/src/Processors/MergeTrait.php b/src/Processors/MergeTrait.php index 8706d34f5..488c12534 100644 --- a/src/Processors/MergeTrait.php +++ b/src/Processors/MergeTrait.php @@ -31,8 +31,9 @@ protected function inheritFrom(Schema $schema, Schema $from, string $refPath, Co } // merging other properties into allOf is done in the AugmentSchemas processor $schema->allOf[] = new Schema([ - '_context' => $context, 'ref' => Components::SCHEMA_REF . Util::refEncode($refPath), + '_context' => $context, + '_aux' => true, ]); } diff --git a/src/Processors/MergeXmlContent.php b/src/Processors/MergeXmlContent.php index 33fba6d3f..908c36a71 100644 --- a/src/Processors/MergeXmlContent.php +++ b/src/Processors/MergeXmlContent.php @@ -43,6 +43,7 @@ public function __invoke(Analysis $analysis) 'example' => $xmlContent->example, 'examples' => $xmlContent->examples, '_context' => new Context(['generated' => true], $xmlContent->_context), + '_aux' => true, ]); if (!$parent instanceof Parameter) { $parent->content['application/xml']->mediaType = 'application/xml'; diff --git a/tests/UtilTest.php b/tests/UtilTest.php index 2316950bb..6c14e19f9 100644 --- a/tests/UtilTest.php +++ b/tests/UtilTest.php @@ -24,6 +24,7 @@ public function testExclude() 'InheritProperties', 'Apis', 'PHP', + 'Parser', 'Analysers', 'Processors', 'UsingRefs.php',