|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Lackoxygen\ShowDocGeneration\Parser;
|
|
|
|
|
|
|
|
use Illuminate\Foundation\Application;
|
|
|
|
use Illuminate\Routing\Route;
|
|
|
|
use Illuminate\Routing\RouteCollection;
|
|
|
|
use Illuminate\Routing\Router;
|
|
|
|
use Illuminate\Support\Collection;
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Annotation;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Catalog;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\HeaderLine;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Method;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\ParamLine;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Remark;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Resp;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\RespLine;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Title;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Annotations\Url;
|
|
|
|
use Lackoxygen\ShowDocGeneration\Logger;
|
|
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|
|
|
|
|
|
|
class Paster
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected array $annotations = [
|
|
|
|
Catalog::class,
|
|
|
|
Title::class,
|
|
|
|
Url::class,
|
|
|
|
Method::class,
|
|
|
|
HeaderLine::class,
|
|
|
|
ParamLine::class,
|
|
|
|
Resp::class,
|
|
|
|
RespLine::class,
|
|
|
|
Remark::class
|
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Application
|
|
|
|
*/
|
|
|
|
protected Application $application;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected string $prefix;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Collection|array
|
|
|
|
*/
|
|
|
|
protected Collection $docsCollect;
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$this->docsCollect = collect();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Application $application
|
|
|
|
* @param string|null $prefix
|
|
|
|
* @return array|Collection
|
|
|
|
*/
|
|
|
|
public static function resolve(Application $application, string $prefix = null)
|
|
|
|
{
|
|
|
|
$static = new static();
|
|
|
|
$static->application = $application;
|
|
|
|
$static->prefix = $prefix;
|
|
|
|
try {
|
|
|
|
$routes = $static->getRoutes();
|
|
|
|
|
|
|
|
$static->eachRoutes($routes, function (self $self, Route $route) {
|
|
|
|
Logger::writeln('load ' . join('|', $route->methods()) . ' ' . $route->uri());
|
|
|
|
try {
|
|
|
|
$doc = $self->resolveAnnotation($route);
|
|
|
|
$doc->middles = $route->middleware();
|
|
|
|
$self->docsCollect->push($doc);
|
|
|
|
} catch (\ReflectionException $e) {
|
|
|
|
Logger::writeln('error ' . $e->getMessage());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
|
|
|
|
Logger::writeln('error ' . $e->getMessage());
|
|
|
|
}
|
|
|
|
|
|
|
|
return $static->docsCollect;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param RouteCollection $routes
|
|
|
|
* @param $callback
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function eachRoutes(RouteCollection $routes, $callback)
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var Route $route
|
|
|
|
*/
|
|
|
|
foreach ($routes as $route) {
|
|
|
|
if ($this->isMatch($route)) {
|
|
|
|
$callback($this, $route);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Route $route
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
protected function isMatch(Route $route): bool
|
|
|
|
{
|
|
|
|
if ($this->prefix && $prefixArray = explode(',', $this->prefix)) {
|
|
|
|
if (!in_array($route->getPrefix(), $prefixArray)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$action = $route->getAction();
|
|
|
|
|
|
|
|
if (!isset($action['controller'])) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Route $route
|
|
|
|
* @return Doc
|
|
|
|
* @throws \ReflectionException
|
|
|
|
*/
|
|
|
|
protected function resolveAnnotation(Route $route): Doc
|
|
|
|
{
|
|
|
|
Logger::writeln('parse ' . join('|', $route->methods()) . ' ' . $route->uri() . ' Annotation');
|
|
|
|
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
|
|
|
|
|
|
|
|
$refClass = new \ReflectionClass(($route->getController()));
|
|
|
|
$method = $refClass->getMethod($route->getActionMethod());
|
|
|
|
|
|
|
|
$doc = new Doc();
|
|
|
|
|
|
|
|
foreach ($this->annotations as $annot) {
|
|
|
|
|
|
|
|
Logger::writeln('parse ' . join('|', $route->methods()) . ' ' . $route->uri() . ' method annotation ' . $annot);
|
|
|
|
|
|
|
|
$annotation = $reader->getMethodAnnotation($method, $annot);
|
|
|
|
|
|
|
|
$pro = Str::camel(class_basename($annot));
|
|
|
|
|
|
|
|
if (!$annotation instanceof Annotation) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Str::endsWith($annot, 'Line')) {
|
|
|
|
$doc->{$pro}[] = $annotation->toArray();
|
|
|
|
} else {
|
|
|
|
$doc->{$pro} = $annotation->toArray();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $doc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return \Illuminate\Routing\RouteCollectionInterface|RouteCollection
|
|
|
|
* @throws ContainerExceptionInterface
|
|
|
|
* @throws NotFoundExceptionInterface
|
|
|
|
*/
|
|
|
|
protected function getRoutes()
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var Router $router
|
|
|
|
*/
|
|
|
|
$router = $this->application->get('router');
|
|
|
|
|
|
|
|
return $router->getRoutes();
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|