Skip to content

Commit

Permalink
Merge branch 'zircote:master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
fulldecent authored Sep 25, 2024
2 parents a6ab2af + 874c909 commit 6cb5e46
Show file tree
Hide file tree
Showing 9 changed files with 929 additions and 799 deletions.
6 changes: 6 additions & 0 deletions docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@
border-bottom: solid 1px #ddd;
}
}

.table-plain, table.table-plain tr, table.table-plain th, table.table-plain td {
border: none;
padding: 2px 12px 2px 0;
background: none;
}
302 changes: 151 additions & 151 deletions docs/reference/annotations.md

Large diffs are not rendered by default.

1,282 changes: 641 additions & 641 deletions docs/reference/attributes.md

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions docs/reference/processors.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@ Generate the OperationId based on the context of the OpenApi annotation.
</dl>


### [AugmentTags](https://github.com/zircote/swagger-php/tree/master/src/Processors/AugmentTags.php)

Ensures that all tags used on operations also exist in the global <code>tags</code> list.
### [CleanUnmerged](https://github.com/zircote/swagger-php/tree/master/src/Processors/CleanUnmerged.php)


Expand Down Expand Up @@ -151,3 +148,14 @@ Tracks the use of all <code>Components</code> and removed unused schemas.
</dl>


### [AugmentTags](https://github.com/zircote/swagger-php/tree/master/src/Processors/AugmentTags.php)

Ensures that all tags used on operations also exist in the global <code>tags</code> list.
#### Config settings
<dl>
<dt><strong>augmentTags.whitelist</strong> : <span style="font-family: monospace;">array</span></dt>
<dt><strong>default</strong> : <span style="font-family: monospace;">[]</span></dt>
<dd><p>Whitelist tags to keep even if not used. <code>*</code> may be used to keep all unused.</p> </dd>
</dl>


5 changes: 5 additions & 0 deletions src/Annotations/PathParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ class PathParameter extends Parameter
* @inheritdoc
*/
public $required = true;

/**
* @inheritdoc
*/
public static $_required = ['name'];
}
32 changes: 31 additions & 1 deletion src/Processors/AugmentTags.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@
*/
class AugmentTags implements ProcessorInterface
{

/** @var array<string> */
protected $whitelist = [];

public function __construct(array $whitelist = [])
{
$this->whitelist = $whitelist;
}

/**
* Whitelist tags to keep even if not used. <code>*</code> may be used to keep all unused.
*/
public function setWhitelist(array $whitelist): AugmentTags
{
$this->whitelist = $whitelist;

return $this;
}

public function __invoke(Analysis $analysis)
{
/** @var OA\Operation[] $operations */
Expand All @@ -39,6 +58,7 @@ public function __invoke(Analysis $analysis)
$analysis->openapi->tags = array_values($declaredTags);
}

// Add a tag for each tag that is used in operations but not declared in the global tags
if ($usedTagNames) {
$declatedTagNames = array_keys($declaredTags);
foreach ($usedTagNames as $tagName) {
Expand All @@ -48,8 +68,18 @@ public function __invoke(Analysis $analysis)
}
}

$this->removeUnusedTags($usedTagNames, $declaredTags, $analysis);
}

private function removeUnusedTags(array $usedTagNames, array $declaredTags, Analysis $analysis)
{
if (in_array('*', $this->whitelist)) {
return;
}

$tagsToKeep = array_merge($usedTagNames, $this->whitelist);
foreach ($declaredTags as $tag) {
if (!in_array($tag->name, $usedTagNames)) {
if (!in_array($tag->name, $tagsToKeep)) {
if (false !== $index = array_search($tag, $analysis->openapi->tags, true)) {
$analysis->annotations->detach($tag);
unset($analysis->openapi->tags[$index]);
Expand Down
32 changes: 32 additions & 0 deletions tests/Fixtures/UnusedTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types=1);

/**
* @license Apache 2.0
*/

namespace OpenApi\Tests\Fixtures;

use OpenApi\Attributes as OAT;

#[OAT\OpenApi(
info: new OAT\Info(
title: 'test',
description: 'test',
version: '2.0.0'
),
tags: [
// definding tag 'other' globally with nice description
new OAT\Tag('other', 'Other description'),
// making a tag that has no operations referencing it, but we wish to keep it
new OAT\Tag('fancy', 'Fancy description'),
// making a tag that it not used, but we do not wish to keep
new OAT\Tag('notused', 'remove this one'),
]
)]
class UnusedTags
{
#[OAT\Get(path: '/other/', tags: ['other'], responses: [new OAT\Response(response: '200', description: 'success')])]
public function hello(): void
{
}
}
38 changes: 38 additions & 0 deletions tests/Processors/AugmentTagsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,42 @@ public function testDedupedAugmentTags(): void

$this->assertCount(3, $analysis->openapi->tags, 'Expecting 3 unique tags');
}

/**
* @requires PHP 8.1
*/
public function testAllowUnusedTags(): void
{
$this->skipLegacy();

$analysis = $this->analysisFromFixtures(
['UnusedTags.php'],
static::processors(),
null,
[
'augmentTags' => ['whitelist' => ['fancy']],
]
);

$this->assertCount(2, $analysis->openapi->tags, 'Expecting fancy tag to be preserved');
}

/**
* @requires PHP 8.1
*/
public function testAllowUnusedTagsWildcard(): void
{
$this->skipLegacy();

$analysis = $this->analysisFromFixtures(
['UnusedTags.php'],
static::processors(),
null,
[
'augmentTags' => ['whitelist' => ['*']],
]
);

$this->assertCount(3, $analysis->openapi->tags, 'Expecting all tags to be preserved');
}
}
17 changes: 14 additions & 3 deletions tools/src/Docs/RefGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,18 +163,28 @@ public function formatAnnotationsDetails(string $name, string $fqdn, string $fil

protected function getPropertyDocumentation(string $fqdn, string $name): array
{
/** @var class-string<AbstractAnnotation> $class */
$class = str_replace('Attributes', 'Annotations', $fqdn);
try {
$rp = new \ReflectionProperty(str_replace('Attributes', 'Annotations', $fqdn), $name);
$rp = new \ReflectionProperty($class, $name);
} catch (\ReflectionException $re) {
$rp = null;
}

return $this->extractDocumentation($rp ? $rp->getDocComment() : null);
$documentation = $this->extractDocumentation($rp ? $rp->getDocComment() : null);

$documentation['required'] = in_array($name, $class::$_required);

return $documentation;
}

protected function propertyDetails(array $propertyDocumentation): void
{
echo '<p>' . nl2br($propertyDocumentation['content'] ?: self::NO_DETAILS_AVAILABLE) . '</p>';

echo '<table class="table-plain">';
echo '<tr><td><i>Required</i>:</td><td style="padding-left: 0;"><b>' . ($propertyDocumentation['required'] ? 'yes' : 'no') . '</b></td></tr>';

if ($propertyDocumentation['see']) {
$links = [];
foreach ($propertyDocumentation['see'] as $see) {
Expand All @@ -183,10 +193,11 @@ protected function propertyDetails(array $propertyDocumentation): void
}
}
if ($links) {
echo '<p><i>See</i>: ' . implode(', ', $links) . '</p>';
echo '<tr><td style="padding-left: 0;"><i>See</i>:</td><td style="padding-left: 0;">' . implode(', ', $links) . '</td></tr>';
}
}

echo '</table>';
}

/**
Expand Down

0 comments on commit 6cb5e46

Please sign in to comment.