瀏覽代碼

Add `@header` tag

shalvah 5 年之前
父節點
當前提交
46fb9684b6

+ 9 - 0
docs/documenting-endpoint-headers.md

@@ -17,3 +17,12 @@ To specify headers to be added to your endpoints, use the `apply.headers` sectio
 ```
 
 All endpoints that start with `v2/` will have the header `Api-Version: v2` included in their example requests and response calls.
+
+Alternatively, you can use the `@header` doc block tag, in the format `@header <name> <optional example>`:
+
+```php
+/**
+ * @header X-Api-Version v1
+ */
+
+```

+ 80 - 0
src/Extracting/Strategies/Headers/GetFromHeaderTag.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace Knuckles\Scribe\Extracting\Strategies\Headers;
+
+use Dingo\Api\Http\FormRequest as DingoFormRequest;
+use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest;
+use Illuminate\Routing\Route;
+use Knuckles\Scribe\Extracting\ParamHelpers;
+use Knuckles\Scribe\Extracting\RouteDocBlocker;
+use Knuckles\Scribe\Extracting\Strategies\Strategy;
+use Mpociot\Reflection\DocBlock;
+use Mpociot\Reflection\DocBlock\Tag;
+use ReflectionClass;
+use ReflectionFunctionAbstract;
+
+class GetFromHeaderTag extends Strategy
+{
+    public $stage = 'headers';
+
+    use ParamHelpers;
+
+    public function __invoke(Route $route, ReflectionClass $controller, ReflectionFunctionAbstract $method, array $routeRules, array $context = [])
+    {
+        foreach ($method->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 @header 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());
+    }
+
+    public function getHeadersFromDocBlock($tags)
+    {
+        $headers = collect($tags)
+            ->filter(function ($tag) {
+                return $tag instanceof Tag && $tag->getName() === 'header';
+            })
+            ->mapWithKeys(function (Tag $tag) {
+                // Format:
+                // @header <name> <example>
+                // Examples:
+                // @header X-Custom An API header
+                preg_match('/([\S]+)(.*)?/', $tag->getContent(), $content);
+
+                [$_, $name, $value] = $content;
+                $value = trim($value);
+                if (empty($value)) {
+                    $value = $this->generateDummyValue('string');
+                }
+
+                return [$name => $value];
+            })->toArray();
+
+        return $headers;
+    }
+}

+ 3 - 3
src/Extracting/Strategies/UrlParameters/GetFromUrlParamTag.php

@@ -40,10 +40,10 @@ class GetFromUrlParamTag extends Strategy
             if (class_exists(LaravelFormRequest::class) && $parameterClass->isSubclassOf(LaravelFormRequest::class)
                 || class_exists(DingoFormRequest::class) && $parameterClass->isSubclassOf(DingoFormRequest::class)) {
                 $formRequestDocBlock = new DocBlock($parameterClass->getDocComment());
-                $queryParametersFromDocBlock = $this->getUrlParametersFromDocBlock($formRequestDocBlock->getTags());
+                $urlParametersFromDocBlock = $this->getUrlParametersFromDocBlock($formRequestDocBlock->getTags());
 
-                if (count($queryParametersFromDocBlock)) {
-                    return $queryParametersFromDocBlock;
+                if (count($urlParametersFromDocBlock)) {
+                    return $urlParametersFromDocBlock;
                 }
             }
         }

+ 33 - 0
tests/Strategies/Headers/GetFromUrlParamTagTest.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Strategies\Headers;
+
+use Knuckles\Scribe\Extracting\Strategies\Headers\GetFromHeaderTag;
+use Knuckles\Scribe\Tools\DocumentationConfig;
+use Mpociot\Reflection\DocBlock\Tag;
+use PHPUnit\Framework\TestCase;
+use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
+
+class GetFromHeaderTagTest extends TestCase
+{
+    use ArraySubsetAsserts;
+
+    /** @test */
+    public function can_fetch_from_header_tag()
+    {
+        $strategy = new GetFromHeaderTag(new DocumentationConfig([]));
+        $tags = [
+            new Tag('header', 'Api-Version v1'),
+            new Tag('header', 'Some-Custom'),
+        ];
+        $results = $strategy->getHeadersFromDocBlock($tags);
+
+        $this->assertArraySubset([
+            'Api-Version' => 'v1',
+        ], $results);
+
+        $this->assertArrayHasKey('Some-Custom', $results);
+        $this->assertNotEmpty($results['Some-Custom']);
+    }
+
+}

+ 0 - 2
todo.md

@@ -11,8 +11,6 @@
 - Port recent changes from old repo
 
 # Features
-- @header
-- --no-extraction
 - Possible feature: https://github.com/mpociot/laravel-apidoc-generator/issues/731
 - file input python