mpociot / laravel-apidoc-generator

Compare 248a052 ... +21 ... f98914a

Showing 14 of 29 files from the diff.

@@ -19,12 +19,14 @@
Loading
19 19
    }
20 20
21 21
    /**
22 -
     * @param array $action
22 +
     * @param array|Route $routeOrAction
23 23
     *
24 24
     * @return array|null
25 25
     */
26 -
    public static function getRouteActionUses(array $action)
26 +
    public static function getRouteClassAndMethodNames($routeOrAction)
27 27
    {
28 +
        $action = $routeOrAction instanceof Route ? $routeOrAction->getAction() : $routeOrAction;
29 +
28 30
        if ($action['uses'] !== null) {
29 31
            if (is_array($action['uses'])) {
30 32
                return $action['uses'];

@@ -0,0 +1,67 @@
Loading
1 +
<?php
2 +
3 +
namespace Mpociot\ApiDoc\Strategies\Responses;
4 +
5 +
use Illuminate\Routing\Route;
6 +
use Mpociot\Reflection\DocBlock;
7 +
use Mpociot\Reflection\DocBlock\Tag;
8 +
use Mpociot\ApiDoc\Strategies\Strategy;
9 +
use Mpociot\ApiDoc\Tools\RouteDocBlocker;
10 +
11 +
/**
12 +
 * Get a response from the docblock ( @response ).
13 +
 */
14 +
class UseResponseTag extends Strategy
15 +
{
16 +
    /**
17 +
     * @param Route $route
18 +
     * @param \ReflectionClass $controller
19 +
     * @param \ReflectionMethod $method
20 +
     * @param array $routeRules
21 +
     * @param array $context
22 +
     *
23 +
     * @throws \Exception
24 +
     *
25 +
     * @return array|null
26 +
     */
27 +
    public function __invoke(Route $route, \ReflectionClass $controller, \ReflectionMethod $method, array $routeRules, array $context = [])
28 +
    {
29 +
        $docBlocks = RouteDocBlocker::getDocBlocksFromRoute($route);
30 +
        /** @var DocBlock $methodDocBlock */
31 +
        $methodDocBlock = $docBlocks['method'];
32 +
33 +
        return $this->getDocBlockResponses($methodDocBlock->getTags());
34 +
    }
35 +
36 +
    /**
37 +
     * Get the response from the docblock if available.
38 +
     *
39 +
     * @param array $tags
40 +
     *
41 +
     * @return array|null
42 +
     */
43 +
    protected function getDocBlockResponses(array $tags)
44 +
    {
45 +
        $responseTags = array_values(
46 +
            array_filter($tags, function ($tag) {
47 +
                return $tag instanceof Tag && strtolower($tag->getName()) === 'response';
48 +
            })
49 +
        );
50 +
51 +
        if (empty($responseTags)) {
52 +
            return null;
53 +
        }
54 +
55 +
        $responses = array_map(function (Tag $responseTag) {
56 +
            preg_match('/^(\d{3})?\s?([\s\S]*)$/', $responseTag->getContent(), $result);
57 +
58 +
            $status = $result[1] ?: 200;
59 +
            $content = $result[2] ?: '{}';
60 +
61 +
            return [$content, (int) $status];
62 +
        }, $responseTags);
63 +
64 +
        // Convert responses to [200 => 'response', 401 => 'response']
65 +
        return collect($responses)->pluck('0', '1')->toArray();
66 +
    }
67 +
}

@@ -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 +
}

@@ -247,7 +247,7 @@
Loading
247 247
     */
248 248
    private function isValidRoute(Route $route)
249 249
    {
250 -
        $action = Utils::getRouteActionUses($route->getAction());
250 +
        $action = Utils::getRouteClassAndMethodNames($route->getAction());
251 251
        if (is_array($action)) {
252 252
            $action = implode('@', $action);
253 253
        }
@@ -264,7 +264,7 @@
Loading
264 264
     */
265 265
    private function isRouteVisibleForDocumentation(array $action)
266 266
    {
267 -
        list($class, $method) = Utils::getRouteActionUses($action);
267 +
        list($class, $method) = Utils::getRouteClassAndMethodNames($action);
268 268
        $reflection = new ReflectionClass($class);
269 269
270 270
        if (! $reflection->hasMethod($method)) {

@@ -2,46 +2,91 @@
Loading
2 2
3 3
namespace Mpociot\ApiDoc\Tools\Traits;
4 4
5 -
use Illuminate\Support\Arr;
6 -
use Illuminate\Support\Str;
5 +
use Faker\Factory;
7 6
8 7
trait ParamHelpers
9 8
{
9 +
    protected function generateDummyValue(string $type)
10 +
    {
11 +
        $faker = Factory::create();
12 +
        if ($this->config->get('faker_seed')) {
13 +
            $faker->seed($this->config->get('faker_seed'));
14 +
        }
15 +
        $fakeFactories = [
16 +
            'integer' => function () use ($faker) {
17 +
                return $faker->numberBetween(1, 20);
18 +
            },
19 +
            'number' => function () use ($faker) {
20 +
                return $faker->randomFloat();
21 +
            },
22 +
            'float' => function () use ($faker) {
23 +
                return $faker->randomFloat();
24 +
            },
25 +
            'boolean' => function () use ($faker) {
26 +
                return $faker->boolean();
27 +
            },
28 +
            'string' => function () use ($faker) {
29 +
                return $faker->word;
30 +
            },
31 +
            'array' => function () {
32 +
                return [];
33 +
            },
34 +
            'object' => function () {
35 +
                return new \stdClass;
36 +
            },
37 +
        ];
38 +
39 +
        $fakeFactory = $fakeFactories[$type] ?? $fakeFactories['string'];
40 +
41 +
        return $fakeFactory();
42 +
    }
43 +
10 44
    /**
11 -
     * Create proper arrays from dot-noted parameter names. Also filter out parameters which were excluded from having examples.
45 +
     * Cast a value from a string to a specified type.
12 46
     *
13 -
     * @param array $params
47 +
     * @param string $value
48 +
     * @param string $type
14 49
     *
15 -
     * @return array
50 +
     * @return mixed
16 51
     */
17 -
    protected function cleanParams(array $params)
52 +
    protected function castToType(string $value, string $type)
18 53
    {
19 -
        $values = [];
20 -
        $params = array_filter($params, function ($details) {
21 -
            return ! is_null($details['value']);
22 -
        });
54 +
        $casts = [
55 +
            'integer' => 'intval',
56 +
            'number' => 'floatval',
57 +
            'float' => 'floatval',
58 +
            'boolean' => 'boolval',
59 +
        ];
60 +
61 +
        // First, we handle booleans. We can't use a regular cast,
62 +
        //because PHP considers string 'false' as true.
63 +
        if ($value == 'false' && $type == 'boolean') {
64 +
            return false;
65 +
        }
23 66
24 -
        foreach ($params as $name => $details) {
25 -
            $this->cleanValueFrom($name, $details['value'], $values);
67 +
        if (isset($casts[$type])) {
68 +
            return $casts[$type]($value);
26 69
        }
27 70
28 -
        return $values;
71 +
        return $value;
29 72
    }
30 73
31 74
    /**
32 -
     * Converts dot notation names to arrays and sets the value at the right depth.
75 +
     * Normalizes the stated "type" of a parameter (eg "int", "integer", "double")
76 +
     * to a number of standard types (integer, boolean, float).
33 77
     *
34 -
     * @param string $name
35 -
     * @param mixed $value
36 -
     * @param array $values The array that holds the result
78 +
     * @param string $type
37 79
     *
38 -
     * @return void
80 +
     * @return mixed|string
39 81
     */
40 -
    protected function cleanValueFrom($name, $value, array &$values = [])
82 +
    protected function normalizeParameterType(string $type)
41 83
    {
42 -
        if (Str::contains($name, '[')) {
43 -
            $name = str_replace(['][', '[', ']', '..'], ['.', '.', '', '.*.'], $name);
44 -
        }
45 -
        Arr::set($values, str_replace('.*', '.0', $name), $value);
84 +
        $typeMap = [
85 +
            'int' => 'integer',
86 +
            'bool' => 'boolean',
87 +
            'double' => 'float',
88 +
        ];
89 +
90 +
        return $type ? ($typeMap[$type] ?? $type) : 'string';
46 91
    }
47 92
}

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...

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 7 files with coverage changes found.

New file src/Strategies/BodyParameters/GetFromBodyParamTag.php
New
Loading file...
New file src/Strategies/Strategy.php
New
Loading file...
New file src/Strategies/Metadata/GetFromDocBlocks.php
New
Loading file...
New file src/Strategies/Responses/UseResponseTag.php
New
Loading file...
New file src/Tools/Traits/DocBlockParamHelpers.php
New
Loading file...
New file src/Strategies/QueryParameters/GetFromQueryParamTag.php
New
Loading file...
New file src/Tools/RouteDocBlocker.php
New
Loading file...

23 Commits

Hiding 2 contexual commits
Hiding 6 contexual commits
+1 Files
+5
+5
Hiding 10 contexual commits
+4 Files
+51
+49
+2
Files Complexity Coverage
src ø 0.43% 90.86%
Project Totals (19 files) 315 90.86%
Loading