mirror of
https://github.com/ambieco/scribe.git
synced 2026-04-24 02:20:05 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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'.
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user