Skip to content

Commit

Permalink
make Doctrine annotations optional
Browse files Browse the repository at this point in the history
Fixes #2143
  • Loading branch information
RobertMe committed Nov 23, 2023
1 parent b7a5722 commit bf39ddd
Show file tree
Hide file tree
Showing 14 changed files with 47 additions and 38 deletions.
3 changes: 2 additions & 1 deletion DependencyInjection/Compiler/ConfigurationPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Nelmio\ApiDocBundle\ModelDescriber\FormModelDescriber;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;

/**
Expand All @@ -29,7 +30,7 @@ public function process(ContainerBuilder $container): void
$container->register('nelmio_api_doc.model_describers.form', FormModelDescriber::class)
->setPublic(false)
->addArgument(new Reference('form.factory'))
->addArgument(new Reference('annotations.reader'))
->addArgument(new Reference('annotations.reader', ContainerInterface::NULL_ON_INVALID_REFERENCE))
->addArgument($container->getParameter('nelmio_api_doc.media_types'))
->addArgument($container->getParameter('nelmio_api_doc.use_validation_groups'))
->addTag('nelmio_api_doc.model_describer', ['priority' => 100]);
Expand Down
7 changes: 4 additions & 3 deletions DependencyInjection/NelmioApiDocExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
Expand Down Expand Up @@ -94,7 +95,7 @@ public function load(array $configs, ContainerBuilder $container): void
->setArguments([
new Reference(sprintf('nelmio_api_doc.routes.%s', $area)),
new Reference('nelmio_api_doc.controller_reflector'),
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('annotations.reader', ContainerInterface::NULL_ON_INVALID_REFERENCE), // We cannot use the cached version of the annotation reader since the construction of the annotations is context dependant...
new Reference('logger'),
])
->addTag(sprintf('nelmio_api_doc.describer.%s', $area), ['priority' => -200]);
Expand Down Expand Up @@ -123,7 +124,7 @@ public function load(array $configs, ContainerBuilder $container): void
(new Definition(FilteredRouteCollectionBuilder::class))
->setArguments(
[
new Reference('annotation_reader'), // Here we use the cached version as we don't deal with @OA annotations in this service
new Reference('annotation_reader', ContainerInterface::NULL_ON_INVALID_REFERENCE), // 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,
Expand Down Expand Up @@ -181,7 +182,7 @@ public function load(array $configs, ContainerBuilder $container): void
->setPublic(false)
->setArguments([
new Reference('jms_serializer.metadata_factory'),
new Reference('annotations.reader'),
new Reference('annotations.reader', ContainerInterface::NULL_ON_INVALID_REFERENCE),
$config['media_types'],
$jmsNamingStrategy,
$container->getParameter('nelmio_api_doc.use_validation_groups'),
Expand Down
18 changes: 11 additions & 7 deletions Describer/OpenApiPhpDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class OpenApiPhpDescriber
private $logger;
private $overwrite;

public function __construct(RouteCollection $routeCollection, ControllerReflector $controllerReflector, Reader $annotationReader, LoggerInterface $logger, bool $overwrite = false)
public function __construct(RouteCollection $routeCollection, ControllerReflector $controllerReflector, ?Reader $annotationReader, LoggerInterface $logger, bool $overwrite = false)
{
$this->routeCollection = $routeCollection;
$this->controllerReflector = $controllerReflector;
Expand Down Expand Up @@ -65,16 +65,20 @@ public function describe(OA\OpenApi $api)
$this->setContext($context);

if (!array_key_exists($declaringClass->getName(), $classAnnotations)) {
$classAnnotations = array_filter($this->annotationReader->getClassAnnotations($declaringClass), function ($v) {
return $v instanceof OA\AbstractAnnotation;
});
$classAnnotations = null !== $this->annotationReader ?
array_filter($this->annotationReader->getClassAnnotations($declaringClass), function ($v) {
return $v instanceof OA\AbstractAnnotation;
}) :
[];
$classAnnotations = array_merge($classAnnotations, $this->getAttributesAsAnnotation($declaringClass, $context));
$classAnnotations[$declaringClass->getName()] = $classAnnotations;
}

$annotations = array_filter($this->annotationReader->getMethodAnnotations($method), function ($v) {
return $v instanceof OA\AbstractAnnotation;
});
$annotations = null !== $this->annotationReader ?
array_filter($this->annotationReader->getMethodAnnotations($method), function ($v) {
return $v instanceof OA\AbstractAnnotation;
}) :
[];
$annotations = array_merge($annotations, $this->getAttributesAsAnnotation($method, $context));

if (0 === count($annotations) && 0 === count($classAnnotations[$declaringClass->getName()])) {
Expand Down
8 changes: 1 addition & 7 deletions ModelDescriber/Annotations/AnnotationsReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,16 @@
*/
class AnnotationsReader
{
private $annotationsReader;
private $modelRegistry;

private $phpDocReader;
private $openApiAnnotationsReader;
private $symfonyConstraintAnnotationReader;

public function __construct(
Reader $annotationsReader,
?Reader $annotationsReader,
ModelRegistry $modelRegistry,
array $mediaTypes,
bool $useValidationGroups = false
) {
$this->annotationsReader = $annotationsReader;
$this->modelRegistry = $modelRegistry;

$this->phpDocReader = new PropertyPhpDocReader();
$this->openApiAnnotationsReader = new OpenApiAnnotationsReader($annotationsReader, $modelRegistry, $mediaTypes);
$this->symfonyConstraintAnnotationReader = new SymfonyConstraintAnnotationReader(
Expand Down
6 changes: 5 additions & 1 deletion ModelDescriber/Annotations/OpenApiAnnotationsReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class OpenApiAnnotationsReader
private $annotationsReader;
private $modelRegister;

public function __construct(Reader $annotationsReader, ModelRegistry $modelRegistry, array $mediaTypes)
public function __construct(?Reader $annotationsReader, ModelRegistry $modelRegistry, array $mediaTypes)
{
$this->annotationsReader = $annotationsReader;
$this->modelRegister = new ModelRegister($modelRegistry, $mediaTypes);
Expand Down Expand Up @@ -97,6 +97,10 @@ private function getAnnotation(Context $parentContext, $reflection, string $clas
}
}

if (null === $this->annotationsReader) {
return null;
}

if ($reflection instanceof \ReflectionClass) {
return $this->annotationsReader->getClassAnnotation($reflection, $className);
} elseif ($reflection instanceof \ReflectionProperty) {
Expand Down
14 changes: 8 additions & 6 deletions ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SymfonyConstraintAnnotationReader
use SetsContextTrait;

/**
* @var Reader
* @var Reader|null
*/
private $annotationsReader;

Expand All @@ -42,7 +42,7 @@ class SymfonyConstraintAnnotationReader
*/
private $useValidationGroups;

public function __construct(Reader $annotationsReader, bool $useValidationGroups=false)
public function __construct(?Reader $annotationsReader, bool $useValidationGroups=false)
{
$this->annotationsReader = $annotationsReader;
$this->useValidationGroups = $useValidationGroups;
Expand Down Expand Up @@ -215,10 +215,12 @@ private function locateAnnotations($reflection): \Traversable
}
}

if ($reflection instanceof \ReflectionProperty) {
yield from $this->annotationsReader->getPropertyAnnotations($reflection);
} elseif ($reflection instanceof \ReflectionMethod) {
yield from $this->annotationsReader->getMethodAnnotations($reflection);
if (null !== $this->annotationsReader) {
if ($reflection instanceof \ReflectionProperty) {
yield from $this->annotationsReader->getPropertyAnnotations($reflection);
} elseif ($reflection instanceof \ReflectionMethod) {
yield from $this->annotationsReader->getMethodAnnotations($reflection);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion ModelDescriber/FormModelDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry

public function __construct(
FormFactoryInterface $formFactory = null,
Reader $reader = null,
?Reader $reader = null,
array $mediaTypes = null,
bool $useValidationGroups = false
) {
Expand Down
2 changes: 1 addition & 1 deletion ModelDescriber/JMSModelDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn

public function __construct(
MetadataFactoryInterface $factory,
Reader $reader,
?Reader $reader,
array $mediaTypes,
?PropertyNamingStrategyInterface $namingStrategy = null,
bool $useValidationGroups = false,
Expand Down
2 changes: 1 addition & 1 deletion ModelDescriber/ObjectModelDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar

public function __construct(
PropertyInfoExtractorInterface $propertyInfo,
Reader $reader,
?Reader $reader,
iterable $propertyDescribers,
array $mediaTypes,
NameConverterInterface $nameConverter = null,
Expand Down
2 changes: 1 addition & 1 deletion Resources/config/fos_rest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<services>
<service id="nelmio_api_doc.route_describers.fos_rest" class="Nelmio\ApiDocBundle\RouteDescriber\FosRestDescriber" public="false">
<argument type="service" id="annotation_reader" /> <!-- we don't deal with @OA annotations in this describer so we can use the cached reader -->
<argument type="service" id="annotation_reader" on-invalid="null" /> <!-- we don't deal with @OA annotations in this describer so we can use the cached reader -->
<argument />

<tag name="nelmio_api_doc.route_describer" priority="-250" />
Expand Down
2 changes: 1 addition & 1 deletion Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

<service id="nelmio_api_doc.model_describers.object" class="Nelmio\ApiDocBundle\ModelDescriber\ObjectModelDescriber" public="false">
<argument type="service" id="property_info" />
<argument type="service" id="annotations.reader" />
<argument type="service" id="annotations.reader" on-invalid="null" />
<argument type="tagged" tag="nelmio_api_doc.object_model.property_describer" />
<argument />
<argument type="service" id="serializer.name_converter.metadata_aware" on-invalid="ignore" />
Expand Down
8 changes: 5 additions & 3 deletions RouteDescriber/FosRestDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,23 @@ final class FosRestDescriber implements RouteDescriberInterface
{
use RouteDescriberTrait;

/** @var Reader */
/** @var Reader|null */
private $annotationReader;

/** @var string[] */
private $mediaTypes;

public function __construct(Reader $annotationReader, array $mediaTypes)
public function __construct(?Reader $annotationReader, array $mediaTypes)
{
$this->annotationReader = $annotationReader;
$this->mediaTypes = $mediaTypes;
}

public function describe(OA\OpenApi $api, Route $route, \ReflectionMethod $reflectionMethod)
{
$annotations = $this->annotationReader->getMethodAnnotations($reflectionMethod);
$annotations = null !== $this->annotationReader ?
$this->annotationReader->getMethodAnnotations($reflectionMethod) :
[];
$annotations = array_filter($annotations, static function ($value) {
return $value instanceof RequestParam || $value instanceof QueryParam;
});
Expand Down
8 changes: 4 additions & 4 deletions Routing/FilteredRouteCollectionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

final class FilteredRouteCollectionBuilder
{
/** @var Reader */
/** @var Reader|null */
private $annotationReader;

/** @var ControllerReflector */
Expand All @@ -34,7 +34,7 @@ final class FilteredRouteCollectionBuilder
private $options;

public function __construct(
Reader $annotationReader,
?Reader $annotationReader,
ControllerReflector $controllerReflector,
string $area,
array $options = []
Expand Down Expand Up @@ -137,7 +137,7 @@ private function matchAnnotation(Route $route): bool
/** @var Areas|null $areas */
$areas = $this->getAttributesAsAnnotation($reflectionMethod->getDeclaringClass(), Areas::class)[0] ?? null;

if (null === $areas) {
if (null === $areas && null !== $this->annotationReader) {
/** @var Areas|null $areas */
$areas = $this->annotationReader->getMethodAnnotation(
$reflectionMethod,
Expand Down Expand Up @@ -167,7 +167,7 @@ private function defaultRouteDisabled(Route $route): bool
return false;
}

$annotations = $this->annotationReader->getMethodAnnotations($method);
$annotations = null !== $this->annotationReader ? $this->annotationReader->getMethodAnnotations($method) : [];
if (method_exists(\ReflectionMethod::class, 'getAttributes')) {
$annotations = array_merge($annotations, array_map(function (\ReflectionAttribute $attribute) {
return $attribute->newInstance();
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"require": {
"php": ">=7.2",
"ext-json": "*",
"doctrine/annotations": "^2.0",
"psr/cache": "^1.0|^2.0|^3.0",
"psr/container": "^1.0|^2.0",
"psr/log": "^1.0|^2.0|^3.0",
Expand All @@ -34,6 +33,7 @@
"phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0"
},
"require-dev": {
"doctrine/annotations": "^2.0",
"sensio/framework-extra-bundle": "^5.4|^6.0",
"symfony/asset": "^5.4|^6.0",
"symfony/dom-crawler": "^5.4|^6.0",
Expand All @@ -59,6 +59,7 @@
},
"suggest": {
"api-platform/core": "For using an API oriented framework.",
"doctrine/annotations": "For using Doctrine Annotations",
"friendsofsymfony/rest-bundle": "For using the parameters annotations.",
"jms/serializer-bundle": "For describing your models.",
"symfony/asset": "For using the Swagger UI.",
Expand Down

0 comments on commit bf39ddd

Please sign in to comment.