Skip to content

Commit 54656fa

Browse files
feat: Allow ignoring properties from schema
1 parent 8b4803f commit 54656fa

File tree

10 files changed

+162
-0
lines changed

10 files changed

+162
-0
lines changed

src/Attribute/Ignore.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the NelmioApiDocBundle package.
7+
*
8+
* (c) Nelmio
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Nelmio\ApiDocBundle\Attribute;
15+
16+
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER | \Attribute::TARGET_PROPERTY)]
17+
final class Ignore
18+
{
19+
}

src/ModelDescriber/Annotations/AnnotationsReader.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
1313

1414
use Doctrine\Common\Annotations\Reader;
15+
use Nelmio\ApiDocBundle\Attribute\Ignore;
1516
use Nelmio\ApiDocBundle\Model\ModelRegistry;
1617
use OpenApi\Annotations as OA;
1718
use OpenApi\Generator;
@@ -73,6 +74,24 @@ public function updateProperty($reflection, OA\Property $property, ?array $seria
7374
$this->symfonyConstraintAnnotationReader->updateProperty($reflection, $property, $serializationGroups);
7475
}
7576

77+
/**
78+
* @param \ReflectionProperty[]|\ReflectionMethod[] $reflections
79+
*/
80+
public function shouldDescribeProperty(array $reflections): bool
81+
{
82+
if (\PHP_VERSION_ID < 80100) {
83+
return true;
84+
}
85+
86+
foreach ($reflections as $reflection) {
87+
if ([] !== $reflection->getAttributes(Ignore::class)) {
88+
return false;
89+
}
90+
}
91+
92+
return true;
93+
}
94+
7695
/**
7796
* Whether the model describer should continue reading class properties
7897
* after updating the open api schema from an `OA\Schema` definition.

src/ModelDescriber/JMSModelDescriber.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ public function describe(Model $model, OA\Schema $schema)
159159
}
160160
}
161161

162+
if (!$annotationsReader->shouldDescribeProperty($reflections)) {
163+
$context->popPropertyMetadata();
164+
165+
continue;
166+
}
167+
162168
$groups = $this->computeGroups($context, $item->type);
163169

164170
if (true === $item->inline && isset($item->type['name'])) {

src/ModelDescriber/ObjectModelDescriber.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ public function describe(Model $model, OA\Schema $schema)
132132

133133
$reflections = $this->getReflections($reflClass, $propertyName);
134134

135+
if (!$annotationsReader->shouldDescribeProperty($reflections)) {
136+
continue;
137+
}
138+
135139
// Check if a custom name is set
136140
foreach ($reflections as $reflection) {
137141
$serializedName = $annotationsReader->getPropertyName($reflection, $serializedName);

tests/Functional/Controller/ApiController81.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityThroughNameConverter;
2525
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityWithAlternateType81;
2626
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityWithFalsyDefaults;
27+
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityWithIgnoredProperty;
2728
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityWithNullableSchemaSet;
2829
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityWithObjectType;
2930
use Nelmio\ApiDocBundle\Tests\Functional\Entity\EntityWithRef;
@@ -350,6 +351,18 @@ public function entityWithUuid()
350351
{
351352
}
352353

354+
#[Route('/entity-with-ignored-property', methods: ['GET', 'POST'])]
355+
#[OA\Response(
356+
response: 200,
357+
description: 'success',
358+
content: new OA\JsonContent(
359+
ref: new Model(type: EntityWithIgnoredProperty::class),
360+
),
361+
)]
362+
public function entityWithIgnoredProperty()
363+
{
364+
}
365+
353366
#[Route('/form-with-alternate-type', methods: ['POST'])]
354367
#[OA\Response(
355368
response: 204,

tests/Functional/Controller/JMSController81.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSComplex81;
1818
use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSDualComplex;
1919
use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSEnum81;
20+
use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSIgnoredProperty;
2021
use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSNamingStrategyConstraints;
2122
use Nelmio\ApiDocBundle\Tests\Functional\Entity\JMSUser;
2223
use Nelmio\ApiDocBundle\Tests\Functional\Entity\NestedGroup\JMSChat;
@@ -157,4 +158,15 @@ public function discriminatorMapAction()
157158
public function enumArrayAction()
158159
{
159160
}
161+
162+
#[Route('/api/jms_ignored_property', methods: ['GET'])]
163+
#[OA\Response(
164+
response: 200,
165+
description: 'Success',
166+
content: new Model(type: JMSIgnoredProperty::class)
167+
)
168+
]
169+
public function ignoredProperty()
170+
{
171+
}
160172
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the NelmioApiDocBundle package.
7+
*
8+
* (c) Nelmio
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Nelmio\ApiDocBundle\Tests\Functional\Entity;
15+
16+
use Nelmio\ApiDocBundle\Attribute\Ignore;
17+
18+
class EntityWithIgnoredProperty
19+
{
20+
public function __construct(
21+
public string $regularProperty,
22+
#[Ignore]
23+
public string $ignoredProperty,
24+
) {
25+
}
26+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the NelmioApiDocBundle package.
7+
*
8+
* (c) Nelmio
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Nelmio\ApiDocBundle\Tests\Functional\Entity;
15+
16+
use JMS\Serializer\Annotation as Serializer;
17+
use Nelmio\ApiDocBundle\Attribute\Ignore;
18+
19+
/**
20+
* JMSIgnoredProperty.
21+
*/
22+
#[Serializer\ExclusionPolicy('all')]
23+
class JMSIgnoredProperty
24+
{
25+
#[Serializer\Type('string')]
26+
#[Serializer\Expose]
27+
private $regularProperty;
28+
29+
#[Ignore]
30+
#[Serializer\Type('string')]
31+
#[Serializer\Expose]
32+
private $ignoredProperty;
33+
}

tests/Functional/FunctionalTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,20 @@ public function testEntityWithUuid(): void
918918
], json_decode($this->getModel('EntityWithUuid')->toJson(), true));
919919
}
920920

921+
public function testEntityWithIgnoredProperty(): void
922+
{
923+
self::assertEquals([
924+
'schema' => 'EntityWithIgnoredProperty',
925+
'type' => 'object',
926+
'required' => ['regularProperty'],
927+
'properties' => [
928+
'regularProperty' => [
929+
'type' => 'string',
930+
],
931+
],
932+
], json_decode($this->getModel('EntityWithIgnoredProperty')->toJson(), true));
933+
}
934+
921935
public function testEntitiesWithRefInSchemaDoNoReadOtherProperties(): void
922936
{
923937
$model = $this->getModel('EntityWithRef');

tests/Functional/JMSFunctionalTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,22 @@ public function testModeDiscriminatorMap(): void
461461
], json_decode($this->getModel('JMSAbstractUser')->toJson(), true));
462462
}
463463

464+
/**
465+
* @requires PHP >= 8.1
466+
*/
467+
public function testIgnoredProperty(): void
468+
{
469+
self::assertEquals([
470+
'schema' => 'JMSIgnoredProperty',
471+
'type' => 'object',
472+
'properties' => [
473+
'regular_property' => [
474+
'type' => 'string',
475+
],
476+
],
477+
], json_decode($this->getModel('JMSIgnoredProperty')->toJson(), true));
478+
}
479+
464480
/**
465481
* @param array<mixed> $options
466482
*/

0 commit comments

Comments
 (0)