From fdae3cce61e14673d3f26ff1be680e6011dfb0c6 Mon Sep 17 00:00:00 2001 From: Joris van Lier Date: Sat, 22 May 2021 20:21:26 +0200 Subject: [PATCH] get headers from tags --- config/apidoc.php | 1 + .../partials/example-requests/bash.blade.php | 2 +- src/Extracting/Generator.php | 21 ++++++ .../RequestHeaders/GetFromHeaderTag.php | 73 +++++++++++++++++++ tests/Unit/GeneratorTestCase.php | 1 + 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/Extracting/Strategies/RequestHeaders/GetFromHeaderTag.php diff --git a/config/apidoc.php b/config/apidoc.php index 8ae737be..3f0e6165 100644 --- a/config/apidoc.php +++ b/config/apidoc.php @@ -215,6 +215,7 @@ ], 'headers' => [ \Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromRouteRules::class, + \Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromHeaderTag::class, ], 'bodyParameters' => [ \Mpociot\ApiDoc\Extracting\Strategies\BodyParameters\GetFromBodyParamTag::class, diff --git a/resources/views/partials/example-requests/bash.blade.php b/resources/views/partials/example-requests/bash.blade.php index 5237be86..fca0a120 100644 --- a/resources/views/partials/example-requests/bash.blade.php +++ b/resources/views/partials/example-requests/bash.blade.php @@ -1,7 +1,7 @@ ```bash curl -X {{$route['methods'][0]}} \ {{$route['methods'][0] == 'GET' ? '-G ' : ''}}"{{ rtrim($baseUrl, '/')}}/{{ ltrim($route['boundUri'], '/') }}@if(count($route['cleanQueryParameters']))?{!! \Mpociot\ApiDoc\Tools\Utils::printQueryParamsAsString($route['cleanQueryParameters']) !!}@endif" @if(count($route['headers']))\ -@foreach($route['headers'] as $header => $value) +@foreach($route['cleanHeaders'] as $header => $value) -H "{{$header}}: {{ addslashes($value) }}"@if(! ($loop->last) || ($loop->last && count($route['bodyParameters']))) \ @endif @endforeach diff --git a/src/Extracting/Generator.php b/src/Extracting/Generator.php index 0a5f1df5..8b429f68 100644 --- a/src/Extracting/Generator.php +++ b/src/Extracting/Generator.php @@ -76,6 +76,7 @@ public function processRoute(Route $route, array $routeRules = []) $headers = $this->fetchRequestHeaders($controller, $method, $route, $routeRules, $parsedRoute); $parsedRoute['headers'] = $headers; + $parsedRoute['cleanHeaders'] = $this->cleanHeaders($headers); $bodyParameters = $this->fetchBodyParameters($controller, $method, $route, $routeRules, $parsedRoute); $parsedRoute['bodyParameters'] = $bodyParameters; @@ -222,6 +223,26 @@ protected function cleanParams(array $params) return $values; } + /** + * Create samples at index 0 for array parameters. + * Also filter out header which were excluded from having examples. + * + * @param array $params + * + * @return array + */ + protected function cleanHeaders(array $params) + { + $values = []; + + // Remove params which have no examples. + $params = array_filter($params, function ($details) { + return ! empty($details); + }); + + return $params; + } + /** * For each array notation parameter (eg user.*, item.*.name, object.*.*, user[]) * generate concrete sample (user.0, item.0.name, object.0.0, user.0) with example as value. diff --git a/src/Extracting/Strategies/RequestHeaders/GetFromHeaderTag.php b/src/Extracting/Strategies/RequestHeaders/GetFromHeaderTag.php new file mode 100644 index 00000000..5485c6d8 --- /dev/null +++ b/src/Extracting/Strategies/RequestHeaders/GetFromHeaderTag.php @@ -0,0 +1,73 @@ +getParameters() as $param) { + $paramType = $param->getType(); + if ($paramType === null) { + continue; + } + + $parameterClassName = $paramType->getName(); + + try { + $parameterClass = new ReflectionClass($parameterClassName); + } catch (\ReflectionException $e) { + continue; + } + + // If there's a FormRequest, we check there for @urlParam tags. + if (class_exists(LaravelFormRequest::class) && $parameterClass->isSubclassOf(LaravelFormRequest::class) + || class_exists(DingoFormRequest::class) && $parameterClass->isSubclassOf(DingoFormRequest::class)) { + $formRequestDocBlock = new DocBlock($parameterClass->getDocComment()); + $headersFromDocBlock = $this->getHeadersFromDocBlock($formRequestDocBlock->getTags()); + + if (count($headersFromDocBlock)) { + return $headersFromDocBlock; + } + } + } + + /** @var DocBlock $methodDocBlock */ + $methodDocBlock = RouteDocBlocker::getDocBlocksFromRoute($route)['method']; + + return $this->getHeadersFromDocBlock($methodDocBlock->getTags()); + } + + private function getHeadersFromDocBlock($tags) + { + $parameters = collect($tags) + ->filter(function ($tag) { + return $tag instanceof Tag && $tag->getName() === 'header'; + }) + ->mapWithKeys(function (Tag $tag) { + // Format: + // @header + // Examples: + // @header Cookie foo Example: crumbs + preg_match('/(.+?)\s+(.*)/', $tag->getContent(), $content); + list($content, $name, $value) = $content; + return [$name => $value]; + })->toArray(); + + return $parameters; + } +} diff --git a/tests/Unit/GeneratorTestCase.php b/tests/Unit/GeneratorTestCase.php index f4a167d6..1dbbf923 100644 --- a/tests/Unit/GeneratorTestCase.php +++ b/tests/Unit/GeneratorTestCase.php @@ -33,6 +33,7 @@ abstract class GeneratorTestCase extends TestCase \Mpociot\ApiDoc\Extracting\Strategies\QueryParameters\GetFromQueryParamTag::class, ], 'headers' => [ + \Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromHeaderTag::class, \Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromRouteRules::class, ], 'bodyParameters' => [