AugmentSchemas.php 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php declare(strict_types=1);
  2. /**
  3. * @license Apache 2.0
  4. */
  5. namespace OpenApi\Processors;
  6. use OpenApi\Analysis;
  7. use OpenApi\Annotations\Schema;
  8. use OpenApi\Annotations\Property;
  9. /**
  10. * Use the Schema context to extract useful information and inject that into the annotation.
  11. * Merges properties
  12. */
  13. class AugmentSchemas
  14. {
  15. public function __invoke(Analysis $analysis)
  16. {
  17. $schemas = $analysis->getAnnotationsOfType(Schema::class);
  18. // Use the class names for @OA\Schema()
  19. foreach ($schemas as $schema) {
  20. if ($schema->schema === UNDEFINED) {
  21. if ($schema->_context->is('class')) {
  22. $schema->schema = $schema->_context->class;
  23. } elseif ($schema->_context->is('interface')) {
  24. $schema->schema = $schema->_context->interface;
  25. } elseif ($schema->_context->is('trait')) {
  26. $schema->schema = $schema->_context->trait;
  27. }
  28. }
  29. }
  30. // Merge unmerged @OA\Property annotations into the @OA\Schema of the class
  31. $unmergedProperties = $analysis->unmerged()->getAnnotationsOfType(Property::class);
  32. foreach ($unmergedProperties as $property) {
  33. if ($property->_context->nested) {
  34. continue;
  35. }
  36. $schemaContext = $property->_context->with('class') ?: $property->_context->with('trait') ?: $property->_context->with('interface');
  37. if ($schemaContext->annotations) {
  38. foreach ($schemaContext->annotations as $annotation) {
  39. if ($annotation instanceof Schema) {
  40. if ($annotation->_context->nested) {
  41. //we should'not merge property into nested schemas
  42. continue;
  43. }
  44. if ($annotation->allOf !== UNDEFINED) {
  45. $schema = null;
  46. foreach ($annotation->allOf as $nestedSchema) {
  47. if ($nestedSchema->ref !== UNDEFINED) {
  48. continue;
  49. }
  50. $schema = $nestedSchema;
  51. }
  52. if ($schema === null) {
  53. $schema = new Schema(['_context' => $annotation->_context]);
  54. $annotation->allOf[] = $schema;
  55. }
  56. $schema->merge([$property], true);
  57. break;
  58. }
  59. $annotation->merge([$property], true);
  60. break;
  61. }
  62. }
  63. }
  64. }
  65. foreach ($schemas as $schema) {
  66. if ($schema->type === UNDEFINED) {
  67. if (is_array($schema->properties) && count($schema->properties) > 0) {
  68. $schema->type = 'object';
  69. } elseif (is_array($schema->additionalProperties) && count($schema->additionalProperties) > 0) {
  70. $schema->type = 'object';
  71. } elseif (is_array($schema->patternProperties) && count($schema->patternProperties) > 0) {
  72. $schema->type = 'object';
  73. } elseif (is_array($schema->propertyNames) && count($schema->propertyNames) > 0) {
  74. $schema->type = 'object';
  75. }
  76. }
  77. }
  78. }
  79. }