mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-03-11 18:16:13 +03:00
* Fix #1628 : since annotations construction is context dependant, we cannot use the cached annotations reader * CS * Small improvement * cs
This commit is contained in:
parent
3f90ef6ce9
commit
fb84e36fdf
@ -87,7 +87,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
|
||||
->setArguments([
|
||||
new Reference(sprintf('nelmio_api_doc.routes.%s', $area)),
|
||||
new Reference('nelmio_api_doc.controller_reflector'),
|
||||
new Reference('annotation_reader'),
|
||||
new Reference('annotations.reader'), // We cannot use the cached version of the annotation reader since the construction of the annotations is context dependant...
|
||||
new Reference('logger'),
|
||||
$config['media_types'],
|
||||
])
|
||||
@ -116,7 +116,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
|
||||
(new Definition(FilteredRouteCollectionBuilder::class))
|
||||
->setArguments(
|
||||
[
|
||||
new Reference('annotation_reader'),
|
||||
new Reference('annotation_reader'), // Here we use the cached version as we don't deal with @OA annotations in this service
|
||||
new Reference('nelmio_api_doc.controller_reflector'),
|
||||
$area,
|
||||
$areaConfig,
|
||||
@ -165,7 +165,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
|
||||
->setPublic(false)
|
||||
->setArguments([
|
||||
new Reference('jms_serializer.metadata_factory'),
|
||||
new Reference('annotation_reader'),
|
||||
new Reference('annotations.reader'),
|
||||
$config['media_types'],
|
||||
$jmsNamingStrategy,
|
||||
])
|
||||
|
@ -18,6 +18,7 @@ use Nelmio\ApiDocBundle\OpenApiPhp\AddDefaults;
|
||||
use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister;
|
||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||
use Nelmio\ApiDocBundle\Util\ControllerReflector;
|
||||
use OpenApi\Analyser;
|
||||
use OpenApi\Analysis;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@ -75,6 +76,15 @@ final class OpenApiPhpDescriber implements ModelRegistryAwareInterface
|
||||
/** @var \ReflectionMethod $method */
|
||||
foreach ($this->getMethodsToParse() as $method => list($path, $httpMethods)) {
|
||||
$declaringClass = $method->getDeclaringClass();
|
||||
|
||||
$path = Util::getPath($api, $path);
|
||||
|
||||
Analyser::$context = Util::createContext(['nested' => $path], $path->_context);
|
||||
Analyser::$context->namespace = $method->getNamespaceName();
|
||||
Analyser::$context->class = $declaringClass->getShortName();
|
||||
Analyser::$context->method = $method->name;
|
||||
Analyser::$context->filename = $method->getFileName();
|
||||
|
||||
if (!array_key_exists($declaringClass->getName(), $classAnnotations)) {
|
||||
$classAnnotations = array_filter($this->annotationReader->getClassAnnotations($declaringClass), function ($v) {
|
||||
return $v instanceof OA\AbstractAnnotation;
|
||||
@ -90,19 +100,10 @@ final class OpenApiPhpDescriber implements ModelRegistryAwareInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = Util::getPath($api, $path);
|
||||
$path->_context->namespace = $method->getNamespaceName();
|
||||
$path->_context->class = $declaringClass->getShortName();
|
||||
$path->_context->method = $method->name;
|
||||
$path->_context->filename = $method->getFileName();
|
||||
|
||||
$nestedContext = Util::createContext(['nested' => $path], $path->_context);
|
||||
$implicitAnnotations = [];
|
||||
$mergeProperties = new \stdClass();
|
||||
|
||||
foreach (array_merge($annotations, $classAnnotations[$declaringClass->getName()]) as $annotation) {
|
||||
$annotation->_context = $nestedContext;
|
||||
|
||||
if ($annotation instanceof Operation) {
|
||||
foreach ($httpMethods as $httpMethod) {
|
||||
$operation = Util::getOperation($path, $httpMethod);
|
||||
@ -142,13 +143,6 @@ final class OpenApiPhpDescriber implements ModelRegistryAwareInterface
|
||||
throw new \LogicException(sprintf('Using the annotation "%s" as a root annotation in "%s::%s()" is not allowed.', get_class($annotation), $method->getDeclaringClass()->name, $method->name));
|
||||
}
|
||||
|
||||
foreach ($annotation->_unmerged as $unmergedAnnotation) {
|
||||
if (!$unmergedAnnotation instanceof OA\JsonContent && !$unmergedAnnotation instanceof OA\XmlContent) {
|
||||
continue;
|
||||
}
|
||||
$unmergedAnnotation->_context->nested = $annotation;
|
||||
}
|
||||
|
||||
$implicitAnnotations[] = $annotation;
|
||||
}
|
||||
|
||||
@ -166,6 +160,9 @@ final class OpenApiPhpDescriber implements ModelRegistryAwareInterface
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the Analyser after the parsing
|
||||
Analyser::$context = null;
|
||||
|
||||
return $analysis;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Nelmio\ApiDocBundle\Model\ModelRegistry;
|
||||
use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister;
|
||||
use OpenApi\Analyser;
|
||||
use OpenApi\Analysis;
|
||||
use OpenApi\Annotations as OA;
|
||||
use OpenApi\Context;
|
||||
@ -61,19 +62,20 @@ class OpenApiAnnotationsReader
|
||||
|
||||
public function updateProperty(\ReflectionProperty $reflectionProperty, OA\Property $property, array $serializationGroups = null): void
|
||||
{
|
||||
/** @var OA\Property $oaProperty */
|
||||
if (!$oaProperty = $this->annotationsReader->getPropertyAnnotation($reflectionProperty, OA\Property::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// In order to have nicer errors
|
||||
$declaringClass = $reflectionProperty->getDeclaringClass();
|
||||
$context = new Context([
|
||||
Analyser::$context = new Context([
|
||||
'namespace' => $declaringClass->getNamespaceName(),
|
||||
'class' => $declaringClass->getShortName(),
|
||||
'property' => $reflectionProperty->name,
|
||||
'filename' => $declaringClass->getFileName(),
|
||||
]);
|
||||
$oaProperty->_context = $context;
|
||||
|
||||
/** @var OA\Property $oaProperty */
|
||||
if (!$oaProperty = $this->annotationsReader->getPropertyAnnotation($reflectionProperty, OA\Property::class)) {
|
||||
return;
|
||||
}
|
||||
Analyser::$context = null;
|
||||
|
||||
// Read @Model annotations
|
||||
$this->modelRegister->__invoke(new Analysis([$oaProperty]), $serializationGroups);
|
||||
|
@ -36,6 +36,8 @@ class ApiController
|
||||
* )
|
||||
* @OA\Parameter(ref="#/components/parameters/test")
|
||||
* @Route("/article/{id}", methods={"GET"})
|
||||
* @OA\Parameter(name="Accept-Version", in="header", @OA\Schema(type="string"))
|
||||
* @OA\Parameter(name="Application-Name", in="header", @OA\Schema(type="string"))
|
||||
*/
|
||||
public function fetchArticleAction()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user