Merge remote-tracking branch 'origin/master'

This commit is contained in:
shalvah
2019-06-08 12:39:49 +02:00
8 changed files with 102 additions and 8 deletions

View File

@@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
## [3.8.0] - Wednesday, 29 May 2019
### Added
- Support for PHP array callable syntax in route action (https://github.com/mpociot/laravel-apidoc-generator/pull/516)
## [3.7.3] - Thursday, 23 May 2019
### Fixed
- Added faker_seed (https://github.com/mpociot/laravel-apidoc-generator/commit/d2901e51a68c17066d4dd96054ff5bfdf124945b)

View File

@@ -7,6 +7,7 @@ use ReflectionClass;
use ReflectionException;
use Illuminate\Routing\Route;
use Illuminate\Console\Command;
use Mpociot\ApiDoc\Tools\Utils;
use Mpociot\Reflection\DocBlock;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\URL;
@@ -217,7 +218,7 @@ class GenerateDocumentation extends Command
foreach ($routes as $routeItem) {
$route = $routeItem['route'];
/** @var Route $route */
if ($this->isValidRoute($route) && $this->isRouteVisibleForDocumentation($route->getAction()['uses'])) {
if ($this->isValidRoute($route) && $this->isRouteVisibleForDocumentation($route->getAction())) {
$parsedRoutes[] = $generator->processRoute($route, $routeItem['apply']);
$this->info('Processed route: ['.implode(',', $generator->getMethods($route)).'] '.$generator->getUri($route));
} else {
@@ -235,19 +236,24 @@ class GenerateDocumentation extends Command
*/
private function isValidRoute(Route $route)
{
return ! is_callable($route->getAction()['uses']) && ! is_null($route->getAction()['uses']);
$action = Utils::getRouteActionUses($route->getAction());
if (is_array($action)) {
$action = implode('@', $action);
}
return ! is_callable($action) && ! is_null($action);
}
/**
* @param $route
* @param $action
*
* @throws ReflectionException
*
* @return bool
*/
private function isRouteVisibleForDocumentation($route)
private function isRouteVisibleForDocumentation($action)
{
list($class, $method) = explode('@', $route);
list($class, $method) = Utils::getRouteActionUses($action);
$reflection = new ReflectionClass($class);
if (! $reflection->hasMethod($method)) {
@@ -260,7 +266,7 @@ class GenerateDocumentation extends Command
$phpdoc = new DocBlock($comment);
return collect($phpdoc->getTags())
->filter(function ($tag) use ($route) {
->filter(function ($tag) use ($action) {
return $tag->getName() === 'hideFromAPIDocumentation';
})
->isEmpty();

View File

@@ -53,8 +53,7 @@ class Generator
*/
public function processRoute(Route $route, array $rulesToApply = [])
{
$routeAction = $route->getAction();
list($class, $method) = explode('@', $routeAction['uses']);
list($class, $method) = Utils::getRouteActionUses($route->getAction());
$controller = new ReflectionClass($class);
$method = $controller->getMethod($method);

View File

@@ -14,6 +14,28 @@ class Utils
return self::replaceUrlParameterBindings($uri, $bindings);
}
/**
* @param array $action
*
* @return array|null
*/
public static function getRouteActionUses(array $action)
{
if ($action['uses'] !== null) {
if (is_array($action['uses'])) {
return $action['uses'];
} elseif (is_string($action['uses'])) {
return explode('@', $action['uses']);
}
}
if (array_key_exists(0, $action) && array_key_exists(1, $action)) {
return [
0 => $action[0],
1 => $action[1],
];
}
}
/**
* Transform parameters in URLs into real values (/users/{user} -> /users/2).
* Uses bindings specified by caller, otherwise just uses '1'.

View File

@@ -93,6 +93,35 @@ class GenerateDocumentationTest extends TestCase
$this->assertContains('Processed route: [GET] test', $output);
}
/** @test */
public function console_command_work_with_routes_uses_array()
{
RouteFacade::get('/api/array/test', [TestController::class, 'withEndpointDescription']);
config(['apidoc.routes.0.match.prefixes' => ['api/*']]);
$output = $this->artisan('apidoc:generate');
$this->assertNotContains('Skipping route: [GET] api/array/test', $output);
$this->assertContains('Processed route: [GET] api/array/test', $output);
}
/** @test */
public function console_command_work_with_dingo_routes_uses_array()
{
$api = app(\Dingo\Api\Routing\Router::class);
$api->version('v1', function ($api) {
$api->get('/array/dingo/test', [TestController::class, 'withEndpointDescription']);
});
config(['apidoc.router' => 'dingo']);
config(['apidoc.routes.0.match.prefixes' => ['*']]);
config(['apidoc.routes.0.match.versions' => ['v1']]);
$output = $this->artisan('apidoc:generate');
$this->assertNotContains('Skipping route: [GET] array/dingo/test', $output);
$this->assertContains('Processed route: [GET] array/dingo/test', $output);
}
/** @test */
public function can_skip_single_routes()
{

View File

@@ -34,4 +34,16 @@ class DingoGeneratorTest extends GeneratorTestCase
return $route;
}
public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false)
{
$route = null;
/** @var Router $api */
$api = app(Router::class);
$api->version('v1', function (Router $api) use ($controllerMethod, $path, $httpMethod, &$route) {
$route = $api->$httpMethod($path, [TestController::class, $controllerMethod]);
});
return $route;
}
}

View File

@@ -601,5 +601,18 @@ abstract class GeneratorTestCase extends TestCase
$this->assertEquals('value', $responseContent['header']);
}
/** @test */
public function can_use_arrays_in_routes_uses()
{
$route = $this->createRouteUsesArray('GET', '/api/array/test', 'withEndpointDescription');
$parsed = $this->generator->processRoute($route);
$this->assertSame('Example title.', $parsed['title']);
$this->assertSame("This will be the long description.\nIt can also be multiple lines long.", $parsed['description']);
}
abstract public function createRoute(string $httpMethod, string $path, string $controllerMethod, $register = false);
abstract public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false);
}

View File

@@ -24,4 +24,13 @@ class LaravelGeneratorTest extends GeneratorTestCase
return new Route([$httpMethod], $path, ['uses' => TestController::class."@$controllerMethod"]);
}
}
public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false)
{
if ($register) {
return RouteFacade::{$httpMethod}($path, TestController::class."@$controllerMethod");
} else {
return new Route([$httpMethod], $path, ['uses' => [TestController::class, $controllerMethod]]);
}
}
}