Add resolving references of components (#1544)
This commit is contained in:
parent
e1fb191ae0
commit
a6d8a93e5d
|
@ -43,6 +43,9 @@ Determines `schema`, `enum` and `type`.
|
|||
Use the Schema context to extract useful information and inject that into the annotation.
|
||||
|
||||
Merges properties.
|
||||
## [AugmentRequestBody](https://github.com/zircote/swagger-php/tree/master/src/Processors/AugmentRequestBody.php)
|
||||
|
||||
Use the RequestBody context to extract useful information and inject that into the annotation.
|
||||
## [AugmentProperties](https://github.com/zircote/swagger-php/tree/master/src/Processors/AugmentProperties.php)
|
||||
|
||||
Use the property context to extract useful information and inject that into the annotation.
|
||||
|
|
|
@ -324,6 +324,18 @@ class Analysis
|
|||
* @param string $fqdn the source class/interface/trait
|
||||
*/
|
||||
public function getSchemaForSource(string $fqdn): ?OA\Schema
|
||||
{
|
||||
return $this->getAnnotationForSource($fqdn, OA\Schema::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of OA\AbstractAnnotation
|
||||
*
|
||||
* @param string $fqdn the source class/interface/trait
|
||||
* @param class-string<T> $class
|
||||
* @return T|null
|
||||
*/
|
||||
public function getAnnotationForSource(string $fqdn, string $class): ?OA\AbstractAnnotation
|
||||
{
|
||||
$fqdn = '\\' . ltrim($fqdn, '\\');
|
||||
|
||||
|
@ -331,8 +343,9 @@ class Analysis
|
|||
if (array_key_exists($fqdn, $definitions)) {
|
||||
$definition = $definitions[$fqdn];
|
||||
if (is_iterable($definition['context']->annotations)) {
|
||||
/** @var OA\AbstractAnnotation $annotation */
|
||||
foreach (array_reverse($definition['context']->annotations) as $annotation) {
|
||||
if ($annotation instanceof OA\Schema && $annotation->isRoot(OA\Schema::class) && !$annotation->_context->is('generated')) {
|
||||
if (is_a($annotation, $class) && $annotation->isRoot($class) && !$annotation->_context->is('generated')) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,6 +261,7 @@ class Generator
|
|||
new Processors\ExpandTraits(),
|
||||
new Processors\ExpandEnums(),
|
||||
new Processors\AugmentSchemas(),
|
||||
new Processors\AugmentRequestBody(),
|
||||
new Processors\AugmentProperties(),
|
||||
new Processors\BuildPaths(),
|
||||
new Processors\AugmentParameters(),
|
||||
|
|
|
@ -66,6 +66,8 @@ class AugmentRefs implements ProcessorInterface
|
|||
// check if we have a schema for this
|
||||
if ($refSchema = $analysis->getSchemaForSource($annotation->ref)) {
|
||||
$annotation->ref = OA\Components::ref($refSchema);
|
||||
} elseif ($refAnnotation = $analysis->getAnnotationForSource($annotation->ref, get_class($annotation))) {
|
||||
$annotation->ref = OA\Components::ref($refAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Processors;
|
||||
|
||||
use OpenApi\Analysis;
|
||||
use OpenApi\Annotations as OA;
|
||||
use OpenApi\Generator;
|
||||
|
||||
/**
|
||||
* Use the RequestBody context to extract useful information and inject that into the annotation.
|
||||
*/
|
||||
class AugmentRequestBody implements ProcessorInterface
|
||||
{
|
||||
public function __invoke(Analysis $analysis)
|
||||
{
|
||||
/** @var array<OA\RequestBody> $requests */
|
||||
$requests = $analysis->getAnnotationsOfType(OA\RequestBody::class);
|
||||
|
||||
$this->augmentRequestBody($requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<OA\RequestBody> $requests
|
||||
*/
|
||||
protected function augmentRequestBody(array $requests): void
|
||||
{
|
||||
foreach ($requests as $request) {
|
||||
if (!$request->isRoot(OA\RequestBody::class)) {
|
||||
continue;
|
||||
}
|
||||
if (Generator::isDefault($request->request)) {
|
||||
if ($request->_context->is('class')) {
|
||||
$request->request = $request->_context->class;
|
||||
} elseif ($request->_context->is('interface')) {
|
||||
$request->request = $request->_context->interface;
|
||||
} elseif ($request->_context->is('trait')) {
|
||||
$request->request = $request->_context->trait;
|
||||
} elseif ($request->_context->is('enum')) {
|
||||
$request->request = $request->_context->enum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
// NOTE: this file uses "\r\n" linebreaks on purpose
|
||||
|
||||
namespace OpenApi\Tests\Fixtures;
|
||||
|
||||
use OpenApi\Annotations as OA;
|
||||
|
||||
/**
|
||||
* @OA\RequestBody
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* @OA\Post(
|
||||
* path="/",
|
||||
* @OA\RequestBody(ref=OpenApi\Tests\Fixtures\Request::class),
|
||||
* @OA\Response(response="200", description="An example resource")
|
||||
* )
|
||||
*/
|
||||
public function post()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Tests\Processors;
|
||||
|
||||
use OpenApi\Processors\AugmentRefs;
|
||||
use OpenApi\Processors\AugmentRequestBody;
|
||||
use OpenApi\Processors\BuildPaths;
|
||||
use OpenApi\Processors\Concerns\DocblockTrait;
|
||||
use OpenApi\Processors\MergeIntoComponents;
|
||||
use OpenApi\Processors\MergeIntoOpenApi;
|
||||
use OpenApi\Tests\OpenApiTestCase;
|
||||
|
||||
class AugmentRefsTest extends OpenApiTestCase
|
||||
{
|
||||
use DocblockTrait;
|
||||
|
||||
public function testAugmentRefsForRequestBody(): void
|
||||
{
|
||||
$analysis = $this->analysisFromFixtures(['Request.php']);
|
||||
$analysis->process([
|
||||
// create openapi->components
|
||||
new MergeIntoOpenApi(),
|
||||
// Merge standalone Scheme's into openapi->components
|
||||
new MergeIntoComponents(),
|
||||
new BuildPaths(),
|
||||
new AugmentRequestBody(),
|
||||
]);
|
||||
|
||||
$this->assertSame($analysis->openapi->paths[0]->post->requestBody->ref, 'OpenApi\Tests\Fixtures\Request');
|
||||
|
||||
$analysis->process([
|
||||
new AugmentRefs(),
|
||||
]);
|
||||
|
||||
$this->assertSame($analysis->openapi->paths[0]->post->requestBody->ref, '#/components/requestBodies/Request');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @license Apache 2.0
|
||||
*/
|
||||
|
||||
namespace OpenApi\Tests\Processors;
|
||||
|
||||
use OpenApi\Generator;
|
||||
use OpenApi\Processors\AugmentRequestBody;
|
||||
use OpenApi\Processors\MergeIntoComponents;
|
||||
use OpenApi\Processors\MergeIntoOpenApi;
|
||||
use OpenApi\Tests\OpenApiTestCase;
|
||||
|
||||
class AugmentRequestBodyTest extends OpenApiTestCase
|
||||
{
|
||||
public function testAugmentSchemas(): void
|
||||
{
|
||||
$analysis = $this->analysisFromFixtures(['Request.php']);
|
||||
$analysis->process([
|
||||
// create openapi->components
|
||||
new MergeIntoOpenApi(),
|
||||
// Merge standalone Scheme's into openapi->components
|
||||
new MergeIntoComponents(),
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $analysis->openapi->components->requestBodies);
|
||||
$request = $analysis->openapi->components->requestBodies[0];
|
||||
$this->assertSame(Generator::UNDEFINED, $request->request, 'Sanity check. No request was defined');
|
||||
$analysis->process([new AugmentRequestBody()]);
|
||||
|
||||
$this->assertSame('Request', $request->request, '@OA\RequestBody()->request based on classname');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue