updae:基于AST重构代码生成

This commit is contained in:
JaguarJack 2020-11-19 17:31:31 +08:00
parent e01790aa23
commit 5713d12ce1
13 changed files with 611 additions and 271 deletions

View File

@ -8,10 +8,14 @@ use catcher\generate\factory\Migration;
use catcher\generate\factory\Model; use catcher\generate\factory\Model;
use catcher\generate\factory\Route; use catcher\generate\factory\Route;
use catcher\generate\factory\SQL; use catcher\generate\factory\SQL;
use catcher\library\Composer;
use think\facade\Db; use think\facade\Db;
class Generator class Generator
{ {
const NEED_PACKAGE = 'nikic/php-parser';
/** /**
* generate * generate
* *
@ -21,6 +25,13 @@ class Generator
*/ */
public function done($params) public function done($params)
{ {
// 判断是否安装了扩展包
if (!(new Composer)->hasPackage(self::NEED_PACKAGE)) {
throw new FailedException(
sprintf('you must use [ composer require --dev %s]', self::NEED_PACKAGE)
);
}
$params = \json_decode($params['data'], true); $params = \json_decode($params['data'], true);
[$controller, $model] = $this->parseParams($params); [$controller, $model] = $this->parseParams($params);
@ -86,7 +97,7 @@ class Generator
switch ($type) { switch ($type) {
case 'controller': case 'controller':
return (new Controller())->getContent($controller); return (new Controller())->dones();
case 'model': case 'model':
return (new Model())->getContent($model); return (new Model())->getContent($model);
default: default:

View File

@ -1,26 +1,46 @@
<?php <?php
namespace catcher\generate\build; namespace catcher\generate\build;
use catcher\CatchAdmin;
use catcher\facade\FileSystem;
use catcher\generate\build\classes\Classes; use catcher\generate\build\classes\Classes;
use PhpParser\BuilderFactory; use PhpParser\BuilderFactory;
use PhpParser\PrettyPrinter\Standard; use PhpParser\PrettyPrinter\Standard;
class PHPBuild class CatchBuild
{ {
protected $astBuilder; protected $astBuilder;
protected $outPath;
protected $filename;
public function __construct() public function __construct()
{ {
$this->astBuilder = app(BuilderFactory::class); $this->astBuilder = app(BuilderFactory::class);
} }
/**
* 命名空间
*
* @time 2020年11月19日
* @param string $namespace
* @return $this
*/
public function namespace(string $namespace) public function namespace(string $namespace)
{ {
$this->astBuilder = $this->astBuilder->namespace('god'); $this->astBuilder = $this->astBuilder->namespace($namespace);
return $this; return $this;
} }
/**
* use 方法体
*
* @time 2020年11月19日
* @param $use
* @return $this
*/
public function use($use) public function use($use)
{ {
$this->astBuilder->addStmt($use); $this->astBuilder->addStmt($use);
@ -29,21 +49,93 @@ class PHPBuild
} }
/**
* class 模版
*
* @time 2020年11月19日
* @param Classes $class
* @param \Closure $function
* @return $this
*/
public function class(Classes $class, \Closure $function) public function class(Classes $class, \Closure $function)
{ {
$function($class); $function($class);
$this->astBuilder->addStmt($class->build()); $this->astBuilder->addStmt($class->build());
return $this;
}
/**
* 条件
*
* @time 2020年11月19日
* @param $condition
* @param \Closure $closure
* @return $this
*/
public function when($condition, \Closure $closure)
{
if ($condition && $closure instanceof \Closure) {
$closure($this);
}
return $this;
}
/**
* 获取内容
*
* @time 2020年11月19日
* @return string
*/
public function getContent()
{
$stmts = array($this->astBuilder->getNode());
$prettyPrinter = new Standard();
return $prettyPrinter->prettyPrintFile($stmts);
}
/**
* 输出
*
* @time 2020年11月19日
* @return string
*/
public function output()
{
return FileSystem::put($this->outPath . $this->filename, $this->getContent());
}
/**
* 输出 Path
*
* @time 2020年11月19日
* @param $path
* @return $this
*/
public function path($path)
{
CatchAdmin::makeDirectory($path);
$this->outPath = $path;
return $this; return $this;
} }
/**
public function finish() * 设置文件名
*
* @time 2020年11月19日
* @param $name
* @return mixed
*/
public function filename($name)
{ {
$stmts = array($this->astBuilder->getNode()); $this->filename = $name;
$prettyPrinter = new Standard();
dd($prettyPrinter->prettyPrintFile($stmts)); return $this;
} }
} }

View File

@ -1,17 +1,27 @@
<?php <?php
namespace catcher\generate\classes; namespace catcher\generate\build\classes;
class Classes extends Iteration use PhpParser\BuilderFactory;
class Classes
{ {
protected $classBuild;
public function __construct(string $name)
{
$this->classBuild = (new BuilderFactory())->class($name);
}
/** /**
* 设置 comment
* *
* @time 2020年11月17日 * @time 2020年11月19
* @param $name * @param string $comment
* @return $this * @return $this
*/ */
public function name($name) public function docComment($comment="\r\n")
{ {
$this->data['name'] = $name; $this->classBuild->setDocComment($comment);
return $this; return $this;
} }
@ -23,7 +33,7 @@ class Classes extends Iteration
*/ */
public function extend($extend) public function extend($extend)
{ {
$this->data['extend'] = $extend; $this->classBuild->extend($extend);
return $this; return $this;
} }
@ -33,9 +43,9 @@ class Classes extends Iteration
* @param $interfaces * @param $interfaces
* @return $this * @return $this
*/ */
public function interfaces($interfaces) public function implement($interfaces)
{ {
$this->data['interfaces'] = $interfaces; $this->classBuild->implement($interfaces);
return $this; return $this;
} }
@ -44,9 +54,9 @@ class Classes extends Iteration
* @time 2020年11月17日 * @time 2020年11月17日
* @return $this * @return $this
*/ */
public function isAbstract() public function abstract()
{ {
$this->data['type'] = 'Abstract'; $this->classBuild->makeAbstract();
return $this; return $this;
} }
@ -55,21 +65,36 @@ class Classes extends Iteration
* @time 2020年11月17日 * @time 2020年11月17日
* @return $this * @return $this
*/ */
public function isFinal() public function final()
{ {
$this->data['type'] = 'Final'; $this->classBuild->makeFinal();
return $this; return $this;
} }
/** public function build()
* @time 2020年11月17日
* @param $type
* @param $param
* @return void
*/
public function construct($type, $param)
{ {
$this->data['construct'][] = [$type, $param]; return $this->classBuild;
}
public function addMethod(Methods $method)
{
$this->classBuild->addStmt($method->build());
return $this;
}
public function addProperty(Property $property)
{
$this->classBuild->addStmt($property->build());
return $this;
}
public function addTrait(Traits $trait)
{
$this->classBuild->addStmt($trait->build());
return $this;
} }
} }

View File

@ -1,55 +1,43 @@
<?php <?php
namespace catcher\generate\classes; namespace catcher\generate\build\classes;
class Methods extends Iteration use catcher\generate\build\traits\CatchMethodReturn;
use PhpParser\BuilderFactory;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Expression;
class Methods
{ {
protected $method = [];
/** use CatchMethodReturn;
* set method name
* protected $methodBuild;
* @time 2020年11月16日
* @param string $method public function __construct(string $name)
* @return $this
*/
public function name(string $method)
{ {
$this->method['name'] = $method; $this->methodBuild = (new BuilderFactory())->method($name);
}
public function public()
{
$this->methodBuild->makePublic();
return $this; return $this;
} }
/** public function protected()
* set visible
*
* @time 2020年11月16日
* @param string $visibility
* @return $this
*/
public function visible(string $visibility)
{ {
$this->method['visible'] = $visibility; $this->methodBuild->makeProtected();
return $this; return $this;
} }
public function makePublic() public function private()
{ {
$this->method['visible'] = 'public'; $this->methodBuild->makePrivate();
return $this;
}
public function makeProtected()
{
$this->method['visible'] = 'protected';
return $this;
}
public function makePrivate()
{
$this->method['visible'] = 'private';
return $this; return $this;
} }
@ -65,25 +53,45 @@ class Methods extends Iteration
*/ */
public function param($param, $type = null, $default = null) public function param($param, $type = null, $default = null)
{ {
$this->method['params'][] = [ $param = (new BuilderFactory())->param($param);
'type' => $type,
'param' => $param, if ($type) {
'default' => $default, $param = $param->setType($type);
]; }
if ($default) {
$param = $param->setDefault($default);
}
$this->methodBuild->addParam(
$param
);
return $this; return $this;
} }
/** /**
* 返回内容 * 定义
* *
* @time 2020年11月17日 * @time 2020年11月18日
* @param $return * @param $variable
* @param $value
* @return $this * @return $this
*/ */
public function return($return) public function declare($variable, $value)
{ {
$this->method['return'] = $return; $smt = new Expression(
new Assign(
new PropertyFetch(
new Variable('this'),
new Identifier($variable)
),
new Variable($value)
)
);
$this->methodBuild->addStmt($smt);
return $this; return $this;
} }
@ -91,12 +99,12 @@ class Methods extends Iteration
* 返回值 * 返回值
* *
* @time 2020年11月16日 * @time 2020年11月16日
* @param $return * @param $returnType
* @return $this * @return $this
*/ */
public function returnType($return) public function returnType($returnType)
{ {
$this->method['return'] = $return; $this->methodBuild->setReturnType($returnType);
return $this; return $this;
} }
@ -109,9 +117,9 @@ class Methods extends Iteration
* @param $comment * @param $comment
* @return $this * @return $this
*/ */
public function docComment($comment) public function docComment(string $comment)
{ {
$this->method['comment'] = $comment; $this->methodBuild->setDocComment($comment);
return $this; return $this;
} }
@ -124,7 +132,7 @@ class Methods extends Iteration
*/ */
public function toAbstract() public function toAbstract()
{ {
$this->method['type'] = 'Abstract'; $this->methodBuild->makeAbstract();
return $this; return $this;
} }
@ -137,23 +145,14 @@ class Methods extends Iteration
*/ */
public function toFinal() public function toFinal()
{ {
$this->method['type'] = 'Final'; $this->methodBuild->makeFinal();
return $this; return $this;
} }
/**
* join public function build()
*
* @time 2020年11月17日
* @return $this
*/
public function join()
{ {
$this->data[] = $this->method; return $this->methodBuild;
$this->method = [];
return $this;
} }
} }

View File

@ -3,7 +3,7 @@ namespace catcher\generate\build\classes;
use PhpParser\BuilderFactory; use PhpParser\BuilderFactory;
class Properties class Property
{ {
protected $propertyBuild; protected $propertyBuild;
@ -89,7 +89,7 @@ class Properties
return $this; return $this;
} }
public function build() public function build()
{ {
return $this->propertyBuild; return $this->propertyBuild;

View File

@ -1,37 +1,88 @@
<?php <?php
namespace catcher\generate\classes; namespace catcher\generate\build\classes;
class Traits extends Iteration use PhpParser\BuilderFactory;
class Traits
{ {
protected $trait = []; protected $traitBuild;
public function name($name) protected $build;
public function use(...$names)
{ {
if (!empty($this->trait)) { $this->build = new BuilderFactory;
$this->data[] = $this->trait;
$this->trait = []; $this->traitBuild = call_user_func_array([$this->build, 'useTrait'], $names);
return $this;
}
$this->trait['name'] = $name;
return $this; return $this;
} }
public function adaptation($name) public function and($name)
{ {
$this->trait['adaptation'] = $name; $this->traitBuild->and($name);
return $this;
} }
/**
* with
*
* @time 2020年11月19日
* @param \Closure|null $closure
* @return $this
*/
public function with(\Closure $closure = null)
{
if ($closure instanceof \Closure) {
$this->traitBuild->withe($closure($this));
return $this;
}
return $this;
}
/**
* @time 2020年11月19日
* @param $name
* @param null $method
* @return $this
*/
public function adaptation($name, $method = null)
{
$this->build = $this->build->traitUseAdaptation($name. $method);
return $this;
}
/**
* @time 2020年11月19日
* @param $name
* @return $this
*/
public function as($name)
{
$this->build->as($name);
return $this;
}
/**
* @time 2020年11月19日
* @param $name
* @return $this
*/
public function insteadof($name) public function insteadof($name)
{ {
$this->trait['insteadof'] = $name; $this->build->insteadof($name);
return $this;
} }
public function as($as) public function build()
{ {
$this->trait['as'] = $as; return $this->traitBuild;
} }
} }

View File

@ -1,23 +1,29 @@
<?php <?php
namespace catcher\generate\classes; namespace catcher\generate\build\classes;
use think\helper\Str; use PhpParser\BuilderFactory;
class Uses extends Iteration class Uses
{ {
protected $uses; public function name(string $name, string $as = '')
public function __construct($uses)
{ {
$delimiter = ' as '; $build = (new BuilderFactory())->use($name);
foreach ($uses as $key => $use) { if ($as) {
if (Str::contains($use, $delimiter)) { $build->as($as);
$uses[$key] = explode($delimiter, $use);
}
} }
$this->data = $uses; return $build;
}
public function function(string $function)
{
return (new BuilderFactory())->useFunction($function);
}
public function const(string $const)
{
return (new BuilderFactory())->useConst($const);
} }
} }

View File

@ -2,30 +2,129 @@
namespace catcher\generate\build\traits; namespace catcher\generate\build\traits;
class MethodReturn use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Return_;
trait CatchMethodReturn
{ {
public function index() /**
* 列表
*
* @time 2020年11月18日
* @param $model
* @return $this
*/
public function index($model)
{ {
$class = new Name('CatchResponse');
$arg = new Arg(new MethodCall(
new PropertyFetch(
new Variable('this'), new Identifier($model)
),
new Identifier('getList')
));
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'paginate', [$arg])));
return $this;
} }
public function save() /**
* 保存
*
* @time 2020年11月18日
* @param $model
* @return $this
*/
public function save($model)
{ {
$arg = new Arg(new MethodCall(
new PropertyFetch(
new Variable('this'), new Identifier($model)
),
new Identifier('storeBy'), [new Arg(new MethodCall(new Variable('request'), new Identifier('post')))]
));
$class = new Name('CatchResponse');
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
return $this;
} }
public function update() /**
* 更新
*
* @time 2020年11月18日
* @param $model
* @return $this
*/
public function update($model)
{ {
$arg = new Arg(new MethodCall(
new PropertyFetch(
new Variable('this'), new Identifier($model)
),
new Identifier('updateBy'), [
new Arg(new Variable('id')),
new Arg(new MethodCall(new Variable('request'), new Identifier('post')))
]
));
$class = new Name('CatchResponse');
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
return $this;
} }
public function read() public function read($model)
{ {
$arg = new Arg(new MethodCall(
new PropertyFetch(
new Variable('this'), new Identifier($model)
),
new Identifier('findBy'), [
new Arg(new Variable('id'))
]
));
$class = new Name('CatchResponse');
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
return $this;
} }
public function delete() /**
* 删除
*
* @time 2020年11月18日
* @param $model
* @return $this
*/
public function delete($model)
{ {
$arg = new Arg(new MethodCall(
new PropertyFetch(
new Variable('this'), new Identifier($model)
),
new Identifier('deleteBy'), [
new Arg(new Variable('id'))
]
));
$class = new Name('CatchResponse');
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
return $this;
} }
} }

View File

@ -1,20 +1,28 @@
<?php <?php
namespace catcher\generate\build\types; namespace catcher\generate\build\types;
use PhpParser\Comment\Doc;
use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Scalar\String_; use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Expr\Array_;
class Array_ class Arr
{ {
public function build($array) public function build($fields)
{ {
$items = []; $items = [];
foreach ($array as $item) { foreach ($fields as $field) {
$items[] = new ArrayItem(new String_($item)); $arrItem = new ArrayItem(new String_($field['name']));
if ($field['comment']) {
$arrItem->setDocComment(
new Doc('// ' . $field['comment'])
);
}
$items[] = $arrItem;
} }
return new \PhpParser\Node\Expr\Array_($items); return new Array_($items);
} }
} }

View File

@ -1,14 +1,35 @@
<?php <?php
namespace catcher\generate\factory; namespace catcher\generate\factory;
use catcher\CatchAdmin;
use catcher\exceptions\FailedException; use catcher\exceptions\FailedException;
use catcher\generate\template\Controller as Template; use catcher\facade\FileSystem;
use catcher\generate\build\classes\Methods;
use catcher\generate\build\CatchBuild;
use catcher\generate\build\classes\Classes;
use catcher\generate\build\classes\Property;
use catcher\generate\build\classes\Uses;
use PhpParser\BuilderFactory;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ClosureUse;
use PhpParser\PrettyPrinter\Standard;
use think\helper\Str; use think\helper\Str;
use PhpParser\Error;
use PhpParser\NodeDumper;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter;
use PhpParser\Node;
class Controller extends Factory class Controller extends Factory
{ {
protected $methods = []; protected $methods = [];
protected $uses = [
'catcher\base\CatchRequest as Request',
'catcher\CatchResponse',
'catcher\base\CatchController'
];
/** /**
* *
* @time 2020年04月27日 * @time 2020年04月27日
@ -19,8 +40,9 @@ class Controller extends Factory
{ {
// 写入成功之后 // 写入成功之后
$controllerPath = $this->getGeneratePath($params['controller']); $controllerPath = $this->getGeneratePath($params['controller']);
if (file_put_contents($controllerPath, $this->getContent($params))) {
return $controllerPath; if (FileSystem::put($controllerPath, $this->getContent($params))) {
return $controllerPath;
} }
throw new FailedException($params['controller'] . ' generate failed~'); throw new FailedException($params['controller'] . ' generate failed~');
@ -39,109 +61,136 @@ class Controller extends Factory
throw new FailedException('params has lost'); throw new FailedException('params has lost');
} }
$template = new Template();
// parse controller // parse controller
[$className, $namespace] = $this->parseFilename($params['controller']); [$className, $namespace] = $this->parseFilename($params['controller']);
[$model, $modelNamespace] = $this->parseFilename($params['model']);
$asModel = lcfirst(Str::contains($model, 'Model') ? : $model . 'Model');
if (!$className) { if (!$className) {
throw new FailedException('未填写控制器名称'); throw new FailedException('未填写控制器名称');
} }
// parse model
[$model, $modelNamespace] = $this->parseFilename($params['model']);
$use = implode(';',[ $use = new Uses();
'use ' . $params['model'] .' as '. $model . 'Model', $class = new Classes($className);
]) . ';';
$content = $template->header() . return (new CatchBuild())->namespace($namespace)
$template->nameSpace($namespace) . ->use($use->name('catcher\base\CatchRequest', 'Request'))
str_replace('{USE}', $model ? $use : '', $template->uses()) . ->use($use->name('catcher\CatchResponse'))
$template->createClass($className); ->use($use->name('catcher\base\CatchController'))
->use($use->name($modelNamespace . '\\' . ucfirst($model), $asModel))
->class($class->extend('CatchController')->docComment(), function (Classes $class) use ($asModel) {
foreach ($this->getMethods($asModel) as $method) {
$class->addMethod($method);
}
return str_replace('{CONTENT}', ($model ? $template->construct($model.'Model') : '') . rtrim($this->content($params, $template), "\r\n"), $content); $class->addProperty(
(new Property($asModel))->public()
);
})
->getContent();
} }
/** /**
* parse use * 方法集合
* *
* @time 202004月28 * @time 202011月19
* @param $params * @param $model
* @return string * @return array
*/ */
protected function parseUse($params) protected function getMethods($model)
{ {
$date = date('Y年m月d日 H:i');
}
/**
* content
*
* @time 2020年04月27日
* @param $params
* @param $template
* @return string
*/
protected function content($params, $template)
{
$content = '';
if ($params['restful']) {
$methods = $this->restful();
$this->methods = array_merge($this->methods, $methods);
foreach ($methods as $method) {
$content .= $template->{$method[0]}();
}
}
/**
if (!empty($params['other_function'])) {
$others = $this->parseOtherMethods($params['other_function']);
$this->methods = array_merge($this->methods, $others);
foreach ($others as $other) {
$content .= $template->otherFunction($other[0], $other[1]);
}
}*/
return $content;
}
/**
* parse $method
* class_method/http_method
* @time 2020年04月27日
* @param $methods
* @return false|string[]
*/
public function parseOtherMethods($methods)
{
$_methods = [];
foreach ($methods as $method) {
if (Str::contains($method, '/')) {
$_methods[] = explode('/', $method);
} else {
// 默认使用 Get 方式
$_methods[] = [$method, 'get'];
}
}
return $_methods;
}
/**
* restful 路由
*
* @time 2020年04月27日
* @return \string[][]
*/
public function restful()
{
return [ return [
['index', 'get'], (new Methods('__construct'))
['save', 'post'], ->public()
['read', 'get'], ->param($model, ucfirst($model))
['update', 'put'], ->docComment("\r\n")
['delete', 'delete'], ->declare($model, $model),
(new Methods('index'))->public()
->param('request', 'Request')
->docComment(
<<<TEXT
/**
* 列表
* @time $date
* @param Request \$request
*/
TEXT
)
->returnType('\think\Response')->index($model),
(new Methods('save'))
->public()
->param('request', 'Request')
->docComment(
<<<TEXT
/**
* 保存信息
* @time $date
* @param Request \$request
*/
TEXT
)
->returnType('\think\Response')
->save($model),
(new Methods('read'))->public()
->param('id')
->docComment(
<<<TEXT
/**
* 读取
* @time $date
* @param \$id
*/
TEXT
)
->returnType('\think\Response')->read($model),
(new Methods('update'))->public()
->param('request', 'Request')
->param('id')
->docComment(
<<<TEXT
/**
* 更新
* @time $date
* @param Request \$request
* @param \$id
*/
TEXT
)
->returnType('\think\Response')->update($model),
(new Methods('delete'))->public()
->param('id')
->docComment(
<<<TEXT
/**
* 删除
* @time $date
* @param \$id
*/
TEXT
)
->returnType('\think\Response')->delete($model),
]; ];
} }
} }

View File

@ -42,7 +42,7 @@ abstract class Factory
CatchAdmin::makeDirectory($filePath); CatchAdmin::makeDirectory($filePath);
return $filePath . DIRECTORY_SEPARATOR . $filename . '.php'; return $filePath . DIRECTORY_SEPARATOR . ucfirst($filename ). '.php';
} }
/** /**

View File

@ -2,21 +2,34 @@
namespace catcher\generate\factory; namespace catcher\generate\factory;
use catcher\exceptions\FailedException; use catcher\exceptions\FailedException;
use catcher\generate\template\Model as Template; use catcher\facade\FileSystem;
use catcher\Utils; use catcher\generate\build\CatchBuild;
use Phinx\Util\Util; use catcher\generate\build\classes\Classes;
use catcher\generate\build\classes\Property;
use catcher\generate\build\classes\Traits;
use catcher\generate\build\classes\Uses;
use catcher\generate\build\types\Arr;
use catcher\traits\db\BaseOptionsTrait;
use catcher\traits\db\ScopeTrait;
use think\facade\Db; use think\facade\Db;
use think\helper\Str; use think\helper\Str;
class Model extends Factory class Model extends Factory
{ {
/**
* done
*
* @time 2020年11月19日
* @param $params
* @return string
*/
public function done($params) public function done($params)
{ {
$content = $this->getContent($params); $content = $this->getContent($params);
$modelPath = $this->getGeneratePath($params['model']); $modelPath = $this->getGeneratePath($params['model']);
file_put_contents($modelPath, $content); FileSystem::put($modelPath, $content);
if (!file_exists($modelPath)) { if (!file_exists($modelPath)) {
throw new FailedException('create model failed'); throw new FailedException('create model failed');
@ -34,9 +47,6 @@ class Model extends Factory
*/ */
public function getContent($params) public function getContent($params)
{ {
// TODO: Implement done() method.
$template = new Template();
$extra = $params['extra']; $extra = $params['extra'];
$table = $params['table']; $table = $params['table'];
@ -53,43 +63,31 @@ class Model extends Factory
throw new FailedException('model name not set'); throw new FailedException('model name not set');
} }
$content = $template->useTrait($extra['soft_delete']) . $softDelete = $extra['soft_delete'];
$template->name(str_replace(Utils::tablePrefix(), '', $table)) .
$template->field($this->parseField($table));
$class = $template->header() . return (new CatchBuild)->namespace($namespace)
$template->nameSpace($namespace) . ->use((new Uses())->name('catcher\base\CatchModel', 'Model'))
$template->uses($extra['soft_delete']) . ->when(!$softDelete, function (CatchBuild $build){
$template->createModel($modelName, $table); $build->use((new Uses())->name(BaseOptionsTrait::class));
$build->use((new Uses())->name(ScopeTrait::class));
})
->class((new Classes($modelName))->extend('Model')->docComment(),
function (Classes $class) use ($softDelete, $table) {
if (!$softDelete) {
$class->addTrait(
(new Traits())->use('BaseOptionsTrait', 'ScopeTrait')
);
}
return str_replace('{CONTENT}', $content, $class); $class->addProperty(
} (new Property('name'))->default($table)->docComment('// 表名')
);
/** $class->addProperty(
* parse field (new Property('field'))->default(
* (new Arr)->build(Db::getFields($table))
* @time 2020年04月28日 )->docComment('// 数据库字段映射')
* @param $table );
* @return string })->getContent();
*/
protected function parseField($table)
{
if (!$this->hasTableExists($table)) {
return false;
}
$columns = Db::query('show full columns from ' . $table);
$new = [];
foreach ($columns as $field) {
$new[$field['Field']] = $field['Comment'];
}
$fields = [];
foreach ($new as $field => $comment) {
$fields[] = sprintf("'%s', // %s", $field, $comment);
}
return implode("\r\n\t\t", $fields);
} }
} }

View File

@ -1,6 +1,7 @@
<?php <?php
namespace catcher\generate\factory; namespace catcher\generate\factory;
use catcher\facade\FileSystem;
use catcher\generate\template\Content; use catcher\generate\template\Content;
class Route extends Factory class Route extends Factory
@ -34,11 +35,12 @@ class Route extends Factory
$comment = '// ' . $this->controllerName . '路由'; $comment = '// ' . $this->controllerName . '路由';
array_unshift($route, $comment); array_unshift($route, $comment);
if (file_exists($router)) { if (file_exists($router)) {
return file_put_contents($router, $this->parseRoute($router, $route)); return FileSystem::put($router, $this->parseRoute($router, $route));
} }
return file_put_contents($router, $this->header() . $comment. implode(';'. PHP_EOL , $route) . ';'); return FileSystem::put($router, $this->header() . $comment. implode(';'. PHP_EOL , $route) . ';');
} }
protected function parseRoute($path, $route) protected function parseRoute($path, $route)