Files
kiri-core/Gii/GiiController.php
T

540 lines
14 KiB
PHP
Raw Normal View History

2020-09-07 17:12:46 +08:00
<?php
2020-10-30 01:07:28 +08:00
declare(strict_types=1);
2020-09-07 17:12:46 +08:00
2020-09-08 15:59:15 +08:00
namespace Gii;
2020-09-07 17:12:46 +08:00
2020-12-17 14:09:14 +08:00
use Exception;
2021-04-01 15:57:15 +08:00
use ReflectionException;
2020-09-07 17:12:46 +08:00
use Snowflake\Snowflake;
/**
* Class GiiController
2020-09-08 15:59:15 +08:00
* @package Gii
2020-09-07 17:12:46 +08:00
*/
class GiiController extends GiiBase
{
2020-12-17 14:09:14 +08:00
public string $className = '';
2020-09-07 17:12:46 +08:00
2020-12-17 14:09:14 +08:00
public array $fields = [];
2020-09-07 17:12:46 +08:00
2021-04-01 15:57:15 +08:00
/**
* GiiController constructor.
* @param $className
* @param $fields
*/
2020-09-07 17:12:46 +08:00
public function __construct($className, $fields)
{
$this->className = $className;
$this->fields = $fields;
}
/**
2021-03-25 18:30:22 +08:00
* @return string|bool
2021-04-01 15:57:15 +08:00
* @throws ReflectionException
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-03-25 18:30:22 +08:00
public function generate(): string|bool
2020-09-07 17:12:46 +08:00
{
$path = $this->getControllerPath();
$modelPath = $this->getModelPath();
$managerName = $this->className;
$namespace = rtrim($path['namespace'], '\\');
$model_namespace = rtrim($modelPath['namespace'], '\\');
$prefix = str_replace('_', '', $this->db->tablePrefix);
$managerName = str_replace(ucfirst($prefix), '', $managerName);
$class = '';
2021-03-25 19:57:01 +08:00
$controller = str_replace('\\\\', '\\', "$namespace\\{$managerName}Controller");
2020-09-07 17:12:46 +08:00
2021-03-25 19:45:47 +08:00
$html = "<?php
2020-09-07 17:12:46 +08:00
namespace {$namespace};
2021-03-25 19:45:47 +08:00
";
2021-03-25 18:28:41 +08:00
if (file_exists($path['path'] . '/' . $managerName . 'Controller.php')) {
2021-03-25 18:30:22 +08:00
try {
$class = new \ReflectionClass($controller);
$import = $this->getImports($path['path'] . '/' . $managerName . 'Controller.php', $class);
2021-03-25 19:55:19 +08:00
} catch (\Throwable $Exception) {
2021-03-30 11:56:29 +08:00
exit(logger()->addError($Exception, 'throwable'));
2021-03-25 18:30:22 +08:00
}
} else {
2021-03-25 18:28:41 +08:00
$import = "use Snowflake;
2021-03-25 19:55:19 +08:00
use Exception;
2021-03-02 18:04:57 +08:00
use Annotation\Target;
2021-04-06 18:42:21 +08:00
use Annotation\Route\Middleware;
use Annotation\Route\Route;
2020-09-07 17:12:46 +08:00
use Snowflake\Core\Str;
2021-04-27 19:05:17 +08:00
use Snowflake\Core\Json;
2020-09-08 18:55:45 +08:00
use HttpServer\Http\Request;
use HttpServer\Http\Response;
use HttpServer\Controller;
2021-04-06 18:24:51 +08:00
use JetBrains\PhpStorm\ArrayShape;
2020-09-07 17:12:46 +08:00
use {$model_namespace}\\{$managerName};
";
}
2021-03-25 18:28:41 +08:00
if (!empty($import)) {
$html .= $import;
}
$controllerName = $managerName;
2020-09-07 17:12:46 +08:00
$historyModel = "use {$model_namespace}\\{$managerName};";
2020-12-17 14:09:14 +08:00
if (!str_contains($html, $historyModel)) {
2020-09-07 17:12:46 +08:00
$html .= $historyModel;
}
$html .= "
/**
* Class {$controllerName}Controller
*
* @package controller
*/
2021-03-02 18:04:57 +08:00
#[Target] class {$controllerName}Controller extends Controller
2020-09-07 17:12:46 +08:00
{
";
2021-03-25 19:57:01 +08:00
2020-09-07 17:12:46 +08:00
$funcNames = [];
if (is_object($class)) {
2021-03-25 18:28:41 +08:00
$html .= $this->getClassProperty($class);
2021-03-25 19:58:56 +08:00
$html .= $this->getClassMethods($class);
2020-09-07 17:12:46 +08:00
}
2021-03-25 19:58:56 +08:00
$default = ['loadParam', 'actionAdd', 'actionUpdate', 'actionDetail', 'actionDelete', 'actionBatchDelete', 'actionList'];
foreach ($default as $key => $val) {
2021-03-25 19:59:40 +08:00
if (str_contains($html, ' function ' . $val . '(')) {
2021-03-25 19:58:56 +08:00
continue;
2020-09-07 17:12:46 +08:00
}
2021-04-06 18:48:46 +08:00
$html .= $this->{'controllerMethod' . str_replace('action', '', $val)}($this->fields, $managerName, $managerName, $path) . "\n";
2020-09-07 17:12:46 +08:00
}
$html .= '
}';
$file = $path['path'] . '/' . $controllerName . 'Controller.php';
if (file_exists($file)) {
unlink($file);
}
Snowflake::writeFile($file, $html);
return $controllerName . 'Controller.php';
}
/**
* @return array
*/
2020-12-17 14:09:14 +08:00
private function getControllerPath(): array
2020-09-07 17:12:46 +08:00
{
$dbName = $this->db->id;
if (empty($dbName) || $dbName == 'db') {
$dbName = '';
}
$module = empty($this->module) ? '' : $this->module;
$modelPath['namespace'] = $this->controllerNamespace . $module;
$modelPath['path'] = $this->controllerPath . $module;
if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']);
}
if (!empty($dbName)) {
$modelPath['namespace'] = $this->controllerNamespace . ucfirst($dbName);
$modelPath['path'] = $this->controllerPath . ucfirst($dbName);
}
$modelPath['namespace'] = rtrim($modelPath['namespace'], '\\');
$modelPath['path'] = rtrim($modelPath['path'], '\\');
if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']);
}
return $modelPath;
}
/**
* @param $fields
* @param $className
* @param null $object
2021-04-06 18:48:46 +08:00
* @param $path
2020-09-07 17:12:46 +08:00
* @return string
* 新增
*/
2021-04-06 18:48:46 +08:00
public function controllerMethodAdd($fields, $className, $object, $path): string
2020-09-07 17:12:46 +08:00
{
2021-04-06 18:48:46 +08:00
$_path = str_replace(CONTROLLER_PATH, '', $path['path']);
2021-04-06 18:52:34 +08:00
$_path = lcfirst(rtrim($_path, '/')) . '/' . lcfirst($className);
2021-04-07 10:16:16 +08:00
$_path = ltrim($_path,'/');
2020-09-07 17:12:46 +08:00
return '
/**
2021-03-25 19:56:08 +08:00
* @return string
2021-03-25 19:55:19 +08:00
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-04-06 18:48:46 +08:00
#[Route(uri: "' . $_path . '/add", method: "POST")]
2021-04-06 18:42:21 +08:00
#[Middleware(middleware: [])]
2021-03-25 19:56:08 +08:00
public function actionAdd(): string
2020-09-07 17:12:46 +08:00
{
$model = new ' . $className . '();
$model->attributes = $this->loadParam();
if (!$model->save()) {
return JSON::to(500, $model->getLastError());
}
2020-09-08 18:55:45 +08:00
return JSON::to(0, $model->toArray());
2020-09-07 17:12:46 +08:00
}';
}
/**
* @param $fields
* @param $className
* @param null $object
* @return string
* 通用
*/
2020-12-17 14:09:14 +08:00
public function controllerMethodLoadParam($fields, $className, $object = NULL): string
2020-09-07 17:12:46 +08:00
{
return '
/**
* @return array
* @throws Exception
*/
2021-04-06 18:23:40 +08:00
#[ArrayShape([])]
2021-03-25 19:55:19 +08:00
private function loadParam(): array
2020-09-07 17:12:46 +08:00
{
return [' . $this->getData($fields) . '
];
}';
}
/**
* @param $fields
* @param $className
* @param null $object
2021-04-06 18:48:46 +08:00
* @param array $path
2020-09-07 17:12:46 +08:00
* @return string
* 构建更新
*/
2021-04-06 18:48:46 +08:00
public function controllerMethodUpdate($fields, $className, $object = NULL, $path = []): string
2020-09-07 17:12:46 +08:00
{
2021-04-06 18:48:46 +08:00
$_path = str_replace(CONTROLLER_PATH, '', $path['path']);
2021-04-06 18:52:34 +08:00
$_path = lcfirst(rtrim($_path, '/')) . '/' . lcfirst($className);
2021-04-06 18:48:46 +08:00
2021-04-07 10:16:16 +08:00
$_path = ltrim($_path,'/');
2020-09-07 17:12:46 +08:00
return '
/**
2021-03-25 19:55:19 +08:00
* @return string
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-04-06 18:48:46 +08:00
#[Route(uri: "' . $_path . '/update", method: "POST")]
2021-04-06 18:42:21 +08:00
#[Middleware(middleware: [])]
2021-03-25 19:55:19 +08:00
public function actionUpdate(): string
2020-09-07 17:12:46 +08:00
{
2021-03-25 19:44:27 +08:00
$model = ' . $className . '::findOne($this->input->post(\'id\', 0));
2020-09-07 17:12:46 +08:00
if (empty($model)) {
2020-09-25 15:37:33 +08:00
return JSON::to(500, SELECT_IS_NULL);
2020-09-07 17:12:46 +08:00
}
$model->attributes = $this->loadParam();
if (!$model->save()) {
return JSON::to(500, $model->getLastError());
}
2020-09-08 18:55:45 +08:00
return JSON::to(0, $model->toArray());
2020-09-07 17:12:46 +08:00
}';
}
/**
* @param $fields
* @param $className
* @param null $object
2021-04-06 18:48:46 +08:00
* @param array $path
2020-09-07 17:12:46 +08:00
* @return string
* 构建更新
*/
2021-04-06 18:48:46 +08:00
public function controllerMethodBatchDelete($fields, $className, $object = NULL, $path = []): string
2020-09-07 17:12:46 +08:00
{
2021-04-06 18:48:46 +08:00
$_path = str_replace(CONTROLLER_PATH, '', $path['path']);
2021-04-06 18:52:34 +08:00
$_path = lcfirst(rtrim($_path, '/')) . '/' . lcfirst($className);
2021-04-06 18:48:46 +08:00
2021-04-07 10:16:16 +08:00
$_path = ltrim($_path,'/');
2020-09-07 17:12:46 +08:00
return '
/**
2021-03-25 19:55:19 +08:00
* @return string
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-04-06 18:48:46 +08:00
#[Route(uri: "' . $_path . '/batch-delete", method: "POST")]
2021-04-06 18:42:21 +08:00
#[Middleware(middleware: [])]
2021-03-25 19:55:19 +08:00
public function actionBatchDelete(): string
2020-09-07 17:12:46 +08:00
{
2021-03-25 19:55:19 +08:00
$_key = $this->input->array(\'ids\');
2020-09-07 17:12:46 +08:00
if (empty($_key)) {
2020-09-25 15:37:33 +08:00
return JSON::to(500, PARAMS_IS_NULL);
2020-09-07 17:12:46 +08:00
}
$model = ' . $className . '::find()->in(\'id\', $_key);
2021-04-07 10:24:43 +08:00
if (!$model->delete()) {
2020-09-25 15:37:33 +08:00
return JSON::to(500, DB_ERROR_BUSY);
2020-09-07 17:12:46 +08:00
}
2021-04-07 10:24:43 +08:00
return JSON::to(0, $_key);
2020-09-07 17:12:46 +08:00
}';
}
/**
* @param $fields
* @param $className
* @param $managerName
2021-04-06 18:48:46 +08:00
* @param array $path
2020-09-07 17:12:46 +08:00
* @return string
* 构建详情
*/
2021-04-06 18:48:46 +08:00
public function controllerMethodDetail($fields, $className, $managerName, $path = []): string
2020-09-07 17:12:46 +08:00
{
2021-04-06 18:48:46 +08:00
$_path = str_replace(CONTROLLER_PATH, '', $path['path']);
2021-04-06 18:52:34 +08:00
$_path = lcfirst(rtrim($_path, '/')) . '/' . lcfirst($className);
2021-04-06 18:48:46 +08:00
2021-04-07 10:16:16 +08:00
$_path = ltrim($_path,'/');
2020-09-07 17:12:46 +08:00
return '
/**
2021-03-25 19:55:19 +08:00
* @return string
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-04-06 18:48:46 +08:00
#[Route(uri: "' . $_path . '/detail", method: "POST")]
2021-04-06 18:42:21 +08:00
#[Middleware(middleware: [])]
2021-03-25 19:55:19 +08:00
public function actionDetail(): string
2020-09-07 17:12:46 +08:00
{
2021-03-25 19:44:27 +08:00
$model = ' . $managerName . '::findOne($this->input->get(\'id\'));
2021-04-07 10:24:43 +08:00
if (empty($model)) {
2020-09-25 15:37:33 +08:00
return JSON::to(404, SELECT_IS_NULL);
2020-09-07 17:12:46 +08:00
}
2020-09-08 18:55:45 +08:00
return JSON::to(0, $model->toArray());
2020-09-07 17:12:46 +08:00
}';
}
/**
* @param $fields
* @param $className
* @param $managerName
2021-04-06 18:48:46 +08:00
* @param $path
2020-09-07 17:12:46 +08:00
* @return string
* 构建删除操作
*/
2021-04-06 18:48:46 +08:00
public function controllerMethodDelete($fields, $className, $managerName, $path): string
2020-09-07 17:12:46 +08:00
{
2021-04-06 18:48:46 +08:00
$_path = str_replace(CONTROLLER_PATH, '', $path['path']);
2021-04-06 18:52:34 +08:00
$_path = lcfirst(rtrim($_path, '/')) . '/' . lcfirst($className);
2021-04-06 18:48:46 +08:00
2021-04-07 10:16:16 +08:00
$_path = ltrim($_path,'/');
2020-09-07 17:12:46 +08:00
return '
/**
2021-03-25 19:55:19 +08:00
* @return string
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-04-06 18:48:46 +08:00
#[Route(uri: "' . $_path . '/delete", method: "POST")]
2021-04-06 18:42:21 +08:00
#[Middleware(middleware: [])]
2021-03-25 19:55:19 +08:00
public function actionDelete(): string
2020-09-07 17:12:46 +08:00
{
2021-03-25 19:44:27 +08:00
$_key = $this->input->int(\'id\', true);
2020-09-07 17:12:46 +08:00
$model = ' . $managerName . '::findOne($_key);
if (empty($model)) {
2020-09-25 15:37:33 +08:00
return JSON::to(500, SELECT_IS_NULL);
2020-09-07 17:12:46 +08:00
}
2021-04-07 10:24:43 +08:00
if (!$model->delete()) {
2020-09-07 17:12:46 +08:00
return JSON::to(500, $model->getLastError());
}
2020-09-08 18:55:45 +08:00
return JSON::to(0, $model);
2020-09-07 17:12:46 +08:00
}';
}
/**
* @param $fields
* @param $className
* @param $managerName
2021-04-06 18:48:46 +08:00
* @param array $path
2020-09-07 17:12:46 +08:00
* @return string
* 构建查询列表
*/
2021-04-06 18:48:46 +08:00
public function controllerMethodList($fields, $className, $managerName, $path = []): string
2020-09-07 17:12:46 +08:00
{
2021-04-06 18:48:46 +08:00
$_path = str_replace(CONTROLLER_PATH, '', $path['path']);
2021-04-06 18:52:34 +08:00
$_path = lcfirst(rtrim($_path, '/')) . '/' . lcfirst($className);
2021-04-06 18:48:46 +08:00
2021-04-07 10:16:16 +08:00
$_path = ltrim($_path,'/');
2020-09-07 17:12:46 +08:00
return '
/**
2021-03-25 19:55:19 +08:00
* @return string
* @throws Exception
2020-09-07 17:12:46 +08:00
*/
2021-04-06 18:48:46 +08:00
#[Route(uri: "' . $_path . '/list", method: "POST")]
2021-04-06 18:42:21 +08:00
#[Middleware(middleware: [])]
2021-03-25 19:55:19 +08:00
public function actionList(): string
2021-04-06 18:38:29 +08:00
{
2020-09-07 17:12:46 +08:00
//分页处理
2021-03-25 19:44:27 +08:00
$count = $this->input->get(\'count\', -1);
$order = $this->input->get(\'order\', \'id\');
2021-04-07 10:24:43 +08:00
if (!empty($order)) {
2021-03-25 19:44:27 +08:00
$order .= !$this->input->get(\'isDesc\', 0) ? \' asc\' : \' desc\';
2021-04-07 10:24:43 +08:00
} else {
2020-09-07 17:12:46 +08:00
$order = \'id desc\';
}
2021-04-12 16:15:44 +08:00
2020-09-07 17:12:46 +08:00
//列表输出
2021-04-06 18:38:29 +08:00
$model = ' . $managerName . '::find()->where($this->input->gets())->orderBy($order);
2021-04-12 16:15:44 +08:00
$keyword = $this->input->get(\'keyword\', null);
if (!empty($keyword)) {
$model->like(\'keyword\', $keyword);
}
2021-04-07 10:24:43 +08:00
if ((int) $count === 1) {
2020-09-07 17:12:46 +08:00
$count = $model->count();
}
2021-04-07 10:24:43 +08:00
if ($count != -100) {
2021-03-25 19:44:27 +08:00
$model->limit($this->input->offset() ,$this->input->size());
2020-09-07 17:12:46 +08:00
}
$data = $model->all()->toArray();
2020-09-08 18:55:45 +08:00
return JSON::to(0, $data, $count);
2020-09-07 17:12:46 +08:00
}
';
}
2020-12-17 14:09:14 +08:00
private function getData($fields): string
2020-09-07 17:12:46 +08:00
{
$html = '';
$length = $this->getMaxLength($fields);
foreach ($fields as $key => $val) {
preg_match('/\((\d+)(,(\d+))*\)/', $val['Type'], $number);
$type = strtolower(preg_replace('/\(\d+(,\d+)*\)/', '', $val['Type']));
$first = preg_replace('/\s+\w+/', '', $type);
if ($val['Field'] == 'id') continue;
if ($type == 'timestamp') continue;
$_field = [];
$_field['required'] = $this->checkIsRequired($val);
foreach ($this->type as $_key => $value) {
if (!in_array(strtolower($first), $value)) continue;
$comment = '//' . $val['Comment'];
$_field['type'] = $_key;
if ($type == 'date' || $type == 'datetime' || $type == 'time') {
2021-04-01 15:57:15 +08:00
$_tps = match ($type) {
'date' => '$this->input->' . $_key . '(\'' . $val['Field'] . '\', date(\'Y-m-d\'))',
'time' => '$this->input->' . $_key . '(\'' . $val['Field'] . '\', date(\'H:i:s\'))',
default => '$this->input->' . $_key . '(\'' . $val['Field'] . '\', date(\'Y-m-d H:i:s\'))',
};
2020-09-07 17:12:46 +08:00
$html .= '
\'' . str_pad($val['Field'] . '\'', $length, ' ', STR_PAD_RIGHT) . ' => ' . str_pad($_tps . ',', 60, ' ', STR_PAD_RIGHT) . $comment;
} else {
$tmp = 'null';
if (isset($number[0])) {
if (strpos(',', $number[0])) {
$tmp = '[' . $number[1] . ',' . $number[3] . ']';
$_field['min'] = $number[1];
$_field['max'] = $number[3];
} else {
$tmp = '[0,' . $number[1] . ']';
$_field['min'] = 0;
$_field['max'] = $number[1];
}
}
if ($key == 'string') {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ', ' . $tmp . ')';
2020-09-07 17:12:46 +08:00
} else if ($type == 'int') {
if ($number[0] == 10) {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', time())';
2020-09-07 17:12:46 +08:00
} else {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ')';
2020-09-07 17:12:46 +08:00
}
} else if ($type == 'float') {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ', ' . ($number[3] ?? '2') . ')';
2020-09-07 17:12:46 +08:00
} else if ($key == 'email') {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ')';
2020-09-07 17:12:46 +08:00
} else if ($key == 'timestamp') {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', time())';
2020-09-07 17:12:46 +08:00
} else {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ')';
2020-09-07 17:12:46 +08:00
}
$html .= '
\'' . str_pad($val['Field'] . '\'', $length, ' ', STR_PAD_RIGHT) . ' => ' . str_pad($_tps . ',', 60, ' ', STR_PAD_RIGHT) . $comment;
}
}
$this->rules[$val['Field']] = $_field;
}
return $html;
}
2020-12-17 14:09:14 +08:00
/**
* @param $fields
* @return int
*/
private function getMaxLength($fields): int
2020-09-07 17:12:46 +08:00
{
$length = 0;
foreach ($fields as $key => $val) {
if (mb_strlen($val['Field'] . ' >=') > $length) $length = mb_strlen($val['Field'] . ' >=');
}
return $length;
}
2020-12-17 14:09:14 +08:00
/**
* @param $fields
* @return string
*/
private function getWhere($fields): string
2020-09-07 17:12:46 +08:00
{
$html = '';
$length = $this->getMaxLength($fields);
foreach ($fields as $key => $val) {
preg_match('/\d+/', $val['Type'], $number);
$type = strtolower(preg_replace('/\(\d+\)/', '', $val['Type']));
$first = preg_replace('/\s+\w+/', '', $type);
if ($type == 'timestamp') continue;
if ($type == 'json') continue;
foreach ($this->type as $_key => $value) {
if (!in_array(strtolower($first), $value)) continue;
$comment = '//' . $val['Comment'];
if ($type == 'date' || $type == 'datetime' || $type == 'time') {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->get(\'' . $val['Field'] . '\', null)';
2020-09-07 17:12:46 +08:00
$html .= '
$pWhere[\'' . str_pad($val['Field'] . ' <=\']', $length, ' ', STR_PAD_RIGHT) . ' = ' . str_pad($_tps . ';', 60, ' ', STR_PAD_RIGHT) . $comment;
$html .= '
$pWhere[\'' . str_pad($val['Field'] . ' >=\']', $length, ' ', STR_PAD_RIGHT) . ' = ' . str_pad($_tps . ';', 60, ' ', STR_PAD_RIGHT) . $comment;
} else {
2021-03-25 19:44:27 +08:00
$_tps = '$this->input->get(\'' . $val['Field'] . '\', null)';
2020-09-07 17:12:46 +08:00
$html .= '
$pWhere[\'' . str_pad($val['Field'] . '\']', $length, ' ', STR_PAD_RIGHT) . ' = ' . str_pad($_tps . ';', 60, ' ', STR_PAD_RIGHT) . $comment;
}
}
}
return $html;
}
}