Skip to content

Commit 0513b25

Browse files
authored
Merge pull request #516 from Zolotov88/master
add uses arrays in routes support
2 parents b7581d5 + b645183 commit 0513b25

File tree

7 files changed

+98
-8
lines changed

7 files changed

+98
-8
lines changed

src/Commands/GenerateDocumentation.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use ReflectionException;
77
use Illuminate\Routing\Route;
88
use Illuminate\Console\Command;
9+
use Mpociot\ApiDoc\Tools\Utils;
910
use Mpociot\Reflection\DocBlock;
1011
use Illuminate\Support\Collection;
1112
use Illuminate\Support\Facades\URL;
@@ -207,7 +208,7 @@ private function processRoutes(Generator $generator, array $routes)
207208
foreach ($routes as $routeItem) {
208209
$route = $routeItem['route'];
209210
/** @var Route $route */
210-
if ($this->isValidRoute($route) && $this->isRouteVisibleForDocumentation($route->getAction()['uses'])) {
211+
if ($this->isValidRoute($route) && $this->isRouteVisibleForDocumentation($route->getAction())) {
211212
$parsedRoutes[] = $generator->processRoute($route, $routeItem['apply']);
212213
$this->info('Processed route: ['.implode(',', $generator->getMethods($route)).'] '.$generator->getUri($route));
213214
} else {
@@ -225,19 +226,24 @@ private function processRoutes(Generator $generator, array $routes)
225226
*/
226227
private function isValidRoute(Route $route)
227228
{
228-
return ! is_callable($route->getAction()['uses']) && ! is_null($route->getAction()['uses']);
229+
$action = Utils::getRouteActionUses($route->getAction());
230+
if (is_array($action)) {
231+
$action = implode('@', $action);
232+
}
233+
234+
return ! is_callable($action) && ! is_null($action);
229235
}
230236

231237
/**
232-
* @param $route
238+
* @param $action
233239
*
234240
* @throws ReflectionException
235241
*
236242
* @return bool
237243
*/
238-
private function isRouteVisibleForDocumentation($route)
244+
private function isRouteVisibleForDocumentation($action)
239245
{
240-
list($class, $method) = explode('@', $route);
246+
list($class, $method) = Utils::getRouteActionUses($action);
241247
$reflection = new ReflectionClass($class);
242248

243249
if (! $reflection->hasMethod($method)) {
@@ -250,7 +256,7 @@ private function isRouteVisibleForDocumentation($route)
250256
$phpdoc = new DocBlock($comment);
251257

252258
return collect($phpdoc->getTags())
253-
->filter(function ($tag) use ($route) {
259+
->filter(function ($tag) use ($action) {
254260
return $tag->getName() === 'hideFromAPIDocumentation';
255261
})
256262
->isEmpty();

src/Tools/Generator.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ public function getMethods(Route $route)
5353
*/
5454
public function processRoute(Route $route, array $rulesToApply = [])
5555
{
56-
$routeAction = $route->getAction();
57-
list($class, $method) = explode('@', $routeAction['uses']);
56+
list($class, $method) = Utils::getRouteActionUses($route->getAction());
5857
$controller = new ReflectionClass($class);
5958
$method = $controller->getMethod($method);
6059

src/Tools/Utils.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@ public static function getFullUrl(Route $route, array $bindings = []): string
1414
return self::replaceUrlParameterBindings($uri, $bindings);
1515
}
1616

17+
/**
18+
* @param array $action
19+
*
20+
* @return array|null
21+
*/
22+
public static function getRouteActionUses(array $action)
23+
{
24+
if ($action['uses'] !== null) {
25+
if (is_array($action['uses'])) {
26+
return $action['uses'];
27+
} elseif (is_string($action['uses'])) {
28+
return explode('@', $action['uses']);
29+
}
30+
}
31+
if (array_key_exists(0, $action) && array_key_exists(1, $action)) {
32+
return [
33+
0 => $action[0],
34+
1 => $action[1],
35+
];
36+
}
37+
}
38+
1739
/**
1840
* Transform parameters in URLs into real values (/users/{user} -> /users/2).
1941
* Uses bindings specified by caller, otherwise just uses '1'.

tests/GenerateDocumentationTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,35 @@ public function console_command_does_not_work_with_closure_using_dingo()
9393
$this->assertContains('Processed route: [GET] test', $output);
9494
}
9595

96+
/** @test */
97+
public function console_command_work_with_routes_uses_array()
98+
{
99+
RouteFacade::get('/api/array/test', [TestController::class, 'withEndpointDescription']);
100+
101+
config(['apidoc.routes.0.match.prefixes' => ['api/*']]);
102+
$output = $this->artisan('apidoc:generate');
103+
104+
$this->assertNotContains('Skipping route: [GET] api/array/test', $output);
105+
$this->assertContains('Processed route: [GET] api/array/test', $output);
106+
}
107+
108+
/** @test */
109+
public function console_command_work_with_dingo_routes_uses_array()
110+
{
111+
$api = app(\Dingo\Api\Routing\Router::class);
112+
$api->version('v1', function ($api) {
113+
$api->get('/array/dingo/test', [TestController::class, 'withEndpointDescription']);
114+
});
115+
116+
config(['apidoc.router' => 'dingo']);
117+
config(['apidoc.routes.0.match.prefixes' => ['*']]);
118+
config(['apidoc.routes.0.match.versions' => ['v1']]);
119+
$output = $this->artisan('apidoc:generate');
120+
121+
$this->assertNotContains('Skipping route: [GET] array/dingo/test', $output);
122+
$this->assertContains('Processed route: [GET] array/dingo/test', $output);
123+
}
124+
96125
/** @test */
97126
public function can_skip_single_routes()
98127
{

tests/Unit/DingoGeneratorTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,16 @@ public function createRoute(string $httpMethod, string $path, string $controller
3434

3535
return $route;
3636
}
37+
38+
public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false)
39+
{
40+
$route = null;
41+
/** @var Router $api */
42+
$api = app(Router::class);
43+
$api->version('v1', function (Router $api) use ($controllerMethod, $path, $httpMethod, &$route) {
44+
$route = $api->$httpMethod($path, [TestController::class, $controllerMethod]);
45+
});
46+
47+
return $route;
48+
}
3749
}

tests/Unit/GeneratorTestCase.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,5 +600,18 @@ public function uses_configured_settings_when_calling_route()
600600
$this->assertEquals('value', $responseContent['header']);
601601
}
602602

603+
/** @test */
604+
public function can_use_arrays_in_routes_uses()
605+
{
606+
$route = $this->createRouteUsesArray('GET', '/api/array/test', 'withEndpointDescription');
607+
608+
$parsed = $this->generator->processRoute($route);
609+
610+
$this->assertSame('Example title.', $parsed['title']);
611+
$this->assertSame("This will be the long description.\nIt can also be multiple lines long.", $parsed['description']);
612+
}
613+
603614
abstract public function createRoute(string $httpMethod, string $path, string $controllerMethod, $register = false);
615+
616+
abstract public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false);
604617
}

tests/Unit/LaravelGeneratorTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,13 @@ public function createRoute(string $httpMethod, string $path, string $controller
2424
return new Route([$httpMethod], $path, ['uses' => TestController::class."@$controllerMethod"]);
2525
}
2626
}
27+
28+
public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false)
29+
{
30+
if ($register) {
31+
return RouteFacade::{$httpMethod}($path, TestController::class."@$controllerMethod");
32+
} else {
33+
return new Route([$httpMethod], $path, ['uses' => [TestController::class, $controllerMethod]]);
34+
}
35+
}
2736
}

0 commit comments

Comments
 (0)