Skip to content

Commit df1b82d

Browse files
committed
Improving swagger OAPI generator to mark deprecated endpoint and generating new swagger specification.
1 parent 8ddfc68 commit df1b82d

File tree

5 files changed

+450
-66
lines changed

5 files changed

+450
-66
lines changed
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,20 @@
1616
description: 'Generate an OpenAPI documentation from the temporary file created by the swagger:annotate command. '
1717
. 'The temporary file is deleted afterwards.'
1818
)]
19-
class GenerateSwagger extends Command
19+
class SwaggerGenerator extends Command
2020
{
2121
protected function execute(InputInterface $input, OutputInterface $output): int
2222
{
2323
$path = __DIR__ . '/../V1Module/presenters/_autogenerated_annotations_temp.php';
2424

2525
// check if file exists
2626
if (!file_exists($path)) {
27-
$output->writeln("Error in GenerateSwagger: Temp annotation file not found.");
27+
$output->writeln("Error in SwaggerGenerator: Temp annotation file not found.");
2828
return Command::FAILURE;
2929
}
3030

31-
$openapi = Generator::scan([$path]);
31+
$generator = new Generator();
32+
$openapi = $generator->generate([$path]);
3233

3334
$output->writeln($openapi->toYaml());
3435

app/config/config.neon

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ services:
312312

313313
# commands
314314
- App\Console\DoctrineFixtures
315-
#- App\Console\GenerateSwagger(@router)
316315
- App\Console\CleanupUploads
317316
- App\Console\CleanupExercisesFiles
318317
- App\Console\CleanupWorkerTmpFiles
@@ -322,7 +321,7 @@ services:
322321
- App\Console\GeneralStatsNotification
323322
- App\Console\ExportDatabase
324323
- App\Console\MetaConverter
325-
- App\Console\GenerateSwagger
324+
- App\Console\SwaggerGenerator
326325
- App\Console\SwaggerAnnotator
327326
- App\Console\CleanupLocalizedTexts
328327
- App\Console\CleanupExerciseConfigs

app/helpers/Swagger/AnnotationData.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ class AnnotationData
3737
public array $responseDataList;
3838
public ?string $endpointDescription;
3939

40+
/**
41+
* @var string|null A message indicating why the endpoint is deprecated, or null if the endpoint is not deprecated.
42+
* Empty string is valid and indicates deprecation without a message.
43+
*/
44+
public ?string $deprecated = null;
45+
4046
public function __construct(
4147
string $className,
4248
string $methodName,
@@ -47,6 +53,7 @@ public function __construct(
4753
array $fileParams,
4854
array $responseDataList,
4955
?string $endpointDescription = null,
56+
?string $deprecated = null,
5057
) {
5158
$this->className = $className;
5259
$this->methodName = $methodName;
@@ -57,6 +64,28 @@ public function __construct(
5764
$this->fileParams = $fileParams;
5865
$this->responseDataList = $responseDataList;
5966
$this->endpointDescription = $endpointDescription;
67+
$this->deprecated = $deprecated;
68+
}
69+
70+
private function getSummary(): ?string
71+
{
72+
$summary = $this->endpointDescription;
73+
if ($this->deprecated !== null) {
74+
$summary = $summary ?? '';
75+
$summary .= ($summary ? " " : "") . "[DEPRECATED]";
76+
}
77+
return $summary;
78+
}
79+
80+
private function getDescription(): ?string
81+
{
82+
$description = $this->endpointDescription;
83+
if ($this->deprecated !== null) {
84+
$description = $description ?? '';
85+
$description .= ($description ? "\n" : "") . "[DEPRECATED]" . ($this->deprecated ? ": " : "")
86+
. $this->deprecated;
87+
}
88+
return $description;
6089
}
6190

6291
public function getAllParams(): array
@@ -219,8 +248,8 @@ public function toSwaggerAnnotations(string $route)
219248

220249
// add the endpoint description when provided
221250
if ($this->endpointDescription !== null) {
222-
$body->addKeyValue("summary", $this->endpointDescription);
223-
$body->addKeyValue("description", $this->endpointDescription);
251+
$body->addKeyValue("summary", $this->getSummary());
252+
$body->addKeyValue("description", $this->getDescription());
224253
}
225254

226255
foreach ($this->pathParams as $pathParam) {
@@ -255,6 +284,10 @@ public function toSwaggerAnnotations(string $route)
255284
$body->addValue('@OA\Response(response="200",description="Placeholder response")');
256285
}
257286

287+
if ($this->deprecated) {
288+
$body->addKeyValue("deprecated", true);
289+
}
290+
258291
return $httpMethodAnnotation . $body->toString();
259292
}
260293
}

app/helpers/Swagger/AnnotationHelper.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,31 @@ private static function extractAnnotationDescription(array $annotations): ?strin
285285
return null;
286286
}
287287

288+
/**
289+
* Extracts the deprecated message from the annotations.
290+
* @param array $annotations The array of annotations.
291+
* @return string|null Returns the concatenated deprecated message (may be '' @deprecated without message is set)
292+
* or null if the endpoint is not deprecated.
293+
*/
294+
private static function extractAnnotationDeprecatedMessage(array $annotations): ?string
295+
{
296+
$deprecated = [];
297+
foreach ($annotations as $annotation) {
298+
if (str_starts_with($annotation, "@deprecated")) {
299+
$deprecated[] = trim(preg_replace('/^@deprecated\s*/', '', $annotation));
300+
}
301+
}
302+
return $deprecated ? implode("\n", array_filter($deprecated)) : null;
303+
}
304+
288305
private static function annotationParameterDataToAnnotationData(
289306
string $className,
290307
string $methodName,
291308
HttpMethods $httpMethod,
292309
array $params,
293310
array $responseDataList,
294311
?string $description,
312+
?string $deprecated = null,
295313
): AnnotationData {
296314
$pathParams = [];
297315
$queryParams = [];
@@ -322,6 +340,7 @@ private static function annotationParameterDataToAnnotationData(
322340
$fileParams,
323341
$responseDataList,
324342
$description,
343+
$deprecated
325344
);
326345
}
327346

@@ -345,14 +364,16 @@ public static function extractStandardAnnotationData(
345364
$httpMethod = self::extractAnnotationHttpMethod($methodAnnotations);
346365
$params = self::extractStandardAnnotationParams($methodAnnotations, $route);
347366
$description = self::extractAnnotationDescription($methodAnnotations);
367+
$deprecated = self::extractAnnotationDeprecatedMessage($methodAnnotations);
348368

349369
return self::annotationParameterDataToAnnotationData(
350370
$className,
351371
$methodName,
352372
$httpMethod,
353373
$params,
354-
[], // there are no reponse params defined in the old annotations
355-
$description
374+
[], // there are no response params defined in the old annotations
375+
$description,
376+
$deprecated,
356377
);
357378
}
358379

@@ -413,6 +434,7 @@ public static function extractAttributeData(string $className, string $methodNam
413434
return $data->toAnnotationParameterData();
414435
}, $attributeData);
415436
$description = self::extractAnnotationDescription($methodAnnotations);
437+
$deprecated = self::extractAnnotationDeprecatedMessage($methodAnnotations);
416438

417439
return self::annotationParameterDataToAnnotationData(
418440
$className,
@@ -421,6 +443,7 @@ public static function extractAttributeData(string $className, string $methodNam
421443
$params,
422444
$responseDataList,
423445
$description,
446+
$deprecated,
424447
);
425448
}
426449

@@ -511,7 +534,6 @@ public static function getPropertyValue(mixed $object, string $propertyName): mi
511534
}
512535
} while ($property === null && $class !== null);
513536

514-
$property->setAccessible(true);
515537
return $property->getValue($object);
516538
}
517539

0 commit comments

Comments
 (0)