Skip to content

Commit

Permalink
Merge pull request #10 from Tobion/fix-default-route-name-swagger-3.2.2
Browse files Browse the repository at this point in the history
Fix default route name with swagger-php >=3.2.2 which hashes the operationId
  • Loading branch information
Tobion committed Sep 2, 2021
2 parents fb790c9 + 96ff5af commit 48a08be
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
28 changes: 26 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ on:
- cron: '0 11 26 * *'

jobs:
build-lowest-version:
name: Build lowest version
build-lowest-dependencies:
name: With lowest dependencies
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -53,3 +53,27 @@ jobs:

- name: Run tests
run: vendor/bin/simple-phpunit

build-dev-dependencies:
name: With dev dependencies & PHP
runs-on: ubuntu-latest

steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
coverage: 'none'

- name: Checkout code
uses: actions/checkout@v2

- name: Allow dev dependencies
run: composer config minimum-stability dev

- name: Install dependencies
run: composer update --no-interaction --no-progress --prefer-dist

- name: Run tests
continue-on-error: true
run: vendor/bin/simple-phpunit
38 changes: 33 additions & 5 deletions src/OpenApiRouteLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

namespace Tobion\OpenApiSymfonyRouting;

use OpenApi\Analysis;
use OpenApi\Annotations\OpenApi;
use OpenApi\Annotations\Operation;
use OpenApi\Generator;
use OpenApi\Processors\DocBlockDescriptions;
use OpenApi\Processors\OperationId;
use Symfony\Bundle\FrameworkBundle\Routing\RouteLoaderInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Routing\Route;
Expand All @@ -22,9 +27,18 @@ class OpenApiRouteLoader implements RouteLoaderInterface
*/
private $routeNames = [];

/**
* @var string
*/
private static $openApiUndefined;

public function __construct(Finder $finder)
{
$this->finder = $finder;

if (!isset(self::$openApiUndefined)) {
self::$openApiUndefined = \class_exists(Generator::class) ? Generator::UNDEFINED : \OpenApi\UNDEFINED;
}
}

public static function fromDirectories(string $dir, string ...$moreDirs): self
Expand All @@ -44,7 +58,7 @@ public static function fromSrcDirectory(): self

public function __invoke(): RouteCollection
{
$openApi = \OpenApi\scan($this->finder);
$openApi = $this->createOpenApi();
$routeCollection = new RouteCollection();

$globalFormatSuffixConfig = FormatSuffixConfig::fromAnnotation($openApi);
Expand All @@ -66,12 +80,26 @@ public function __invoke(): RouteCollection
return $routeCollection;
}

private function createOpenApi(): OpenApi
{
if (!\class_exists(Generator::class)) {
return \OpenApi\scan($this->finder);
}

$processors = array_filter(Analysis::processors(), static function ($processor): bool {
// remove OperationId processor which would hash the controller starting in 3.2.2 breaking the default route name logic
return !$processor instanceof OperationId && !$processor instanceof DocBlockDescriptions;
});

return (new Generator())->setProcessors($processors)->generate($this->finder);
}

/**
* @param Operation|string $operation
*/
private function addRouteFromOpenApiOperation(RouteCollection $routeCollection, $operation, FormatSuffixConfig $parentFormatSuffixConfig): void
{
if (\OpenApi\UNDEFINED === $operation || !$operation instanceof Operation) {
if (self::$openApiUndefined === $operation || !$operation instanceof Operation) {
return;
}

Expand All @@ -98,9 +126,9 @@ private function createRoute(Operation $operation, string $controller, FormatSuf
$route->setRequirement('_format', $formatSuffixConfig->pattern);
}
}
if (\OpenApi\UNDEFINED !== $operation->parameters) {
if (self::$openApiUndefined !== $operation->parameters) {
foreach ($operation->parameters as $parameter) {
if ('path' === $parameter->in && \OpenApi\UNDEFINED !== $parameter->schema && \OpenApi\UNDEFINED !== $parameter->schema->pattern) {
if ('path' === $parameter->in && self::$openApiUndefined !== $parameter->schema && self::$openApiUndefined !== $parameter->schema->pattern) {
$route->setRequirement($parameter->name, $parameter->schema->pattern);
}
}
Expand All @@ -121,7 +149,7 @@ private function getRouteName(Operation $operation, string $controller): string
// swagger-php v3 adds the controller as operationId automatically, see \OpenApi\Processors\OperationId.
// This must be ignored as it is not viable with multiple annotations on the same controller.

return \OpenApi\UNDEFINED === $operation->operationId || $controller === $operation->operationId ? $this->getDefaultRouteName($controller) : $operation->operationId;
return self::$openApiUndefined === $operation->operationId || $controller === $operation->operationId ? $this->getDefaultRouteName($controller) : $operation->operationId;
}

private function getRoutePriority(Operation $operation): int
Expand Down

0 comments on commit 48a08be

Please sign in to comment.