mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 15:51:48 +03:00
Add support for zircore/swagger-php 4.0 (#1916)
* add zircore/swagger-php v4 to composer.json * fix incompatibilities * add compatibility with 3.2 * Apply fixes from StyleCI * mark SetsContextTrait as internal * Bump php version Co-authored-by: Alexey <alshenestky@icloud.com> Co-authored-by: Alexey Alshenetsky <alshenetsky@users.noreply.github.com> Co-authored-by: Guilhem Niot <guilhem@gniot.fr>
This commit is contained in:
parent
a041c69a0c
commit
14383f4ee5
2
.github/workflows/continuous-integration.yml
vendored
2
.github/workflows/continuous-integration.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- php-version: 7.1
|
- php-version: 7.2
|
||||||
composer-flags: "--prefer-lowest"
|
composer-flags: "--prefer-lowest"
|
||||||
- php-version: 7.2
|
- php-version: 7.2
|
||||||
symfony-require: "^4.0"
|
symfony-require: "^4.0"
|
||||||
|
@ -20,6 +20,7 @@ use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister;
|
|||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Analysis;
|
use OpenApi\Analysis;
|
||||||
use OpenApi\Annotations\OpenApi;
|
use OpenApi\Annotations\OpenApi;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Psr\Log\LoggerAwareTrait;
|
use Psr\Log\LoggerAwareTrait;
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ final class ApiDocGenerator
|
|||||||
$defaultOperationIdProcessor = new DefaultOperationId();
|
$defaultOperationIdProcessor = new DefaultOperationId();
|
||||||
$defaultOperationIdProcessor($analysis);
|
$defaultOperationIdProcessor($analysis);
|
||||||
|
|
||||||
$analysis->process();
|
$analysis->process((new Generator())->getProcessors());
|
||||||
$analysis->validate();
|
$analysis->validate();
|
||||||
|
|
||||||
if (isset($item)) {
|
if (isset($item)) {
|
||||||
|
@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\Describer;
|
|||||||
|
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the swagger documentation valid even if there are missing fields.
|
* Makes the swagger documentation valid even if there are missing fields.
|
||||||
@ -26,22 +27,22 @@ final class DefaultDescriber implements DescriberInterface
|
|||||||
// Info
|
// Info
|
||||||
/** @var OA\Info $info */
|
/** @var OA\Info $info */
|
||||||
$info = Util::getChild($api, OA\Info::class);
|
$info = Util::getChild($api, OA\Info::class);
|
||||||
if (OA\UNDEFINED === $info->title) {
|
if (Generator::UNDEFINED === $info->title) {
|
||||||
$info->title = '';
|
$info->title = '';
|
||||||
}
|
}
|
||||||
if (OA\UNDEFINED === $info->version) {
|
if (Generator::UNDEFINED === $info->version) {
|
||||||
$info->version = '0.0.0';
|
$info->version = '0.0.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
if (OA\UNDEFINED === $api->paths) {
|
if (Generator::UNDEFINED === $api->paths) {
|
||||||
$api->paths = [];
|
$api->paths = [];
|
||||||
}
|
}
|
||||||
foreach ($api->paths as $path) {
|
foreach ($api->paths as $path) {
|
||||||
foreach (Util::OPERATIONS as $method) {
|
foreach (Util::OPERATIONS as $method) {
|
||||||
/** @var OA\Operation $operation */
|
/** @var OA\Operation $operation */
|
||||||
$operation = $path->{$method};
|
$operation = $path->{$method};
|
||||||
if (OA\UNDEFINED !== $operation && null !== $operation && (OA\UNDEFINED === $operation->responses || empty($operation->responses))) {
|
if (Generator::UNDEFINED !== $operation && null !== $operation && (Generator::UNDEFINED === $operation->responses || empty($operation->responses))) {
|
||||||
/** @var OA\Response $response */
|
/** @var OA\Response $response */
|
||||||
$response = Util::getIndexedCollectionItem($operation, OA\Response::class, 'default');
|
$response = Util::getIndexedCollectionItem($operation, OA\Response::class, 'default');
|
||||||
$response->description = '';
|
$response->description = '';
|
||||||
|
@ -16,8 +16,9 @@ use Nelmio\ApiDocBundle\Annotation\Operation;
|
|||||||
use Nelmio\ApiDocBundle\Annotation\Security;
|
use Nelmio\ApiDocBundle\Annotation\Security;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use Nelmio\ApiDocBundle\Util\ControllerReflector;
|
use Nelmio\ApiDocBundle\Util\ControllerReflector;
|
||||||
use OpenApi\Analyser;
|
use Nelmio\ApiDocBundle\Util\SetsContextTrait;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
@ -27,6 +28,8 @@ class_exists(OA\OpenApi::class);
|
|||||||
|
|
||||||
final class OpenApiPhpDescriber
|
final class OpenApiPhpDescriber
|
||||||
{
|
{
|
||||||
|
use SetsContextTrait;
|
||||||
|
|
||||||
private $routeCollection;
|
private $routeCollection;
|
||||||
private $controllerReflector;
|
private $controllerReflector;
|
||||||
private $annotationReader;
|
private $annotationReader;
|
||||||
@ -52,11 +55,13 @@ final class OpenApiPhpDescriber
|
|||||||
|
|
||||||
$path = Util::getPath($api, $path);
|
$path = Util::getPath($api, $path);
|
||||||
|
|
||||||
Analyser::$context = Util::createContext(['nested' => $path], $path->_context);
|
$context = Util::createContext(['nested' => $path], $path->_context);
|
||||||
Analyser::$context->namespace = $method->getNamespaceName();
|
$context->namespace = $method->getNamespaceName();
|
||||||
Analyser::$context->class = $declaringClass->getShortName();
|
$context->class = $declaringClass->getShortName();
|
||||||
Analyser::$context->method = $method->name;
|
$context->method = $method->name;
|
||||||
Analyser::$context->filename = $method->getFileName();
|
$context->filename = $method->getFileName();
|
||||||
|
|
||||||
|
$this->setContext($context);
|
||||||
|
|
||||||
if (!array_key_exists($declaringClass->getName(), $classAnnotations)) {
|
if (!array_key_exists($declaringClass->getName(), $classAnnotations)) {
|
||||||
$classAnnotations = array_filter($this->annotationReader->getClassAnnotations($declaringClass), function ($v) {
|
$classAnnotations = array_filter($this->annotationReader->getClassAnnotations($declaringClass), function ($v) {
|
||||||
@ -90,7 +95,7 @@ final class OpenApiPhpDescriber
|
|||||||
if (!in_array($annotation->method, $httpMethods, true)) {
|
if (!in_array($annotation->method, $httpMethods, true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (OA\UNDEFINED !== $annotation->path && $path->path !== $annotation->path) {
|
if (Generator::UNDEFINED !== $annotation->path && $path->path !== $annotation->path) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,14 +140,14 @@ final class OpenApiPhpDescriber
|
|||||||
$operation->merge($implicitAnnotations);
|
$operation->merge($implicitAnnotations);
|
||||||
$operation->mergeProperties($mergeProperties);
|
$operation->mergeProperties($mergeProperties);
|
||||||
|
|
||||||
if (OA\UNDEFINED === $operation->operationId) {
|
if (Generator::UNDEFINED === $operation->operationId) {
|
||||||
$operation->operationId = $httpMethod.'_'.$routeName;
|
$operation->operationId = $httpMethod.'_'.$routeName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the Analyser after the parsing
|
// Reset the Generator after the parsing
|
||||||
Analyser::$context = null;
|
$this->setContext(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMethodsToParse(): \Generator
|
private function getMethodsToParse(): \Generator
|
||||||
|
@ -15,16 +15,19 @@ use Doctrine\Common\Annotations\Reader;
|
|||||||
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister;
|
use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Analyser;
|
use Nelmio\ApiDocBundle\Util\SetsContextTrait;
|
||||||
use OpenApi\Analysis;
|
use OpenApi\Analysis;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use OpenApi\Context;
|
use OpenApi\Context;
|
||||||
|
use OpenApi\Generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
class OpenApiAnnotationsReader
|
class OpenApiAnnotationsReader
|
||||||
{
|
{
|
||||||
|
use SetsContextTrait;
|
||||||
|
|
||||||
private $annotationsReader;
|
private $annotationsReader;
|
||||||
private $modelRegister;
|
private $modelRegister;
|
||||||
|
|
||||||
@ -60,19 +63,20 @@ class OpenApiAnnotationsReader
|
|||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OA\UNDEFINED !== $oaProperty->property ? $oaProperty->property : $default;
|
return Generator::UNDEFINED !== $oaProperty->property ? $oaProperty->property : $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateProperty($reflection, OA\Property $property, array $serializationGroups = null): void
|
public function updateProperty($reflection, OA\Property $property, array $serializationGroups = null): void
|
||||||
{
|
{
|
||||||
// In order to have nicer errors
|
// In order to have nicer errors
|
||||||
$declaringClass = $reflection->getDeclaringClass();
|
$declaringClass = $reflection->getDeclaringClass();
|
||||||
Analyser::$context = new Context([
|
|
||||||
|
$this->setContext(new Context([
|
||||||
'namespace' => $declaringClass->getNamespaceName(),
|
'namespace' => $declaringClass->getNamespaceName(),
|
||||||
'class' => $declaringClass->getShortName(),
|
'class' => $declaringClass->getShortName(),
|
||||||
'property' => $reflection->name,
|
'property' => $reflection->name,
|
||||||
'filename' => $declaringClass->getFileName(),
|
'filename' => $declaringClass->getFileName(),
|
||||||
]);
|
]));
|
||||||
|
|
||||||
/** @var OA\Property $oaProperty */
|
/** @var OA\Property $oaProperty */
|
||||||
if ($reflection instanceof \ReflectionProperty && !$oaProperty = $this->annotationsReader->getPropertyAnnotation($reflection, OA\Property::class)) {
|
if ($reflection instanceof \ReflectionProperty && !$oaProperty = $this->annotationsReader->getPropertyAnnotation($reflection, OA\Property::class)) {
|
||||||
@ -80,7 +84,7 @@ class OpenApiAnnotationsReader
|
|||||||
} elseif ($reflection instanceof \ReflectionMethod && !$oaProperty = $this->annotationsReader->getMethodAnnotation($reflection, OA\Property::class)) {
|
} elseif ($reflection instanceof \ReflectionMethod && !$oaProperty = $this->annotationsReader->getMethodAnnotation($reflection, OA\Property::class)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Analyser::$context = null;
|
$this->setContext(null);
|
||||||
|
|
||||||
// Read @Model annotations
|
// Read @Model annotations
|
||||||
$this->modelRegister->__invoke(new Analysis([$oaProperty], Util::createContext()), $serializationGroups);
|
$this->modelRegister->__invoke(new Analysis([$oaProperty], Util::createContext()), $serializationGroups);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
|
namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
|
||||||
|
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
|
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
|
||||||
use phpDocumentor\Reflection\DocBlockFactory;
|
use phpDocumentor\Reflection\DocBlockFactory;
|
||||||
|
|
||||||
@ -53,10 +54,10 @@ class PropertyPhpDocReader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (OA\UNDEFINED === $property->title && $title) {
|
if (Generator::UNDEFINED === $property->title && $title) {
|
||||||
$property->title = $title;
|
$property->title = $title;
|
||||||
}
|
}
|
||||||
if (OA\UNDEFINED === $property->description && $docBlock->getDescription() && $docBlock->getDescription()->render()) {
|
if (Generator::UNDEFINED === $property->description && $docBlock->getDescription() && $docBlock->getDescription()->render()) {
|
||||||
$property->description = $docBlock->getDescription()->render();
|
$property->description = $docBlock->getDescription()->render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
|
|||||||
use Doctrine\Common\Annotations\Reader;
|
use Doctrine\Common\Annotations\Reader;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ class SymfonyConstraintAnnotationReader
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$existingRequiredFields = OA\UNDEFINED !== $this->schema->required ? $this->schema->required : [];
|
$existingRequiredFields = Generator::UNDEFINED !== $this->schema->required ? $this->schema->required : [];
|
||||||
$existingRequiredFields[] = $propertyName;
|
$existingRequiredFields[] = $propertyName;
|
||||||
|
|
||||||
$this->schema->required = array_values(array_unique($existingRequiredFields));
|
$this->schema->required = array_values(array_unique($existingRequiredFields));
|
||||||
@ -131,7 +132,7 @@ class SymfonyConstraintAnnotationReader
|
|||||||
}
|
}
|
||||||
foreach ($this->schema->properties as $schemaProperty) {
|
foreach ($this->schema->properties as $schemaProperty) {
|
||||||
if ($schemaProperty === $property) {
|
if ($schemaProperty === $property) {
|
||||||
return OA\UNDEFINED !== $schemaProperty->property ? $schemaProperty->property : null;
|
return Generator::UNDEFINED !== $schemaProperty->property ? $schemaProperty->property : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ class SymfonyConstraintAnnotationReader
|
|||||||
if (null === $newPattern) {
|
if (null === $newPattern) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (OA\UNDEFINED !== $property->pattern) {
|
if (Generator::UNDEFINED !== $property->pattern) {
|
||||||
$property->pattern = sprintf('%s, %s', $property->pattern, $newPattern);
|
$property->pattern = sprintf('%s, %s', $property->pattern, $newPattern);
|
||||||
} else {
|
} else {
|
||||||
$property->pattern = $newPattern;
|
$property->pattern = $newPattern;
|
||||||
|
@ -18,6 +18,7 @@ use Nelmio\ApiDocBundle\Model\Model;
|
|||||||
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
use Symfony\Component\Form\FormConfigInterface;
|
use Symfony\Component\Form\FormConfigInterface;
|
||||||
@ -90,7 +91,7 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
$property = Util::getProperty($schema, $name);
|
$property = Util::getProperty($schema, $name);
|
||||||
|
|
||||||
if ($config->getRequired()) {
|
if ($config->getRequired()) {
|
||||||
$required = OA\UNDEFINED !== $schema->required ? $schema->required : [];
|
$required = Generator::UNDEFINED !== $schema->required ? $schema->required : [];
|
||||||
$required[] = $name;
|
$required[] = $name;
|
||||||
|
|
||||||
$schema->required = $required;
|
$schema->required = $required;
|
||||||
@ -100,7 +101,7 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
$property->mergeProperties($config->getOption('documentation'));
|
$property->mergeProperties($config->getOption('documentation'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OA\UNDEFINED !== $property->type) {
|
if (Generator::UNDEFINED !== $property->type) {
|
||||||
continue; // Type manually defined
|
continue; // Type manually defined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ use Nelmio\ApiDocBundle\Model\Model;
|
|||||||
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,7 +135,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
|
|||||||
$annotationsReader->updateProperty($reflection, $property, $groups);
|
$annotationsReader->updateProperty($reflection, $property, $groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OA\UNDEFINED !== $property->type || OA\UNDEFINED !== $property->ref) {
|
if (Generator::UNDEFINED !== $property->type || Generator::UNDEFINED !== $property->ref) {
|
||||||
$context->popPropertyMetadata();
|
$context->popPropertyMetadata();
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -20,6 +20,7 @@ use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
|||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use Nelmio\ApiDocBundle\PropertyDescriber\PropertyDescriberInterface;
|
use Nelmio\ApiDocBundle\PropertyDescriber\PropertyDescriberInterface;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||||
@ -72,7 +73,7 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar
|
|||||||
$annotationsReader->updateDefinition($reflClass, $schema);
|
$annotationsReader->updateDefinition($reflClass, $schema);
|
||||||
|
|
||||||
$discriminatorMap = $this->doctrineReader->getClassAnnotation($reflClass, DiscriminatorMap::class);
|
$discriminatorMap = $this->doctrineReader->getClassAnnotation($reflClass, DiscriminatorMap::class);
|
||||||
if ($discriminatorMap && OA\UNDEFINED === $schema->discriminator) {
|
if ($discriminatorMap && Generator::UNDEFINED === $schema->discriminator) {
|
||||||
$this->applyOpenApiDiscriminator(
|
$this->applyOpenApiDiscriminator(
|
||||||
$model,
|
$model,
|
||||||
$schema,
|
$schema,
|
||||||
@ -114,7 +115,7 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If type manually defined
|
// If type manually defined
|
||||||
if (OA\UNDEFINED !== $property->type || OA\UNDEFINED !== $property->ref) {
|
if (Generator::UNDEFINED !== $property->type || Generator::UNDEFINED !== $property->ref) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\OpenApiPhp;
|
|||||||
|
|
||||||
use OpenApi\Analysis;
|
use OpenApi\Analysis;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the OperationId processor from zircote/swagger-php as it breaks our documentation by setting non-unique operation ids.
|
* Disable the OperationId processor from zircote/swagger-php as it breaks our documentation by setting non-unique operation ids.
|
||||||
@ -27,7 +28,7 @@ final class DefaultOperationId
|
|||||||
$allOperations = $analysis->getAnnotationsOfType(OA\Operation::class);
|
$allOperations = $analysis->getAnnotationsOfType(OA\Operation::class);
|
||||||
|
|
||||||
foreach ($allOperations as $operation) {
|
foreach ($allOperations as $operation) {
|
||||||
if (OA\UNDEFINED === $operation->operationId) {
|
if (Generator::UNDEFINED === $operation->operationId) {
|
||||||
$operation->operationId = null;
|
$operation->operationId = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ namespace Nelmio\ApiDocBundle\OpenApiPhp;
|
|||||||
|
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use OpenApi\Context;
|
use OpenApi\Context;
|
||||||
use const OpenApi\UNDEFINED;
|
use OpenApi\Generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Util.
|
* Class Util.
|
||||||
@ -163,7 +163,7 @@ final class Util
|
|||||||
$nested = $parent::$_nested;
|
$nested = $parent::$_nested;
|
||||||
$property = $nested[$class];
|
$property = $nested[$class];
|
||||||
|
|
||||||
if (null === $parent->{$property} || UNDEFINED === $parent->{$property}) {
|
if (null === $parent->{$property} || Generator::UNDEFINED === $parent->{$property}) {
|
||||||
$parent->{$property} = self::createChild($parent, $class, $properties);
|
$parent->{$property} = self::createChild($parent, $class, $properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ final class Util
|
|||||||
|
|
||||||
if (!empty($properties)) {
|
if (!empty($properties)) {
|
||||||
$key = self::searchCollectionItem(
|
$key = self::searchCollectionItem(
|
||||||
$parent->{$collection} && UNDEFINED !== $parent->{$collection} ? $parent->{$collection} : [],
|
$parent->{$collection} && Generator::UNDEFINED !== $parent->{$collection} ? $parent->{$collection} : [],
|
||||||
$properties
|
$properties
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ final class Util
|
|||||||
[$collection, $property] = $nested[$class];
|
[$collection, $property] = $nested[$class];
|
||||||
|
|
||||||
$key = self::searchIndexedCollectionItem(
|
$key = self::searchIndexedCollectionItem(
|
||||||
$parent->{$collection} && UNDEFINED !== $parent->{$collection} ? $parent->{$collection} : [],
|
$parent->{$collection} && Generator::UNDEFINED !== $parent->{$collection} ? $parent->{$collection} : [],
|
||||||
$property,
|
$property,
|
||||||
$value
|
$value
|
||||||
);
|
);
|
||||||
@ -279,7 +279,7 @@ final class Util
|
|||||||
*/
|
*/
|
||||||
public static function createCollectionItem(OA\AbstractAnnotation $parent, $collection, $class, array $properties = []): int
|
public static function createCollectionItem(OA\AbstractAnnotation $parent, $collection, $class, array $properties = []): int
|
||||||
{
|
{
|
||||||
if (UNDEFINED === $parent->{$collection}) {
|
if (Generator::UNDEFINED === $parent->{$collection}) {
|
||||||
$parent->{$collection} = [];
|
$parent->{$collection} = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +418,7 @@ final class Util
|
|||||||
if (\is_string($type) && 0 === strpos($type, '[')) {
|
if (\is_string($type) && 0 === strpos($type, '[')) {
|
||||||
$innerType = substr($type, 1, -1);
|
$innerType = substr($type, 1, -1);
|
||||||
|
|
||||||
if (!$annotation->{$propertyName} || UNDEFINED === $annotation->{$propertyName}) {
|
if (!$annotation->{$propertyName} || Generator::UNDEFINED === $annotation->{$propertyName}) {
|
||||||
$annotation->{$propertyName} = [];
|
$annotation->{$propertyName} = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
|||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
|
|
||||||
class CompoundPropertyDescriber implements PropertyDescriberInterface, ModelRegistryAwareInterface
|
class CompoundPropertyDescriber implements PropertyDescriberInterface, ModelRegistryAwareInterface
|
||||||
{
|
{
|
||||||
@ -30,7 +31,7 @@ class CompoundPropertyDescriber implements PropertyDescriberInterface, ModelRegi
|
|||||||
|
|
||||||
public function describe(array $types, OA\Schema $property, array $groups = null)
|
public function describe(array $types, OA\Schema $property, array $groups = null)
|
||||||
{
|
{
|
||||||
$property->oneOf = OA\UNDEFINED !== $property->oneOf ? $property->oneOf : [];
|
$property->oneOf = Generator::UNDEFINED !== $property->oneOf ? $property->oneOf : [];
|
||||||
|
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
$property->oneOf[] = $schema = Util::createChild($property, OA\Schema::class, []);
|
$property->oneOf[] = $schema = Util::createChild($property, OA\Schema::class, []);
|
||||||
|
@ -16,6 +16,7 @@ use FOS\RestBundle\Controller\Annotations\QueryParam;
|
|||||||
use FOS\RestBundle\Controller\Annotations\RequestParam;
|
use FOS\RestBundle\Controller\Annotations\RequestParam;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\Constraints\DateTime;
|
use Symfony\Component\Validator\Constraints\DateTime;
|
||||||
@ -55,7 +56,7 @@ final class FosRestDescriber implements RouteDescriberInterface
|
|||||||
|
|
||||||
$parameter->required = !$annotation->nullable && $annotation->strict;
|
$parameter->required = !$annotation->nullable && $annotation->strict;
|
||||||
|
|
||||||
if (OA\UNDEFINED === $parameter->description) {
|
if (Generator::UNDEFINED === $parameter->description) {
|
||||||
$parameter->description = $annotation->description;
|
$parameter->description = $annotation->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +129,7 @@ final class FosRestDescriber implements RouteDescriberInterface
|
|||||||
|
|
||||||
private function getContentSchemaForType(OA\RequestBody $requestBody, string $type): OA\Schema
|
private function getContentSchemaForType(OA\RequestBody $requestBody, string $type): OA\Schema
|
||||||
{
|
{
|
||||||
$requestBody->content = OA\UNDEFINED !== $requestBody->content ? $requestBody->content : [];
|
$requestBody->content = Generator::UNDEFINED !== $requestBody->content ? $requestBody->content : [];
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'json':
|
case 'json':
|
||||||
$contentType = 'application/json';
|
$contentType = 'application/json';
|
||||||
@ -165,7 +166,7 @@ final class FosRestDescriber implements RouteDescriberInterface
|
|||||||
{
|
{
|
||||||
$schema->default = $annotation->getDefault();
|
$schema->default = $annotation->getDefault();
|
||||||
|
|
||||||
if (OA\UNDEFINED === $schema->type) {
|
if (Generator::UNDEFINED === $schema->type) {
|
||||||
$schema->type = $annotation->map ? 'array' : 'string';
|
$schema->type = $annotation->map ? 'array' : 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\RouteDescriber;
|
namespace Nelmio\ApiDocBundle\RouteDescriber;
|
||||||
|
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use phpDocumentor\Reflection\DocBlockFactory;
|
use phpDocumentor\Reflection\DocBlockFactory;
|
||||||
use phpDocumentor\Reflection\DocBlockFactoryInterface;
|
use phpDocumentor\Reflection\DocBlockFactoryInterface;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
@ -47,10 +48,10 @@ final class PhpDocDescriber implements RouteDescriberInterface
|
|||||||
|
|
||||||
foreach ($this->getOperations($api, $route) as $operation) {
|
foreach ($this->getOperations($api, $route) as $operation) {
|
||||||
if (null !== $docBlock) {
|
if (null !== $docBlock) {
|
||||||
if (OA\UNDEFINED === $operation->summary && '' !== $docBlock->getSummary()) {
|
if (Generator::UNDEFINED === $operation->summary && '' !== $docBlock->getSummary()) {
|
||||||
$operation->summary = $docBlock->getSummary();
|
$operation->summary = $docBlock->getSummary();
|
||||||
}
|
}
|
||||||
if (OA\UNDEFINED === $operation->description && '' !== (string) $docBlock->getDescription()) {
|
if (Generator::UNDEFINED === $operation->description && '' !== (string) $docBlock->getDescription()) {
|
||||||
$operation->description = (string) $docBlock->getDescription();
|
$operation->description = (string) $docBlock->getDescription();
|
||||||
}
|
}
|
||||||
if ($docBlock->hasTag('deprecated')) {
|
if ($docBlock->hasTag('deprecated')) {
|
||||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\RouteDescriber;
|
|||||||
use LogicException;
|
use LogicException;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +41,7 @@ final class RouteMetadataDescriber implements RouteDescriberInterface
|
|||||||
/** @var OA\Parameter $parameter */
|
/** @var OA\Parameter $parameter */
|
||||||
$parameter = $existingParams[$paramId] ?? null;
|
$parameter = $existingParams[$paramId] ?? null;
|
||||||
if (null !== $parameter) {
|
if (null !== $parameter) {
|
||||||
if (!$parameter->required || OA\UNDEFINED === $parameter->required) {
|
if (!$parameter->required || Generator::UNDEFINED === $parameter->required) {
|
||||||
throw new LogicException(\sprintf('Global parameter "%s" is used as part of route "%s" and must be set as "required"', $pathVariable, $route->getPath()));
|
throw new LogicException(\sprintf('Global parameter "%s" is used as part of route "%s" and must be set as "required"', $pathVariable, $route->getPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +53,11 @@ final class RouteMetadataDescriber implements RouteDescriberInterface
|
|||||||
|
|
||||||
$parameter->schema = Util::getChild($parameter, OA\Schema::class);
|
$parameter->schema = Util::getChild($parameter, OA\Schema::class);
|
||||||
|
|
||||||
if (OA\UNDEFINED === $parameter->schema->type) {
|
if (Generator::UNDEFINED === $parameter->schema->type) {
|
||||||
$parameter->schema->type = 'string';
|
$parameter->schema->type = 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($requirements[$pathVariable]) && OA\UNDEFINED === $parameter->schema->pattern) {
|
if (isset($requirements[$pathVariable]) && Generator::UNDEFINED === $parameter->schema->pattern) {
|
||||||
$parameter->schema->pattern = $requirements[$pathVariable];
|
$parameter->schema->pattern = $requirements[$pathVariable];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,15 +72,15 @@ final class RouteMetadataDescriber implements RouteDescriberInterface
|
|||||||
private function getRefParams(OA\OpenApi $api, OA\Operation $operation): array
|
private function getRefParams(OA\OpenApi $api, OA\Operation $operation): array
|
||||||
{
|
{
|
||||||
/** @var OA\Parameter[] $globalParams */
|
/** @var OA\Parameter[] $globalParams */
|
||||||
$globalParams = OA\UNDEFINED !== $api->components && OA\UNDEFINED !== $api->components->parameters ? $api->components->parameters : [];
|
$globalParams = Generator::UNDEFINED !== $api->components && Generator::UNDEFINED !== $api->components->parameters ? $api->components->parameters : [];
|
||||||
$globalParams = array_column($globalParams, null, 'parameter'); // update the indexes of the array with the reference names actually used
|
$globalParams = array_column($globalParams, null, 'parameter'); // update the indexes of the array with the reference names actually used
|
||||||
$existingParams = [];
|
$existingParams = [];
|
||||||
|
|
||||||
$operationParameters = OA\UNDEFINED !== $operation->parameters ? $operation->parameters : [];
|
$operationParameters = Generator::UNDEFINED !== $operation->parameters ? $operation->parameters : [];
|
||||||
/** @var OA\Parameter $parameter */
|
/** @var OA\Parameter $parameter */
|
||||||
foreach ($operationParameters as $id => $parameter) {
|
foreach ($operationParameters as $id => $parameter) {
|
||||||
$ref = $parameter->ref;
|
$ref = $parameter->ref;
|
||||||
if (OA\UNDEFINED === $ref) {
|
if (Generator::UNDEFINED === $ref) {
|
||||||
// we only concern ourselves with '$ref' parameters, so continue the loop
|
// we only concern ourselves with '$ref' parameters, so continue the loop
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\Tests\Functional;
|
namespace Nelmio\ApiDocBundle\Tests\Functional;
|
||||||
|
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
|
|
||||||
class FOSRestTest extends WebTestCase
|
class FOSRestTest extends WebTestCase
|
||||||
{
|
{
|
||||||
@ -37,17 +38,17 @@ class FOSRestTest extends WebTestCase
|
|||||||
$fooParameter = $this->getParameter($operation, 'foo', 'query');
|
$fooParameter = $this->getParameter($operation, 'foo', 'query');
|
||||||
$this->assertInstanceOf(OA\Schema::class, $fooParameter->schema);
|
$this->assertInstanceOf(OA\Schema::class, $fooParameter->schema);
|
||||||
$this->assertEquals('\d+', $fooParameter->schema->pattern);
|
$this->assertEquals('\d+', $fooParameter->schema->pattern);
|
||||||
$this->assertEquals(OA\UNDEFINED, $fooParameter->schema->format);
|
$this->assertEquals(Generator::UNDEFINED, $fooParameter->schema->format);
|
||||||
|
|
||||||
$mappedParameter = $this->getParameter($operation, 'mapped[]', 'query');
|
$mappedParameter = $this->getParameter($operation, 'mapped[]', 'query');
|
||||||
$this->assertTrue($mappedParameter->explode);
|
$this->assertTrue($mappedParameter->explode);
|
||||||
|
|
||||||
$barProperty = $this->getProperty($bodySchema, 'bar');
|
$barProperty = $this->getProperty($bodySchema, 'bar');
|
||||||
$this->assertEquals('\d+', $barProperty->pattern);
|
$this->assertEquals('\d+', $barProperty->pattern);
|
||||||
$this->assertEquals(OA\UNDEFINED, $barProperty->format);
|
$this->assertEquals(Generator::UNDEFINED, $barProperty->format);
|
||||||
|
|
||||||
$bazProperty = $this->getProperty($bodySchema, 'baz');
|
$bazProperty = $this->getProperty($bodySchema, 'baz');
|
||||||
$this->assertEquals(OA\UNDEFINED, $bazProperty->pattern);
|
$this->assertEquals(Generator::UNDEFINED, $bazProperty->pattern);
|
||||||
$this->assertEquals('IsTrue', $bazProperty->format);
|
$this->assertEquals('IsTrue', $bazProperty->format);
|
||||||
|
|
||||||
$dateTimeProperty = $this->getProperty($bodySchema, 'datetime');
|
$dateTimeProperty = $this->getProperty($bodySchema, 'datetime');
|
||||||
@ -57,7 +58,7 @@ class FOSRestTest extends WebTestCase
|
|||||||
$this->assertEquals('date-time', $dateTimeAltProperty->format);
|
$this->assertEquals('date-time', $dateTimeAltProperty->format);
|
||||||
|
|
||||||
$dateTimeNoFormatProperty = $this->getProperty($bodySchema, 'datetimeNoFormat');
|
$dateTimeNoFormatProperty = $this->getProperty($bodySchema, 'datetimeNoFormat');
|
||||||
$this->assertEquals(OA\UNDEFINED, $dateTimeNoFormatProperty->format);
|
$this->assertEquals(Generator::UNDEFINED, $dateTimeNoFormatProperty->format);
|
||||||
|
|
||||||
$dateProperty = $this->getProperty($bodySchema, 'date');
|
$dateProperty = $this->getProperty($bodySchema, 'date');
|
||||||
$this->assertEquals('date', $dateProperty->format);
|
$this->assertEquals('date', $dateProperty->format);
|
||||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\Tests\Functional;
|
|||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use Nelmio\ApiDocBundle\Tests\Helper;
|
use Nelmio\ApiDocBundle\Tests\Helper;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Component\Serializer\Annotation\SerializedName;
|
use Symfony\Component\Serializer\Annotation\SerializedName;
|
||||||
|
|
||||||
class FunctionalTest extends WebTestCase
|
class FunctionalTest extends WebTestCase
|
||||||
@ -84,7 +85,7 @@ class FunctionalTest extends WebTestCase
|
|||||||
public function testAnnotationWithManualPath()
|
public function testAnnotationWithManualPath()
|
||||||
{
|
{
|
||||||
$path = $this->getPath('/api/swagger2');
|
$path = $this->getPath('/api/swagger2');
|
||||||
$this->assertSame(OA\UNDEFINED, $path->post);
|
$this->assertSame(Generator::UNDEFINED, $path->post);
|
||||||
|
|
||||||
$operation = $this->getOperation('/api/swagger', 'get');
|
$operation = $this->getOperation('/api/swagger', 'get');
|
||||||
$this->assertNotHasParameter('Accept-Version', 'header', $operation);
|
$this->assertNotHasParameter('Accept-Version', 'header', $operation);
|
||||||
@ -123,10 +124,10 @@ class FunctionalTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
$operation = $this->getOperation('/api/test/{user}', 'get');
|
$operation = $this->getOperation('/api/test/{user}', 'get');
|
||||||
|
|
||||||
$this->assertEquals(OA\UNDEFINED, $operation->security);
|
$this->assertEquals(Generator::UNDEFINED, $operation->security);
|
||||||
$this->assertEquals(OA\UNDEFINED, $operation->summary);
|
$this->assertEquals(Generator::UNDEFINED, $operation->summary);
|
||||||
$this->assertEquals(OA\UNDEFINED, $operation->description);
|
$this->assertEquals(Generator::UNDEFINED, $operation->description);
|
||||||
$this->assertEquals(OA\UNDEFINED, $operation->deprecated);
|
$this->assertEquals(Generator::UNDEFINED, $operation->deprecated);
|
||||||
$this->assertHasResponse(200, $operation);
|
$this->assertHasResponse(200, $operation);
|
||||||
|
|
||||||
$this->assertHasParameter('user', 'path', $operation);
|
$this->assertHasParameter('user', 'path', $operation);
|
||||||
@ -134,7 +135,7 @@ class FunctionalTest extends WebTestCase
|
|||||||
$this->assertTrue($parameter->required);
|
$this->assertTrue($parameter->required);
|
||||||
$this->assertEquals('string', $parameter->schema->type);
|
$this->assertEquals('string', $parameter->schema->type);
|
||||||
$this->assertEquals('/foo/', $parameter->schema->pattern);
|
$this->assertEquals('/foo/', $parameter->schema->pattern);
|
||||||
$this->assertEquals(OA\UNDEFINED, $parameter->schema->format);
|
$this->assertEquals(Generator::UNDEFINED, $parameter->schema->format);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDeprecatedAction()
|
public function testDeprecatedAction()
|
||||||
@ -551,7 +552,7 @@ class FunctionalTest extends WebTestCase
|
|||||||
$this->assertCount(2, $model->discriminator->mapping);
|
$this->assertCount(2, $model->discriminator->mapping);
|
||||||
$this->assertArrayHasKey('one', $model->discriminator->mapping);
|
$this->assertArrayHasKey('one', $model->discriminator->mapping);
|
||||||
$this->assertArrayHasKey('two', $model->discriminator->mapping);
|
$this->assertArrayHasKey('two', $model->discriminator->mapping);
|
||||||
$this->assertNotSame(OA\UNDEFINED, $model->oneOf);
|
$this->assertNotSame(Generator::UNDEFINED, $model->oneOf);
|
||||||
$this->assertCount(2, $model->oneOf);
|
$this->assertCount(2, $model->oneOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\Tests\Functional;
|
namespace Nelmio\ApiDocBundle\Tests\Functional;
|
||||||
|
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
|
|
||||||
public function assertHasPath($path, OA\OpenApi $api)
|
public function assertHasPath($path, OA\OpenApi $api)
|
||||||
{
|
{
|
||||||
$paths = array_column(OA\UNDEFINED !== $api->paths ? $api->paths : [], 'path');
|
$paths = array_column(Generator::UNDEFINED !== $api->paths ? $api->paths : [], 'path');
|
||||||
static::assertContains(
|
static::assertContains(
|
||||||
$path,
|
$path,
|
||||||
$paths,
|
$paths,
|
||||||
@ -104,7 +105,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
|
|
||||||
public function assertNotHasPath($path, OA\OpenApi $api)
|
public function assertNotHasPath($path, OA\OpenApi $api)
|
||||||
{
|
{
|
||||||
$paths = array_column(OA\UNDEFINED !== $api->paths ? $api->paths : [], 'path');
|
$paths = array_column(Generator::UNDEFINED !== $api->paths ? $api->paths : [], 'path');
|
||||||
static::assertNotContains(
|
static::assertNotContains(
|
||||||
$path,
|
$path,
|
||||||
$paths,
|
$paths,
|
||||||
@ -114,7 +115,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
|
|
||||||
public function assertHasResponse($responseCode, OA\Operation $operation)
|
public function assertHasResponse($responseCode, OA\Operation $operation)
|
||||||
{
|
{
|
||||||
$responses = array_column(OA\UNDEFINED !== $operation->responses ? $operation->responses : [], 'response');
|
$responses = array_column(Generator::UNDEFINED !== $operation->responses ? $operation->responses : [], 'response');
|
||||||
static::assertContains(
|
static::assertContains(
|
||||||
$responseCode,
|
$responseCode,
|
||||||
$responses,
|
$responses,
|
||||||
@ -125,7 +126,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
public function assertHasParameter($name, $in, OA\AbstractAnnotation $annotation)
|
public function assertHasParameter($name, $in, OA\AbstractAnnotation $annotation)
|
||||||
{
|
{
|
||||||
/* @var OA\Operation|OA\OpenApi $annotation */
|
/* @var OA\Operation|OA\OpenApi $annotation */
|
||||||
$parameters = array_filter(OA\UNDEFINED !== $annotation->parameters ? $annotation->parameters : [], function (OA\Parameter $parameter) use ($name, $in) {
|
$parameters = array_filter(Generator::UNDEFINED !== $annotation->parameters ? $annotation->parameters : [], function (OA\Parameter $parameter) use ($name, $in) {
|
||||||
return $parameter->name === $name && $parameter->in === $in;
|
return $parameter->name === $name && $parameter->in === $in;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
public function assertNotHasParameter($name, $in, OA\AbstractAnnotation $annotation)
|
public function assertNotHasParameter($name, $in, OA\AbstractAnnotation $annotation)
|
||||||
{
|
{
|
||||||
/* @var OA\Operation|OA\OpenApi $annotation */
|
/* @var OA\Operation|OA\OpenApi $annotation */
|
||||||
$parameters = array_column(OA\UNDEFINED !== $annotation->parameters ? $annotation->parameters : [], 'name', 'in');
|
$parameters = array_column(Generator::UNDEFINED !== $annotation->parameters ? $annotation->parameters : [], 'name', 'in');
|
||||||
static::assertNotContains(
|
static::assertNotContains(
|
||||||
$name,
|
$name,
|
||||||
$parameters[$in] ?? [],
|
$parameters[$in] ?? [],
|
||||||
@ -149,7 +150,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
public function assertHasProperty($property, OA\AbstractAnnotation $annotation)
|
public function assertHasProperty($property, OA\AbstractAnnotation $annotation)
|
||||||
{
|
{
|
||||||
/* @var OA\Schema|OA\Property|OA\Items $annotation */
|
/* @var OA\Schema|OA\Property|OA\Items $annotation */
|
||||||
$properties = array_column(OA\UNDEFINED !== $annotation->properties ? $annotation->properties : [], 'property');
|
$properties = array_column(Generator::UNDEFINED !== $annotation->properties ? $annotation->properties : [], 'property');
|
||||||
static::assertContains(
|
static::assertContains(
|
||||||
$property,
|
$property,
|
||||||
$properties,
|
$properties,
|
||||||
@ -160,7 +161,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
public function assertNotHasProperty($property, OA\AbstractAnnotation $annotation)
|
public function assertNotHasProperty($property, OA\AbstractAnnotation $annotation)
|
||||||
{
|
{
|
||||||
/* @var OA\Schema|OA\Property|OA\Items $annotation */
|
/* @var OA\Schema|OA\Property|OA\Items $annotation */
|
||||||
$properties = array_column(OA\UNDEFINED !== $annotation->properties ? $annotation->properties : [], 'property');
|
$properties = array_column(Generator::UNDEFINED !== $annotation->properties ? $annotation->properties : [], 'property');
|
||||||
static::assertNotContains(
|
static::assertNotContains(
|
||||||
$property,
|
$property,
|
||||||
$properties,
|
$properties,
|
||||||
|
@ -16,6 +16,7 @@ use Nelmio\ApiDocBundle\ModelDescriber\Annotations\SymfonyConstraintAnnotationRe
|
|||||||
use Nelmio\ApiDocBundle\Tests\Helper;
|
use Nelmio\ApiDocBundle\Tests\Helper;
|
||||||
use Nelmio\ApiDocBundle\Tests\ModelDescriber\Annotations\Fixture as CustomAssert;
|
use Nelmio\ApiDocBundle\Tests\ModelDescriber\Annotations\Fixture as CustomAssert;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
@ -190,7 +191,7 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
|
|
||||||
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
||||||
|
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->maxLength);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->maxLength);
|
||||||
$this->assertSame(1, $schema->properties[0]->minLength);
|
$this->assertSame(1, $schema->properties[0]->minLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +227,7 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
|
|
||||||
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
||||||
|
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->minLength);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->minLength);
|
||||||
$this->assertSame(100, $schema->properties[0]->maxLength);
|
$this->assertSame(100, $schema->properties[0]->maxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,11 +273,11 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
$this->assertSame(5, $schema->properties[0]->maximum);
|
$this->assertSame(5, $schema->properties[0]->maximum);
|
||||||
$this->assertTrue($schema->properties[0]->exclusiveMaximum);
|
$this->assertTrue($schema->properties[0]->exclusiveMaximum);
|
||||||
} else {
|
} else {
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->required);
|
$this->assertSame(Generator::UNDEFINED, $schema->required);
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->minimum);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->minimum);
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->exclusiveMinimum);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->exclusiveMinimum);
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->maximum);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->maximum);
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->exclusiveMaximum);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->exclusiveMaximum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +296,7 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
|
|
||||||
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
||||||
|
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->minItems);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->minItems);
|
||||||
$this->assertSame(10, $schema->properties[0]->maxItems);
|
$this->assertSame(10, $schema->properties[0]->maxItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +332,7 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
|
|
||||||
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
||||||
|
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->maxItems);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->maxItems);
|
||||||
$this->assertSame(10, $schema->properties[0]->minItems);
|
$this->assertSame(10, $schema->properties[0]->minItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +368,7 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
|
|
||||||
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
||||||
|
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->maximum);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->maximum);
|
||||||
$this->assertSame(10, $schema->properties[0]->minimum);
|
$this->assertSame(10, $schema->properties[0]->minimum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +404,7 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
|||||||
|
|
||||||
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
$symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]);
|
||||||
|
|
||||||
$this->assertSame(OA\UNDEFINED, $schema->properties[0]->minimum);
|
$this->assertSame(Generator::UNDEFINED, $schema->properties[0]->minimum);
|
||||||
$this->assertSame(10, $schema->properties[0]->maximum);
|
$this->assertSame(10, $schema->properties[0]->maximum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use Nelmio\ApiDocBundle\Model\Model;
|
|||||||
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
||||||
use Nelmio\ApiDocBundle\ModelDescriber\ApplyOpenApiDiscriminatorTrait;
|
use Nelmio\ApiDocBundle\ModelDescriber\ApplyOpenApiDiscriminatorTrait;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
use OpenApi\Generator;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ class ApplyOpenApiDiscriminatorTraitTest extends TestCase
|
|||||||
'two' => 'SecondType',
|
'two' => 'SecondType',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertNotSame(OA\UNDEFINED, $this->schema->oneOf);
|
$this->assertNotSame(Generator::UNDEFINED, $this->schema->oneOf);
|
||||||
$this->assertCount(2, $this->schema->oneOf);
|
$this->assertCount(2, $this->schema->oneOf);
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
$this->modelRegistry->register($this->createModel('FirstType')),
|
$this->modelRegistry->register($this->createModel('FirstType')),
|
||||||
|
@ -14,7 +14,7 @@ namespace Nelmio\ApiDocBundle\Tests\SwaggerPhp;
|
|||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use OpenApi\Context;
|
use OpenApi\Context;
|
||||||
use const OpenApi\UNDEFINED;
|
use OpenApi\Generator;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,7 +107,7 @@ class UtilTest extends TestCase
|
|||||||
return 0 !== strpos($key, '_');
|
return 0 !== strpos($key, '_');
|
||||||
}, ARRAY_FILTER_USE_KEY);
|
}, ARRAY_FILTER_USE_KEY);
|
||||||
|
|
||||||
$this->assertEquals([UNDEFINED], array_unique(array_values($properties)));
|
$this->assertEquals([Generator::UNDEFINED], array_unique(array_values($properties)));
|
||||||
|
|
||||||
$this->assertIsNested($this->rootAnnotation, $info);
|
$this->assertIsNested($this->rootAnnotation, $info);
|
||||||
$this->assertIsConnectedToRootContext($info);
|
$this->assertIsConnectedToRootContext($info);
|
||||||
@ -220,7 +220,7 @@ class UtilTest extends TestCase
|
|||||||
foreach ($items as $assert) {
|
foreach ($items as $assert) {
|
||||||
$setupCollection = empty($assert['components']) ?
|
$setupCollection = empty($assert['components']) ?
|
||||||
($setup[$collection] ?? []) :
|
($setup[$collection] ?? []) :
|
||||||
(OA\UNDEFINED !== $setup['components']->{$collection} ? $setup['components']->{$collection} : []);
|
(Generator::UNDEFINED !== $setup['components']->{$collection} ? $setup['components']->{$collection} : []);
|
||||||
|
|
||||||
// get the indexing correct within haystack preparation
|
// get the indexing correct within haystack preparation
|
||||||
$properties = array_fill(0, \count($setupCollection), null);
|
$properties = array_fill(0, \count($setupCollection), null);
|
||||||
|
22
Util/SetsContextTrait.php
Normal file
22
Util/SetsContextTrait.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Util;
|
||||||
|
|
||||||
|
use OpenApi\Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
trait SetsContextTrait
|
||||||
|
{
|
||||||
|
private function setContext(?Context $context): void
|
||||||
|
{
|
||||||
|
if (class_exists(\OpenApi\Analyser::class)) {
|
||||||
|
// zircote/swagger-php ^3.2
|
||||||
|
\OpenApi\Analyser::$context = $context;
|
||||||
|
} else {
|
||||||
|
/// zircote/swagger-php ^4.0
|
||||||
|
\OpenApi\Generator::$context = $context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1.3",
|
"php": ">=7.2",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"doctrine/annotations": "^1.11",
|
"doctrine/annotations": "^1.11",
|
||||||
"psr/cache": "^1.0|^2.0|^3.0",
|
"psr/cache": "^1.0|^2.0|^3.0",
|
||||||
@ -30,7 +30,7 @@
|
|||||||
"symfony/options-resolver": "^4.4|^5.0",
|
"symfony/options-resolver": "^4.4|^5.0",
|
||||||
"symfony/property-info": "^4.4|^5.0",
|
"symfony/property-info": "^4.4|^5.0",
|
||||||
"symfony/routing": "^4.4|^5.0",
|
"symfony/routing": "^4.4|^5.0",
|
||||||
"zircote/swagger-php": "^3.0",
|
"zircote/swagger-php": "^3.2|^4.0",
|
||||||
"phpdocumentor/reflection-docblock": "^3.1|^4.4|^5.0"
|
"phpdocumentor/reflection-docblock": "^3.1|^4.4|^5.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user