178 lines
4.4 KiB
PHP
Raw Normal View History

2020-04-28 16:34:17 +08:00
<?php
2020-04-28 22:02:03 +08:00
namespace catcher\generate\factory;
2020-04-28 16:34:17 +08:00
2020-11-19 17:31:31 +08:00
use catcher\facade\FileSystem;
2021-06-10 19:38:44 +08:00
use JaguarJack\Generate\Build\Value;
use JaguarJack\Generate\Define;
use PhpParser\ParserFactory;
use JaguarJack\Generate\Generator;
2020-04-28 16:34:17 +08:00
class Route extends Factory
{
2021-06-10 19:38:44 +08:00
use HeaderDoc;
2020-04-28 16:34:17 +08:00
protected $controllerName;
protected $controller;
protected $restful;
2021-06-10 19:38:44 +08:00
protected $module;
2020-04-28 16:34:17 +08:00
protected $methods = [];
2021-06-10 19:38:44 +08:00
const VARIABLE_ST = 'scapegoat';
/**
* 实现
*
* @time 2021年06月09日
* @param array $params
* @throws \Exception
* @return mixed
*/
2021-03-14 07:41:15 +08:00
public function done(array $params = [])
2020-04-28 16:34:17 +08:00
{
2021-06-10 19:38:44 +08:00
$router = $this->getModulePath($this->controller) . DIRECTORY_SEPARATOR . 'route.php';
$content = $this->generateRoute($router);
$content = '<?php' . PHP_EOL .
2021-06-10 19:52:57 +08:00
trim(str_replace(['$scapegoat ='], [''], $content), ';') . ';';
2021-06-10 19:38:44 +08:00
if (! file_exists($router)) {
return FileSystem::put($router, $content);
}
return FileSystem::put($router, $content);
}
/**
* parse router methods
*
* @time 2021年06月09日
* @return array
* @throws \JaguarJack\Generate\Exceptions\TypeNotFoundException
*/
protected function parseRouteMethods(): array
{
$generate = new Generator();
$stmts = [];
2020-04-28 16:34:17 +08:00
if ($this->restful) {
2021-06-10 19:38:44 +08:00
$stmts[] = Define::variable(self::VARIABLE_ST, $generate->methodCall(['router', 'resource'], [
Value::fetch($this->controllerName),
Value::fetch(Define::classConstFetch($this->controller))
]), sprintf('// %s 路由', $this->controllerName));
2020-04-28 16:34:17 +08:00
}
if (!empty($this->methods)) {
foreach ($this->methods as $method) {
2021-06-10 19:38:44 +08:00
$stmts[] = Define::variable(self::VARIABLE_ST,
$generate->methodCall(['router', $method[1]], [
Value::fetch(sprintf('%s/%s', $this->controllerName, $method[0])),
Value::fetch(sprintf('%s@%s', $this->controller, $method[0]))
]));
2020-04-28 16:34:17 +08:00
}
}
2021-06-10 19:38:44 +08:00
return $stmts;
}
2020-05-05 21:52:44 +08:00
2021-06-10 19:38:44 +08:00
/**
* generate route
*
* @time 2021年06月09日
* @param string $router
* @return string
* @throws \Exception
*/
protected function generateRoute(string $router): string
{
$generate = new Generator();
2020-06-30 10:46:39 +08:00
2021-06-10 19:38:44 +08:00
if (! FileSystem::exists($router)) {
$stmts = $this->parseRouteMethods();
2020-11-19 17:31:31 +08:00
2021-06-10 19:38:44 +08:00
$expr = Define::variable(self::VARIABLE_ST, $generate->call(
$generate->methodCall(['router', 'group'], [
Value::fetch($this->module),
$generate->closure()->uses('router')->body($stmts)
]))
->call('middleware', [Value::fetch('auth')])
->call(), $this->header() . PHP_EOL . '/* @var \think\Route $router */');
2020-05-05 21:52:44 +08:00
2021-06-10 19:38:44 +08:00
return $generate->getContent([$expr]);
} else {
$factory = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
2020-04-28 16:34:17 +08:00
2021-06-10 19:38:44 +08:00
$ast = $factory->parse(file_get_contents($router));
2020-09-11 18:19:06 +08:00
2021-06-10 19:38:44 +08:00
$expression = $ast[0];
2020-09-11 18:19:06 +08:00
2021-06-10 19:52:57 +08:00
$argKey = count($expression->expr->var->args) == 1 ? 0 : 1;
$stmts = $expression->expr->var->args[$argKey]->value->stmts;
2020-09-11 18:19:06 +08:00
2021-06-10 19:38:44 +08:00
$stmts = array_merge($stmts, $this->parseRouteMethods());
2020-09-11 18:19:06 +08:00
2021-06-10 19:52:57 +08:00
$expression->expr->var->args[$argKey]->value->stmts = $stmts;
2021-06-10 19:38:44 +08:00
$ast[0] = $expression;
return $generate->getContent($ast);
2020-09-11 18:19:06 +08:00
}
}
2020-04-28 16:34:17 +08:00
/**
* set class
*
* @time 2020年04月28日
* @param $class
* @return $this
*/
2021-06-10 19:38:44 +08:00
public function controller($class): Route
2020-04-28 16:34:17 +08:00
{
$this->controller = $class;
$class = explode('\\', $class);
$this->controllerName = lcfirst(array_pop($class));
2021-06-10 19:38:44 +08:00
array_pop($class);
$this->module = array_pop($class);
2020-04-28 16:34:17 +08:00
return $this;
}
/**
* set restful
*
* @time 2020年04月28日
* @param $restful
* @return $this
*/
2021-06-10 19:38:44 +08:00
public function restful($restful): Route
2020-04-28 16:34:17 +08:00
{
$this->restful = $restful;
return $this;
}
/**
* set methods
*
* @time 2020年04月28日
* @param $methods
* @return $this
*/
2021-06-10 19:38:44 +08:00
public function methods($methods): Route
2020-04-28 16:34:17 +08:00
{
$this->methods = $methods;
return $this;
}
}