mpociot / laravel-apidoc-generator

Compare 1a0bff3 ... +24 ... 44bdabe


@@ -4,13 +4,12 @@
Loading
4 4
5 5
use ReflectionClass;
6 6
use ReflectionMethod;
7 +
use Illuminate\Support\Arr;
8 +
use Illuminate\Support\Str;
7 9
use Illuminate\Routing\Route;
8 -
use Mpociot\ApiDoc\Tools\Traits\ParamHelpers;
9 10
10 11
class Generator
11 12
{
12 -
    use ParamHelpers;
13 -
14 13
    /**
15 14
     * @var DocumentationConfig
16 15
     */
@@ -147,4 +146,50 @@
Loading
147 146
148 147
        return $context[$key];
149 148
    }
149 +
150 +
    /**
151 +
     * Create samples at index 0 for array parameters.
152 +
     * Also filter out parameters which were excluded from having examples.
153 +
     *
154 +
     * @param array $params
155 +
     *
156 +
     * @return array
157 +
     */
158 +
    protected function cleanParams(array $params)
159 +
    {
160 +
        $values = [];
161 +
162 +
        // Remove params which have no examples.
163 +
        $params = array_filter($params, function ($details) {
164 +
            return ! is_null($details['value']);
165 +
        });
166 +
167 +
        foreach ($params as $paramName => $details) {
168 +
            $this->generateConcreteSampleForArrayKeys(
169 +
                $paramName, $details['value'], $values
170 +
            );
171 +
        }
172 +
173 +
        return $values;
174 +
    }
175 +
176 +
    /**
177 +
     * For each array notation parameter (eg user.*, item.*.name, object.*.*, user[])
178 +
     * generate concrete sample (user.0, item.0.name, object.0.0, user.0) with example as value.
179 +
     *
180 +
     * @param string $paramName
181 +
     * @param mixed $paramExample
182 +
     * @param array $values The array that holds the result
183 +
     *
184 +
     * @return void
185 +
     */
186 +
    protected function generateConcreteSampleForArrayKeys($paramName, $paramExample, array &$values = [])
187 +
    {
188 +
        if (Str::contains($paramName, '[')) {
189 +
            // Replace usages of [] with dot notation
190 +
            $paramName = str_replace(['][', '[', ']', '..'], ['.', '.', '', '.*.'], $paramName);
191 +
        }
192 +
        // Then generate a sample item for the dot notation
193 +
        Arr::set($values, str_replace('.*', '.0', $paramName), $paramExample);
194 +
    }
150 195
}

@@ -8,9 +8,16 @@
Loading
8 8
9 9
class RouteDocBlocker
10 10
{
11 -
    public static $docBlocks = [];
11 +
    protected static $docBlocks = [];
12 12
13 -
    public static function getDocBlocksFromRoute(Route $route)
13 +
    /**
14 +
     * @param Route $route
15 +
     *
16 +
     * @throws \ReflectionException
17 +
     *
18 +
     * @return array<string, DocBlock> Method and class docblocks
19 +
     */
20 +
    public static function getDocBlocksFromRoute(Route $route): array
14 21
    {
15 22
        list($className, $methodName) = Utils::getRouteClassAndMethodNames($route);
16 23
        $docBlocks = self::getCachedDocBlock($route, $className, $methodName);
@@ -35,18 +42,18 @@
Loading
35 42
36 43
    protected static function getCachedDocBlock(Route $route, string $className, string $methodName)
37 44
    {
38 -
        $routeId = self::getRouteId($route, $className, $methodName);
45 +
        $routeId = self::getRouteCacheId($route, $className, $methodName);
39 46
40 47
        return self::$docBlocks[$routeId] ?? null;
41 48
    }
42 49
43 50
    protected static function cacheDocBlocks(Route $route, string $className, string $methodName, array $docBlocks)
44 51
    {
45 -
        $routeId = self::getRouteId($route, $className, $methodName);
52 +
        $routeId = self::getRouteCacheId($route, $className, $methodName);
46 53
        self::$docBlocks[$routeId] = $docBlocks;
47 54
    }
48 55
49 -
    private static function getRouteId(Route $route, string $className, string $methodName)
56 +
    private static function getRouteCacheId(Route $route, string $className, string $methodName): string
50 57
    {
51 58
        return $route->uri()
52 59
            .':'

@@ -9,13 +9,13 @@
Loading
9 9
use Mpociot\Reflection\DocBlock\Tag;
10 10
use Mpociot\ApiDoc\Strategies\Strategy;
11 11
use Mpociot\ApiDoc\Tools\RouteDocBlocker;
12 -
use Mpociot\ApiDoc\Tools\Traits\ParamHelpers;
13 12
use Dingo\Api\Http\FormRequest as DingoFormRequest;
13 +
use Mpociot\ApiDoc\Tools\Traits\DocBlockParamHelpers;
14 14
use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest;
15 15
16 -
class GetFromDocBlocks extends Strategy
16 +
class GetFromBodyParamTag extends Strategy
17 17
{
18 -
    use ParamHelpers;
18 +
    use DocBlockParamHelpers;
19 19
20 20
    public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
21 21
    {
@@ -78,7 +78,9 @@
Loading
78 78
79 79
                $type = $this->normalizeParameterType($type);
80 80
                list($description, $example) = $this->parseParamDescription($description, $type);
81 -
                $value = is_null($example) && ! $this->shouldExcludeExample($tag) ? $this->generateDummyValue($type) : $example;
81 +
                $value = is_null($example) && ! $this->shouldExcludeExample($tag)
82 +
                    ? $this->generateDummyValue($type)
83 +
                    : $example;
82 84
83 85
                return [$name => compact('type', 'description', 'required', 'value')];
84 86
            })->toArray();

@@ -3,6 +3,7 @@
Loading
3 3
namespace Mpociot\ApiDoc\Postman;
4 4
5 5
use Ramsey\Uuid\Uuid;
6 +
use Illuminate\Support\Str;
6 7
use Illuminate\Support\Collection;
7 8
use Illuminate\Support\Facades\URL;
8 9
@@ -33,6 +34,9 @@
Loading
33 34
    {
34 35
        try {
35 36
            URL::forceRootUrl($this->baseUrl);
37 +
            if (Str::startsWith($this->baseUrl, 'https://')) {
38 +
                URL::forceScheme('https');
39 +
            }
36 40
        } catch (\Error $e) {
37 41
            echo "Warning: Couldn't force base url as your version of Lumen doesn't have the forceRootUrl method.\n";
38 42
            echo "You should probably double check URLs in your generated Postman collection.\n";

@@ -0,0 +1,45 @@
Loading
1 +
<?php
2 +
3 +
namespace Mpociot\ApiDoc\Tools\Traits;
4 +
5 +
use Mpociot\Reflection\DocBlock\Tag;
6 +
7 +
trait DocBlockParamHelpers
8 +
{
9 +
    use ParamHelpers;
10 +
11 +
    /**
12 +
     * Allows users to specify that we shouldn't generate an example for the parameter
13 +
     * by writing 'No-example'.
14 +
     *
15 +
     * @param Tag $tag
16 +
     *
17 +
     * @return bool Whether no example should be generated
18 +
     */
19 +
    protected function shouldExcludeExample(Tag $tag)
20 +
    {
21 +
        return strpos($tag->getContent(), ' No-example') !== false;
22 +
    }
23 +
24 +
    /**
25 +
     * Allows users to specify an example for the parameter by writing 'Example: the-example',
26 +
     * to be used in example requests and response calls.
27 +
     *
28 +
     * @param string $description
29 +
     * @param string $type The type of the parameter. Used to cast the example provided, if any.
30 +
     *
31 +
     * @return array The description and included example.
32 +
     */
33 +
    protected function parseParamDescription(string $description, string $type)
34 +
    {
35 +
        $example = null;
36 +
        if (preg_match('/(.*)\s+Example:\s*(.*)\s*/', $description, $content)) {
37 +
            $description = $content[1];
38 +
39 +
            // examples are parsed as strings by default, we need to cast them properly
40 +
            $example = $this->castToType($content[2], $type);
41 +
        }
42 +
43 +
        return [$description, $example];
44 +
    }
45 +
}

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Learn more Showing 1 files with coverage changes found.

New file src/Tools/Traits/DocBlockParamHelpers.php
New
Loading file...

26 Commits

Hiding 3 contexual commits
+5 Files
+56
+54
+2
Hiding 3 contexual commits
Hiding 1 contexual commits
+21
+21
-19
-19
Hiding 2 contexual commits
+21
+21
-21
-21
Hiding 2 contexual commits
-4 Files
-53
-51
-2
Files Complexity Coverage
src ø 0.06% 90.86%
Project Totals (19 files) 315 90.86%
Loading