Skip to content

Commit fdae3cc

Browse files
committed
get headers from tags
1 parent 3279e98 commit fdae3cc

File tree

5 files changed

+97
-1
lines changed

5 files changed

+97
-1
lines changed

config/apidoc.php

+1
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@
215215
],
216216
'headers' => [
217217
\Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromRouteRules::class,
218+
\Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromHeaderTag::class,
218219
],
219220
'bodyParameters' => [
220221
\Mpociot\ApiDoc\Extracting\Strategies\BodyParameters\GetFromBodyParamTag::class,

resources/views/partials/example-requests/bash.blade.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
```bash
22
curl -X {{$route['methods'][0]}} \
33
{{$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']))\
4-
@foreach($route['headers'] as $header => $value)
4+
@foreach($route['cleanHeaders'] as $header => $value)
55
-H "{{$header}}: {{ addslashes($value) }}"@if(! ($loop->last) || ($loop->last && count($route['bodyParameters']))) \
66
@endif
77
@endforeach

src/Extracting/Generator.php

+21
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public function processRoute(Route $route, array $routeRules = [])
7676

7777
$headers = $this->fetchRequestHeaders($controller, $method, $route, $routeRules, $parsedRoute);
7878
$parsedRoute['headers'] = $headers;
79+
$parsedRoute['cleanHeaders'] = $this->cleanHeaders($headers);
7980

8081
$bodyParameters = $this->fetchBodyParameters($controller, $method, $route, $routeRules, $parsedRoute);
8182
$parsedRoute['bodyParameters'] = $bodyParameters;
@@ -222,6 +223,26 @@ protected function cleanParams(array $params)
222223
return $values;
223224
}
224225

226+
/**
227+
* Create samples at index 0 for array parameters.
228+
* Also filter out header which were excluded from having examples.
229+
*
230+
* @param array $params
231+
*
232+
* @return array
233+
*/
234+
protected function cleanHeaders(array $params)
235+
{
236+
$values = [];
237+
238+
// Remove params which have no examples.
239+
$params = array_filter($params, function ($details) {
240+
return ! empty($details);
241+
});
242+
243+
return $params;
244+
}
245+
225246
/**
226247
* For each array notation parameter (eg user.*, item.*.name, object.*.*, user[])
227248
* generate concrete sample (user.0, item.0.name, object.0.0, user.0) with example as value.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders;
4+
5+
use Dingo\Api\Http\FormRequest as DingoFormRequest;
6+
use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest;
7+
use Illuminate\Routing\Route;
8+
use Illuminate\Support\Str;
9+
use Mpociot\ApiDoc\Extracting\ParamHelpers;
10+
use Mpociot\ApiDoc\Extracting\RouteDocBlocker;
11+
use Mpociot\ApiDoc\Extracting\Strategies\Strategy;
12+
use Mpociot\Reflection\DocBlock;
13+
use Mpociot\Reflection\DocBlock\Tag;
14+
use ReflectionClass;
15+
use ReflectionMethod;
16+
17+
class GetFromHeaderTag extends Strategy
18+
{
19+
use ParamHelpers;
20+
21+
public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
22+
{
23+
foreach ($method->getParameters() as $param) {
24+
$paramType = $param->getType();
25+
if ($paramType === null) {
26+
continue;
27+
}
28+
29+
$parameterClassName = $paramType->getName();
30+
31+
try {
32+
$parameterClass = new ReflectionClass($parameterClassName);
33+
} catch (\ReflectionException $e) {
34+
continue;
35+
}
36+
37+
// If there's a FormRequest, we check there for @urlParam tags.
38+
if (class_exists(LaravelFormRequest::class) && $parameterClass->isSubclassOf(LaravelFormRequest::class)
39+
|| class_exists(DingoFormRequest::class) && $parameterClass->isSubclassOf(DingoFormRequest::class)) {
40+
$formRequestDocBlock = new DocBlock($parameterClass->getDocComment());
41+
$headersFromDocBlock = $this->getHeadersFromDocBlock($formRequestDocBlock->getTags());
42+
43+
if (count($headersFromDocBlock)) {
44+
return $headersFromDocBlock;
45+
}
46+
}
47+
}
48+
49+
/** @var DocBlock $methodDocBlock */
50+
$methodDocBlock = RouteDocBlocker::getDocBlocksFromRoute($route)['method'];
51+
52+
return $this->getHeadersFromDocBlock($methodDocBlock->getTags());
53+
}
54+
55+
private function getHeadersFromDocBlock($tags)
56+
{
57+
$parameters = collect($tags)
58+
->filter(function ($tag) {
59+
return $tag instanceof Tag && $tag->getName() === 'header';
60+
})
61+
->mapWithKeys(function (Tag $tag) {
62+
// Format:
63+
// @header <content>
64+
// Examples:
65+
// @header Cookie foo Example: crumbs
66+
preg_match('/(.+?)\s+(.*)/', $tag->getContent(), $content);
67+
list($content, $name, $value) = $content;
68+
return [$name => $value];
69+
})->toArray();
70+
71+
return $parameters;
72+
}
73+
}

tests/Unit/GeneratorTestCase.php

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ abstract class GeneratorTestCase extends TestCase
3333
\Mpociot\ApiDoc\Extracting\Strategies\QueryParameters\GetFromQueryParamTag::class,
3434
],
3535
'headers' => [
36+
\Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromHeaderTag::class,
3637
\Mpociot\ApiDoc\Extracting\Strategies\RequestHeaders\GetFromRouteRules::class,
3738
],
3839
'bodyParameters' => [

0 commit comments

Comments
 (0)