coupon-admin/vendor/zircote/swagger-php/src/Processors/AugmentSchemas.php

115 lines
4.5 KiB
PHP

<?php declare(strict_types=1);
/**
* @license Apache 2.0
*/
namespace OpenApi\Processors;
use OpenApi\Analysis;
use OpenApi\Annotations\Property;
use OpenApi\Annotations\Schema;
use OpenApi\Generator;
/**
* Use the Schema context to extract useful information and inject that into the annotation.
*
* Merges properties.
*/
class AugmentSchemas
{
public function __invoke(Analysis $analysis)
{
/** @var Schema[] $schemas */
$schemas = $analysis->getAnnotationsOfType(Schema::class);
// Use the class names for @OA\Schema()
foreach ($schemas as $schema) {
if ($schema->schema === Generator::UNDEFINED) {
if ($schema->_context->is('class')) {
$schema->schema = $schema->_context->class;
} elseif ($schema->_context->is('interface')) {
$schema->schema = $schema->_context->interface;
} elseif ($schema->_context->is('trait')) {
$schema->schema = $schema->_context->trait;
}
}
}
// Merge unmerged @OA\Property annotations into the @OA\Schema of the class
$unmergedProperties = $analysis->unmerged()->getAnnotationsOfType(Property::class);
foreach ($unmergedProperties as $property) {
if ($property->_context->nested) {
continue;
}
$schemaContext = $property->_context->with('class') ?: $property->_context->with('trait') ?: $property->_context->with('interface');
if ($schemaContext->annotations) {
foreach ($schemaContext->annotations as $annotation) {
if ($annotation instanceof Schema) {
if ($annotation->_context->nested) {
// we shouldn't merge property into nested schemas
continue;
}
if ($annotation->allOf !== Generator::UNDEFINED) {
$schema = null;
foreach ($annotation->allOf as $nestedSchema) {
if ($nestedSchema->ref !== Generator::UNDEFINED) {
continue;
}
$schema = $nestedSchema;
}
if ($schema === null) {
$schema = new Schema(['_context' => $annotation->_context]);
$annotation->allOf[] = $schema;
}
$schema->merge([$property], true);
break;
}
$annotation->merge([$property], true);
break;
}
}
}
}
// set schema type based on various properties
foreach ($schemas as $schema) {
if ($schema->type === Generator::UNDEFINED) {
if (is_array($schema->properties) && count($schema->properties) > 0) {
$schema->type = 'object';
} elseif (is_array($schema->additionalProperties) && count($schema->additionalProperties) > 0) {
$schema->type = 'object';
} elseif (is_array($schema->patternProperties) && count($schema->patternProperties) > 0) {
$schema->type = 'object';
} elseif (is_array($schema->propertyNames) && count($schema->propertyNames) > 0) {
$schema->type = 'object';
}
}
}
// move schema properties into allOf if both exist
foreach ($schemas as $schema) {
if ($schema->properties !== Generator::UNDEFINED and $schema->allOf !== Generator::UNDEFINED) {
$allOfPropertiesSchema = null;
foreach ($schema->allOf as $allOfSchema) {
if ($allOfSchema->ref === Generator::UNDEFINED) {
$allOfPropertiesSchema = $allOfSchema;
break;
}
}
if (!$allOfPropertiesSchema) {
$allOfPropertiesSchema = new Schema(['_context' => $schema->_context, 'properties' => []]);
$schema->allOf[] = $allOfPropertiesSchema;
}
$allOfPropertiesSchema->properties = array_merge($allOfPropertiesSchema->properties, $schema->properties);
$schema->properties = Generator::UNDEFINED;
}
}
}
}