mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 23:59:26 +03:00
Use the same root context everywhere
This commit is contained in:
parent
2295f68b89
commit
52e7fc4de1
@ -91,7 +91,14 @@ final class ApiDocGenerator
|
|||||||
return !$processor instanceof \OpenApi\Processors\OperationId;
|
return !$processor instanceof \OpenApi\Processors\OperationId;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$this->openApi = new OpenApi([]);
|
$context = Util::createContext(
|
||||||
|
// BC for for zircote/swagger-php < 4.2
|
||||||
|
method_exists($generator, 'getVersion')
|
||||||
|
? ['version' => $generator->getVersion()]
|
||||||
|
: []
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->openApi = new OpenApi(['_context' => $context]);
|
||||||
$modelRegistry = new ModelRegistry($this->modelDescribers, $this->openApi, $this->alternativeNames);
|
$modelRegistry = new ModelRegistry($this->modelDescribers, $this->openApi, $this->alternativeNames);
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$modelRegistry->setLogger($this->logger);
|
$modelRegistry->setLogger($this->logger);
|
||||||
@ -103,13 +110,6 @@ final class ApiDocGenerator
|
|||||||
|
|
||||||
$describer->describe($this->openApi);
|
$describer->describe($this->openApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
$context = Util::createContext(
|
|
||||||
// BC for for zircote/swagger-php < 4.2
|
|
||||||
method_exists($generator, 'getVersion')
|
|
||||||
? ['version' => $generator->getVersion()]
|
|
||||||
: []
|
|
||||||
);
|
|
||||||
$analysis = new Analysis([], $context);
|
$analysis = new Analysis([], $context);
|
||||||
$analysis->addAnnotation($this->openApi, $context);
|
$analysis->addAnnotation($this->openApi, $context);
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ final class ModelRegistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reserve the name
|
// Reserve the name
|
||||||
Util::getSchema($this->api, $this->names[$hash]);
|
$s = Util::getSchema($this->api, $this->names[$hash]);
|
||||||
|
|
||||||
return OA\Components::SCHEMA_REF.$this->names[$hash];
|
return OA\Components::SCHEMA_REF.$this->names[$hash];
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,15 @@ class OpenApiAnnotationsReader
|
|||||||
|
|
||||||
public function updateSchema(\ReflectionClass $reflectionClass, OA\Schema $schema): void
|
public function updateSchema(\ReflectionClass $reflectionClass, OA\Schema $schema): void
|
||||||
{
|
{
|
||||||
|
$this->setContext(Util::createContext([], $schema->_context));
|
||||||
|
|
||||||
/** @var OA\Schema|null $oaSchema */
|
/** @var OA\Schema|null $oaSchema */
|
||||||
if (!$oaSchema = $this->getAnnotation($reflectionClass, OA\Schema::class)) {
|
if (!$oaSchema = $this->getAnnotation($reflectionClass, OA\Schema::class)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setContext(null);
|
||||||
|
|
||||||
// Read @Model annotations
|
// Read @Model annotations
|
||||||
$this->modelRegister->__invoke(new Analysis([$oaSchema], Util::createContext()));
|
$this->modelRegister->__invoke(new Analysis([$oaSchema], Util::createContext()));
|
||||||
|
|
||||||
@ -69,12 +73,12 @@ class OpenApiAnnotationsReader
|
|||||||
// In order to have nicer errors
|
// In order to have nicer errors
|
||||||
$declaringClass = $reflection->getDeclaringClass();
|
$declaringClass = $reflection->getDeclaringClass();
|
||||||
|
|
||||||
$this->setContext(new Context([
|
$this->setContext(Util::createContext([
|
||||||
'namespace' => $declaringClass->getNamespaceName(),
|
'namespace' => $declaringClass->getNamespaceName(),
|
||||||
'class' => $declaringClass->getShortName(),
|
'class' => $declaringClass->getShortName(),
|
||||||
'property' => $reflection->name,
|
'property' => $reflection->name,
|
||||||
'filename' => $declaringClass->getFileName(),
|
'filename' => $declaringClass->getFileName(),
|
||||||
]));
|
], $property->_context));
|
||||||
|
|
||||||
/** @var OA\Property|null $oaProperty */
|
/** @var OA\Property|null $oaProperty */
|
||||||
if (!$oaProperty = $this->getAnnotation($reflection, OA\Property::class)) {
|
if (!$oaProperty = $this->getAnnotation($reflection, OA\Property::class)) {
|
||||||
|
@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\ModelDescriber;
|
|||||||
|
|
||||||
use Nelmio\ApiDocBundle\Model\Model;
|
use Nelmio\ApiDocBundle\Model\Model;
|
||||||
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
||||||
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
|
||||||
@ -43,18 +44,18 @@ trait ApplyOpenApiDiscriminatorTrait
|
|||||||
array $typeMap
|
array $typeMap
|
||||||
): void {
|
): void {
|
||||||
$schema->oneOf = [];
|
$schema->oneOf = [];
|
||||||
$schema->discriminator = new OA\Discriminator([]);
|
$discriminator = Util::getChild($schema, OA\Discriminator::class);
|
||||||
$schema->discriminator->propertyName = $discriminatorProperty;
|
$discriminator->propertyName = $discriminatorProperty;
|
||||||
$schema->discriminator->mapping = [];
|
$discriminator->mapping = [];
|
||||||
foreach ($typeMap as $propertyValue => $className) {
|
foreach ($typeMap as $propertyValue => $className) {
|
||||||
$oneOfSchema = new OA\Schema([]);
|
$oneOfSchema = Util::createChild($schema, OA\Schema::class);
|
||||||
$oneOfSchema->ref = $modelRegistry->register(new Model(
|
$oneOfSchema->ref = $modelRegistry->register(new Model(
|
||||||
new Type(Type::BUILTIN_TYPE_OBJECT, false, $className),
|
new Type(Type::BUILTIN_TYPE_OBJECT, false, $className),
|
||||||
$model->getGroups(),
|
$model->getGroups(),
|
||||||
$model->getOptions()
|
$model->getOptions()
|
||||||
));
|
));
|
||||||
$schema->oneOf[] = $oneOfSchema;
|
$schema->oneOf[] = $oneOfSchema;
|
||||||
$schema->discriminator->mapping[$propertyValue] = $oneOfSchema->ref;
|
$discriminator->mapping[$propertyValue] = $oneOfSchema->ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
$ref = $this->modelRegistry->register($model);
|
$ref = $this->modelRegistry->register($model);
|
||||||
// We need to use allOf for description and title to be displayed
|
// We need to use allOf for description and title to be displayed
|
||||||
if ($config->hasOption('documentation') && !empty($config->getOption('documentation'))) {
|
if ($config->hasOption('documentation') && !empty($config->getOption('documentation'))) {
|
||||||
$property->allOf = [new OA\Schema(['ref' => $ref])];
|
$property->allOf = [Util::createChild($property, OA\Schema::class, ['ref' => $ref])];
|
||||||
} else {
|
} else {
|
||||||
$property->ref = $ref;
|
$property->ref = $ref;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
|
|||||||
if (empty($customFields)) { // no custom fields
|
if (empty($customFields)) { // no custom fields
|
||||||
$property->ref = $modelRef;
|
$property->ref = $modelRef;
|
||||||
} else {
|
} else {
|
||||||
$property->allOf = [new OA\Schema(['ref' => $modelRef])];
|
$property->allOf = [Util::createChild($property, OA\Schema::class, ['ref' => $modelRef])];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->contexts[$model->getHash()] = $context;
|
$this->contexts[$model->getHash()] = $context;
|
||||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\OpenApiPhp;
|
|||||||
use Nelmio\ApiDocBundle\Annotation\Model as ModelAnnotation;
|
use Nelmio\ApiDocBundle\Annotation\Model as ModelAnnotation;
|
||||||
use Nelmio\ApiDocBundle\Model\Model;
|
use Nelmio\ApiDocBundle\Model\Model;
|
||||||
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
||||||
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Analysis;
|
use OpenApi\Analysis;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
@ -154,11 +155,11 @@ final class ModelRegister
|
|||||||
) {
|
) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'json':
|
case 'json':
|
||||||
$modelAnnotation = new OA\JsonContent($properties);
|
$modelAnnotation = Util::createChild($annotation, OA\JsonContent::class, $properties);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'xml':
|
case 'xml':
|
||||||
$modelAnnotation = new OA\XmlContent($properties);
|
$modelAnnotation = Util::createChild($annotation, OA\XmlContent, $properties);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -84,7 +84,7 @@ final class Util
|
|||||||
public static function getSchema(OA\OpenApi $api, $schema): OA\Schema
|
public static function getSchema(OA\OpenApi $api, $schema): OA\Schema
|
||||||
{
|
{
|
||||||
if (!$api->components instanceof OA\Components) {
|
if (!$api->components instanceof OA\Components) {
|
||||||
$api->components = new OA\Components([]);
|
$api->components = self::createChild($api, OA\Components::class, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::getIndexedCollectionItem($api->components, OA\Schema::class, $schema);
|
return self::getIndexedCollectionItem($api->components, OA\Schema::class, $schema);
|
||||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\PropertyDescriber;
|
|||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
||||||
use Nelmio\ApiDocBundle\Model\Model;
|
use Nelmio\ApiDocBundle\Model\Model;
|
||||||
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ class ObjectPropertyDescriber implements PropertyDescriberInterface, ModelRegist
|
|||||||
|
|
||||||
if ($types[0]->isNullable()) {
|
if ($types[0]->isNullable()) {
|
||||||
$property->nullable = true;
|
$property->nullable = true;
|
||||||
$property->allOf = [new OA\Schema(['ref' => $this->modelRegistry->register(new Model($type, $groups))])];
|
$property->allOf = [Util::createChild($property, OA\Schema::class, ['ref' => $this->modelRegistry->register(new Model($type, $groups))])];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ final class FosRestDescriber implements RouteDescriberInterface
|
|||||||
throw new \InvalidArgumentException('Unsupported media type');
|
throw new \InvalidArgumentException('Unsupported media type');
|
||||||
}
|
}
|
||||||
if (!isset($requestBody->content[$contentType])) {
|
if (!isset($requestBody->content[$contentType])) {
|
||||||
$requestBody->content[$contentType] = new OA\MediaType(
|
$requestBody->content[$contentType] = Util::createChild($requestBody, OA\MediaType::class,
|
||||||
[
|
[
|
||||||
'mediaType' => $contentType,
|
'mediaType' => $contentType,
|
||||||
]
|
]
|
||||||
|
39
Tests/Functional/SwaggerPHPApiComplianceTest.php
Normal file
39
Tests/Functional/SwaggerPHPApiComplianceTest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Functional;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
|
use Nelmio\ApiDocBundle\Tests\Helper;
|
||||||
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Analysis;
|
||||||
|
use Symfony\Component\Serializer\Annotation\SerializedName;
|
||||||
|
|
||||||
|
class SwaggerPHPApiComplianceTest extends WebTestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
static::createClient([], ['HTTP_HOST' => 'api.example.com']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAllContextsHaveSameRoot()
|
||||||
|
{
|
||||||
|
$openApi = $this->getOpenApiDefinition();
|
||||||
|
$root = $openApi->_context;
|
||||||
|
|
||||||
|
$counter = 0;
|
||||||
|
foreach ((new Analysis([$openApi], Util::createContext()))->annotations as $annotation) {
|
||||||
|
$this->assertSame($annotation->_context->root(), $root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user