Browse Source

Merge pull request #445 from ezra-obiwale/fix/request-params

Clean up request parameters
Shalvah 6 years ago
parent
commit
4595e4d8e6

+ 3 - 8
resources/views/partials/route.blade.php

@@ -18,10 +18,9 @@ curl -X {{$route['methods'][0]}} {{$route['methods'][0] == 'GET' ? '-G ' : ''}}"
 @endif
 @endforeach
 @endif
-@foreach($route['bodyParameters'] as $attribute => $parameter)
-    -d "{{$attribute}}"="{{$parameter['value'] === false ? "false" : $parameter['value']}}" @if(! ($loop->last))\
+@if(count($route['cleanBodyParameters']))
+    -d '{!! json_encode($route['cleanBodyParameters']) !!}'
 @endif
-@endforeach
 
 ```
 
@@ -50,11 +49,7 @@ let headers = {
 }
 @if(count($route['bodyParameters']))
 
-let body = JSON.stringify({
-@foreach($route['bodyParameters'] as $attribute => $parameter)
-    "{{ $attribute }}": "{{ $parameter['value'] }}",
-@endforeach
-})
+let body = {!! json_encode($route['cleanBodyParameters'], JSON_PRETTY_PRINT) !!}
 @endif
 
 fetch(url, {

+ 3 - 0
src/Commands/GenerateDocumentation.php

@@ -83,6 +83,9 @@ class GenerateDocumentation extends Command
 
         $parsedRouteOutput = $parsedRoutes->map(function ($routeGroup) {
             return $routeGroup->map(function ($route) {
+                if (count($route['cleanBodyParameters'])) {
+                    $route['headers']['Content-Type'] = 'application/json';
+                }
                 $route['output'] = (string) view('apidoc::partials.route')->with('route', $route)->render();
 
                 return $route;

+ 6 - 2
src/Tools/Generator.php

@@ -8,9 +8,12 @@ use ReflectionMethod;
 use Illuminate\Routing\Route;
 use Mpociot\Reflection\DocBlock;
 use Mpociot\Reflection\DocBlock\Tag;
+use Mpociot\ApiDoc\Tools\Traits\ParamHelpers;
 
 class Generator
 {
+    use ParamHelpers;
+
     /**
      * @param Route $route
      *
@@ -62,6 +65,7 @@ class Generator
             'methods' => $this->getMethods($route),
             'uri' => $this->getUri($route),
             'bodyParameters' => $bodyParameters,
+            'cleanBodyParameters' => $this->cleanParams($bodyParameters),
             'queryParameters' => $queryParameters,
             'authenticated' => $this->getAuthStatusFromDocBlock($docBlock['tags']),
             'response' => $content,
@@ -246,10 +250,10 @@ class Generator
                 return str_random();
             },
             'array' => function () {
-                return '[]';
+                return [];
             },
             'object' => function () {
-                return '{}';
+                return new \stdClass;
             },
         ];
 

+ 5 - 2
src/Tools/ResponseStrategies/ResponseCallStrategy.php

@@ -6,12 +6,15 @@ use Dingo\Api\Dispatcher;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Routing\Route;
+use Mpociot\ApiDoc\Tools\Traits\ParamHelpers;
 
 /**
  * Make a call to the route and retrieve its response.
  */
 class ResponseCallStrategy
 {
+    use ParamHelpers;
+
     /**
      * @param Route $route
      * @param array $tags
@@ -68,8 +71,8 @@ class ResponseCallStrategy
         $request = $this->addHeaders($request, $route, $rulesToApply['headers'] ?? []);
 
         // Mix in parsed parameters with manually specified parameters.
-        $queryParams = collect($queryParams)->map->value->merge($rulesToApply['query'] ?? [])->toArray();
-        $bodyParams = collect($bodyParams)->map->value->merge($rulesToApply['body'] ?? [])->toArray();
+        $queryParams = collect($this->cleanParams($queryParams))->merge($rulesToApply['query'] ?? [])->toArray();
+        $bodyParams = collect($this->cleanParams($bodyParams))->merge($rulesToApply['body'] ?? [])->toArray();
 
         $request = $this->addQueryParameters($request, $queryParams);
         $request = $this->addBodyParameters($request, $bodyParams);

+ 37 - 0
src/Tools/Traits/ParamHelpers.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Mpociot\ApiDoc\Tools\Traits;
+
+trait ParamHelpers {
+
+    /**
+     * Create proper arrays from dot-noted parameter names
+     *
+     * @param array $params
+     * @return array
+     */
+    protected function cleanParams(array $params)
+    {
+        $values = [];
+        foreach ($params as $name => $details) {
+            $this->cleanValueFrom($name, $details['value'], $values);
+        }
+        return $values;
+    }
+
+    /**
+     * Converts dot notation names to arrays and sets the value at the right depth
+     *
+     * @param string $name
+     * @param mixed $value
+     * @param array $values The array that holds the result
+     * @return void
+     */
+    protected function cleanValueFrom($name, $value, array &$values = [])
+    {
+        if (str_contains($name, '[')) {
+            $name = str_replace(['][', '[', ']', '..'], ['.', '.', '', '.*.'], $name);
+        }
+        array_set($values, str_replace('.*', '.0', $name), $value);
+    }
+}

+ 6 - 0
tests/Fixtures/TestController.php

@@ -40,6 +40,12 @@ class TestController extends Controller
      * @bodyParam another_one number Just need something here.
      * @bodyParam yet_another_param object required
      * @bodyParam even_more_param array
+     * @bodyParam book.name string
+     * @bodyParam book.author_id integer
+     * @bodyParam book[pages_count] integer
+     * @bodyParam ids.* integer
+     * @bodyParam users.*.first_name string The first name of the user. Example: John
+     * @bodyParam users.*.last_name string The last name of the user. Example: Doe
      */
     public function withBodyParameters()
     {