e
This commit is contained in:
+342
-342
@@ -1,342 +1,342 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: 向林
|
||||
* Date: 2016/8/9 0009
|
||||
* Time: 17:43
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Gii;
|
||||
|
||||
use Database\Connection;
|
||||
use Database\Db;
|
||||
use Exception;
|
||||
use Kiri\Cache\Redis;
|
||||
use Kiri\Kiri;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
/**
|
||||
* Class gii
|
||||
*
|
||||
* @package Inter\utility
|
||||
*/
|
||||
class Gii
|
||||
{
|
||||
private ?string $tableName = NULL;
|
||||
|
||||
/** @var null|Connection */
|
||||
private ?Connection $db;
|
||||
|
||||
private InputInterface $input;
|
||||
|
||||
public string $modelPath = APP_PATH . 'app/Model/';
|
||||
public string $modelNamespace = 'App\\Model\\';
|
||||
|
||||
public string $controllerPath = APP_PATH . 'app/Http/Controller/';
|
||||
public string $controllerNamespace = 'App\\Controller\\';
|
||||
|
||||
|
||||
public static array $createSqls = [];
|
||||
|
||||
|
||||
public array $keyword = [
|
||||
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Connection|null $db
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function run(?Connection $db, InputInterface $input): array
|
||||
{
|
||||
return $this->gen($input, $db);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param $db
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function gen(InputInterface $input, $db): array
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->db = $db;
|
||||
|
||||
$make = $this->input->getOption('make');
|
||||
if (empty($make)) {
|
||||
throw new Exception('构建类型不能为空~');
|
||||
}
|
||||
switch (strtolower($make)) {
|
||||
case 'task':
|
||||
$task = new GiiTask();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'middleware':
|
||||
$task = new GiiMiddleware();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'rpc-client':
|
||||
$task = new GiiRpcClient();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'rpc-service':
|
||||
$task = new GiiRpcService();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'json-rpc':
|
||||
$task = new GiiJsonRpc();
|
||||
$task->setInput($this->input);
|
||||
return $task->create();
|
||||
default:
|
||||
return $this->getModel($make, $input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $make
|
||||
* @param $input
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getModel($make, $input): array
|
||||
{
|
||||
return $this->makeByDatabases($make, $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $make
|
||||
* @param InputInterface $input
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function makeByDatabases($make, InputInterface $input): array
|
||||
{
|
||||
if ($input->hasOption('name')) {
|
||||
$this->tableName = $input->getOption('name');
|
||||
}
|
||||
return match ($make) {
|
||||
'controller' => $this->getTable(1, 0),
|
||||
'model' => $this->getTable(0, 1),
|
||||
default => [],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $controller
|
||||
* @param $model
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getTable($controller, $model): array
|
||||
{
|
||||
$tables = $this->getFields($this->getTables());
|
||||
if (empty($tables)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$fileList = [];
|
||||
foreach ($tables as $key => $val) {
|
||||
$data = $this->createModelFile($key, $val);
|
||||
if ($controller == 1) {
|
||||
$fileList[] = $this->generateController($data);
|
||||
}
|
||||
if ($model == 1) {
|
||||
$fileList[] = $this->generateModel($data);
|
||||
}
|
||||
}
|
||||
return $fileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function generateModel(array $data): string
|
||||
{
|
||||
$controller = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']);
|
||||
$controller->setConnection($this->db);
|
||||
$controller->setModelPath($this->modelPath);
|
||||
$controller->setModelNamespace($this->modelNamespace);
|
||||
$controller->setInput($this->input);
|
||||
// $controller->setModule($this->input->getArgument('module'));
|
||||
$controller->setControllerPath($this->controllerPath);
|
||||
$controller->setControllerNamespace($this->controllerNamespace);
|
||||
return $controller->generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function generateController(array $data): string
|
||||
{
|
||||
$controller = new GiiController($data['classFileName'], $data['fields']);
|
||||
$controller->setConnection($this->db);
|
||||
$controller->setModelPath($this->modelPath);
|
||||
$controller->setInput($this->input);
|
||||
$controller->setModelNamespace($this->modelNamespace);
|
||||
$controller->setControllerPath($this->controllerPath);
|
||||
$controller->setModule($this->input->getArgument('module'));
|
||||
$controller->setControllerNamespace($this->controllerNamespace);
|
||||
return $controller->generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string|null
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getTables(): array|string|null
|
||||
{
|
||||
if (empty($this->tableName)) {
|
||||
return $this->showAll();
|
||||
}
|
||||
$res = $this->tableName;
|
||||
if (is_string($res)) {
|
||||
$res = explode(',', $this->tableName);
|
||||
}
|
||||
if (empty($res)) {
|
||||
return [];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function showAll(): array
|
||||
{
|
||||
$res = [];
|
||||
$_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db);
|
||||
if (empty($_tables)) {
|
||||
return $res;
|
||||
}
|
||||
foreach ($_tables as $key => $val) {
|
||||
$res[] = array_shift($val);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @return bool|int|null
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getIndex($table): bool|int|null
|
||||
{
|
||||
$data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db);
|
||||
|
||||
return empty($data) ? NULL : $data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tables
|
||||
*
|
||||
* @return array
|
||||
* @throws
|
||||
*/
|
||||
private function getFields($tables): array
|
||||
{
|
||||
$res = [];
|
||||
if (!is_array($tables)) {
|
||||
$tables = [$tables];
|
||||
}
|
||||
foreach ($tables as $key => $val) {
|
||||
if (empty($val)) continue;
|
||||
$_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db);
|
||||
if (empty($_tmp)) {
|
||||
continue;
|
||||
}
|
||||
$res[$val] = $_tmp;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tableName
|
||||
* @param $tables
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createModelFile($tableName, $tables): array
|
||||
{
|
||||
$res = $visible = $fields = $keys = [];
|
||||
foreach ($tables as $_key => $_val) {
|
||||
$keys = $tableName;
|
||||
if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') {
|
||||
$keys = $tableName;
|
||||
}
|
||||
if (!isset($keys) && !($index = $this->getIndex($tableName))) {
|
||||
$keys = $index['Column_name'];
|
||||
}
|
||||
if (in_array(strtoupper($_val['Field']), $this->keyword)) {
|
||||
throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"');
|
||||
}
|
||||
array_push($visible, $this->createVisible($_val['Field']));
|
||||
array_push($fields, $_val);
|
||||
$res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
|
||||
}
|
||||
|
||||
$classFileName = $this->getClassName($tableName);
|
||||
|
||||
return [
|
||||
'classFileName' => $classFileName,
|
||||
'tableName' => $keys,
|
||||
'visible' => $visible,
|
||||
'fields' => $fields,
|
||||
'res' => $res,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @return string
|
||||
* 创建变量注释
|
||||
*/
|
||||
private function createVisible($field): string
|
||||
{
|
||||
return '
|
||||
* @property $' . $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @param $comment
|
||||
* @return string
|
||||
* 暂时不知道干嘛用的
|
||||
*/
|
||||
private function createSetFunc($field, $comment): string
|
||||
{
|
||||
return '
|
||||
' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tableName
|
||||
* @return string
|
||||
* 构建类名称
|
||||
*/
|
||||
private function getClassName($tableName): string
|
||||
{
|
||||
$res = [];
|
||||
$tableName = str_replace($this->db->tablePrefix,'', $tableName);
|
||||
foreach (explode('_', $tableName) as $n => $val) {
|
||||
$res[] = ucfirst($val);
|
||||
}
|
||||
return implode('', $res);
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: 向林
|
||||
* Date: 2016/8/9 0009
|
||||
* Time: 17:43
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Gii;
|
||||
|
||||
use Database\Connection;
|
||||
use Database\Db;
|
||||
use Exception;
|
||||
use Kiri\Cache\Redis;
|
||||
use Kiri\Kiri;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
/**
|
||||
* Class gii
|
||||
*
|
||||
* @package Inter\utility
|
||||
*/
|
||||
class Gii
|
||||
{
|
||||
private ?string $tableName = NULL;
|
||||
|
||||
/** @var null|Connection */
|
||||
private ?Connection $db;
|
||||
|
||||
private InputInterface $input;
|
||||
|
||||
public string $modelPath = APP_PATH . 'app/Model/';
|
||||
public string $modelNamespace = 'App\\Model\\';
|
||||
|
||||
public string $controllerPath = APP_PATH . 'app/Http/Controller/';
|
||||
public string $controllerNamespace = 'App\\Controller\\';
|
||||
|
||||
|
||||
public static array $createSqls = [];
|
||||
|
||||
|
||||
public array $keyword = [
|
||||
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Connection|null $db
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function run(?Connection $db, InputInterface $input): array
|
||||
{
|
||||
return $this->gen($input, $db);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param $db
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function gen(InputInterface $input, $db): array
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->db = $db;
|
||||
|
||||
$make = $this->input->getOption('make');
|
||||
if (empty($make)) {
|
||||
throw new Exception('构建类型不能为空~');
|
||||
}
|
||||
switch (strtolower($make)) {
|
||||
case 'task':
|
||||
$task = new GiiTask();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'middleware':
|
||||
$task = new GiiMiddleware();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'rpc-client':
|
||||
$task = new GiiRpcClient();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'rpc-service':
|
||||
$task = new GiiRpcService();
|
||||
$task->setInput($this->input);
|
||||
return $task->generate();
|
||||
case 'json-rpc':
|
||||
$task = new GiiJsonRpc();
|
||||
$task->setInput($this->input);
|
||||
return $task->create();
|
||||
default:
|
||||
return $this->getModel($make, $input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $make
|
||||
* @param $input
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getModel($make, $input): array
|
||||
{
|
||||
return $this->makeByDatabases($make, $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $make
|
||||
* @param InputInterface $input
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function makeByDatabases($make, InputInterface $input): array
|
||||
{
|
||||
if ($input->hasOption('name')) {
|
||||
$this->tableName = $input->getOption('name');
|
||||
}
|
||||
return match ($make) {
|
||||
'controller' => $this->getTable(1, 0),
|
||||
'model' => $this->getTable(0, 1),
|
||||
default => [],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $controller
|
||||
* @param $model
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getTable($controller, $model): array
|
||||
{
|
||||
$tables = $this->getFields($this->getTables());
|
||||
if (empty($tables)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$fileList = [];
|
||||
foreach ($tables as $key => $val) {
|
||||
$data = $this->createModelFile($key, $val);
|
||||
if ($controller == 1) {
|
||||
$fileList[] = $this->generateController($data);
|
||||
}
|
||||
if ($model == 1) {
|
||||
$fileList[] = $this->generateModel($data);
|
||||
}
|
||||
}
|
||||
return $fileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function generateModel(array $data): string
|
||||
{
|
||||
$controller = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']);
|
||||
$controller->setConnection($this->db);
|
||||
$controller->setModelPath($this->modelPath);
|
||||
$controller->setModelNamespace($this->modelNamespace);
|
||||
$controller->setInput($this->input);
|
||||
// $controller->setModule($this->input->getArgument('module'));
|
||||
$controller->setControllerPath($this->controllerPath);
|
||||
$controller->setControllerNamespace($this->controllerNamespace);
|
||||
return $controller->generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function generateController(array $data): string
|
||||
{
|
||||
$controller = new GiiController($data['classFileName'], $data['fields']);
|
||||
$controller->setConnection($this->db);
|
||||
$controller->setModelPath($this->modelPath);
|
||||
$controller->setInput($this->input);
|
||||
$controller->setModelNamespace($this->modelNamespace);
|
||||
$controller->setControllerPath($this->controllerPath);
|
||||
$controller->setModule($this->input->getArgument('module'));
|
||||
$controller->setControllerNamespace($this->controllerNamespace);
|
||||
return $controller->generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string|null
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getTables(): array|string|null
|
||||
{
|
||||
if (empty($this->tableName)) {
|
||||
return $this->showAll();
|
||||
}
|
||||
$res = $this->tableName;
|
||||
if (is_string($res)) {
|
||||
$res = explode(',', $this->tableName);
|
||||
}
|
||||
if (empty($res)) {
|
||||
return [];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function showAll(): array
|
||||
{
|
||||
$res = [];
|
||||
$_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db);
|
||||
if (empty($_tables)) {
|
||||
return $res;
|
||||
}
|
||||
foreach ($_tables as $key => $val) {
|
||||
$res[] = array_shift($val);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @return bool|int|null
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getIndex($table): bool|int|null
|
||||
{
|
||||
$data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db);
|
||||
|
||||
return empty($data) ? NULL : $data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tables
|
||||
*
|
||||
* @return array
|
||||
* @throws
|
||||
*/
|
||||
private function getFields($tables): array
|
||||
{
|
||||
$res = [];
|
||||
if (!is_array($tables)) {
|
||||
$tables = [$tables];
|
||||
}
|
||||
foreach ($tables as $key => $val) {
|
||||
if (empty($val)) continue;
|
||||
$_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db);
|
||||
if (empty($_tmp)) {
|
||||
continue;
|
||||
}
|
||||
$res[$val] = $_tmp;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tableName
|
||||
* @param $tables
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createModelFile($tableName, $tables): array
|
||||
{
|
||||
$res = $visible = $fields = $keys = [];
|
||||
foreach ($tables as $_key => $_val) {
|
||||
$keys = $tableName;
|
||||
if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') {
|
||||
$keys = $tableName;
|
||||
}
|
||||
if (!isset($keys) && !($index = $this->getIndex($tableName))) {
|
||||
$keys = $index['Column_name'];
|
||||
}
|
||||
if (in_array(strtoupper($_val['Field']), $this->keyword)) {
|
||||
throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"');
|
||||
}
|
||||
array_push($visible, $this->createVisible($_val['Field']));
|
||||
array_push($fields, $_val);
|
||||
$res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
|
||||
}
|
||||
|
||||
$classFileName = $this->getClassName($tableName);
|
||||
|
||||
return [
|
||||
'classFileName' => $classFileName,
|
||||
'tableName' => $keys,
|
||||
'visible' => $visible,
|
||||
'fields' => $fields,
|
||||
'res' => $res,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @return string
|
||||
* 创建变量注释
|
||||
*/
|
||||
private function createVisible($field): string
|
||||
{
|
||||
return '
|
||||
* @property $' . $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @param $comment
|
||||
* @return string
|
||||
* 暂时不知道干嘛用的
|
||||
*/
|
||||
private function createSetFunc($field, $comment): string
|
||||
{
|
||||
return '
|
||||
' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tableName
|
||||
* @return string
|
||||
* 构建类名称
|
||||
*/
|
||||
private function getClassName($tableName): string
|
||||
{
|
||||
$res = [];
|
||||
$tableName = str_replace($this->db->tablePrefix,'', $tableName);
|
||||
foreach (explode('_', $tableName) as $n => $val) {
|
||||
$res[] = ucfirst($val);
|
||||
}
|
||||
return implode('', $res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+411
-411
@@ -1,411 +1,411 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Database\Connection;
|
||||
use Exception;
|
||||
use Kiri\Core\Json;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
/**
|
||||
* Class GiiBase
|
||||
* @package Gii
|
||||
*/
|
||||
abstract class GiiBase
|
||||
{
|
||||
|
||||
public array $fileList = [];
|
||||
|
||||
|
||||
protected InputInterface $input;
|
||||
|
||||
public string $modelPath = APP_PATH . 'app/Model/';
|
||||
public string $modelNamespace = 'App\Model\\';
|
||||
|
||||
public string $controllerPath = APP_PATH . 'app/Http/Controller/';
|
||||
public string $controllerNamespace = 'App\\Controller\\';
|
||||
|
||||
public ?string $module = null;
|
||||
|
||||
public array $rules = [];
|
||||
public array $type = [
|
||||
'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'],
|
||||
'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'],
|
||||
'date' => ['date'],
|
||||
'time' => ['time'],
|
||||
'year' => ['year'],
|
||||
'datetime' => ['datetime'],
|
||||
'timestamp' => ['timestamp'],
|
||||
'float' => ['float', 'double', 'decimal',],
|
||||
];
|
||||
public ?string $tableName = NULL;
|
||||
|
||||
public ?Connection $db = null;
|
||||
|
||||
/**
|
||||
* @param string $modelPath
|
||||
*/
|
||||
public function setModelPath(string $modelPath): void
|
||||
{
|
||||
$this->modelPath = $modelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $modelNamespace
|
||||
*/
|
||||
public function setModelNamespace(string $modelNamespace): void
|
||||
{
|
||||
$this->modelNamespace = $modelNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllerPath
|
||||
*/
|
||||
public function setControllerPath(string $controllerPath): void
|
||||
{
|
||||
$this->controllerPath = $controllerPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $module
|
||||
*/
|
||||
public function setModule($module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllerNamespace
|
||||
*/
|
||||
public function setControllerNamespace(string $controllerNamespace): void
|
||||
{
|
||||
$this->controllerNamespace = $controllerNamespace;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $object
|
||||
* @param $className
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUseContent(ReflectionClass $object, $className): string
|
||||
{
|
||||
if (empty($object)) {
|
||||
return '';
|
||||
}
|
||||
$file = $this->getFilePath($className);
|
||||
if (!file_exists($file)) {
|
||||
return '';
|
||||
}
|
||||
$content = file_get_contents($file);
|
||||
$explode = explode(PHP_EOL, $content);
|
||||
$exists = array_slice($explode, 0, $object->getStartLine());
|
||||
$_tmp = [];
|
||||
foreach ($exists as $key => $val) {
|
||||
if (trim($val) == '/**') {
|
||||
break;
|
||||
}
|
||||
$_tmp[] = $val;
|
||||
}
|
||||
return trim(implode(PHP_EOL, $_tmp));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param ReflectionClass $class
|
||||
* @return string
|
||||
*/
|
||||
protected function getImports(string $fileName, ReflectionClass $class): string
|
||||
{
|
||||
$startLine = 1;
|
||||
$array = [];
|
||||
$fileOpen = fopen($fileName, 'r');
|
||||
while (($content = fgets($fileOpen)) !== false) {
|
||||
if (str_starts_with($content, 'use ')) {
|
||||
$array[] = $content;
|
||||
}
|
||||
if ($startLine == $class->getStartLine()) {
|
||||
break;
|
||||
}
|
||||
++$startLine;
|
||||
}
|
||||
return implode($array);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class
|
||||
* @return string
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
protected function getClassProperty(ReflectionClass $class): string
|
||||
{
|
||||
$html = '';
|
||||
|
||||
$rc = $class->getParentClass()->getConstants();
|
||||
|
||||
foreach ($class->getConstants() as $key => $val) {
|
||||
if (isset($rc[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (is_numeric($val)) {
|
||||
$html .= '
|
||||
const ' . $key . ' = ' . $val . ';' . "\n";
|
||||
} else {
|
||||
$html .= '
|
||||
const ' . $key . ' = \'' . $val . '\';' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($class->getDefaultProperties() as $key => $val) {
|
||||
$property = $class->getProperty($key);
|
||||
if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') {
|
||||
continue;
|
||||
}
|
||||
if ($property->class != $class->getName()) continue;
|
||||
if (is_array($val)) {
|
||||
$val = '[\'' . implode('\', \'', $val) . '\']';
|
||||
} else if (!is_numeric($val)) {
|
||||
$val = '\'' . $val . '\'';
|
||||
}
|
||||
|
||||
if ($property->isProtected()) {
|
||||
$debug = 'protected';
|
||||
} else if ($property->isPrivate()) {
|
||||
$debug = 'private';
|
||||
} else {
|
||||
$debug = 'public';
|
||||
}
|
||||
if ($property->hasType()) {
|
||||
$type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n";
|
||||
} else {
|
||||
$type = ' $' . $key . ' = ' . $val . ';' . "\n";
|
||||
}
|
||||
if ($property->isStatic()) {
|
||||
$html .= '
|
||||
' . $debug . ' static' . $type;
|
||||
} else {
|
||||
$html .= '
|
||||
' . $debug . $type;
|
||||
}
|
||||
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class
|
||||
* @param array $filters
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getClassMethods(ReflectionClass $class, array $filters = []): string
|
||||
{
|
||||
$methods = $class->getMethods();
|
||||
|
||||
$classFileName = str_replace(APP_PATH, '', $class->getFileName());
|
||||
|
||||
$content = [];
|
||||
if (!empty($methods)) foreach ($methods as $key => $val) {
|
||||
if ($val->class != $class->getName()) continue;
|
||||
if (in_array($val->name, $filters)) continue;
|
||||
$over = "
|
||||
" . $val->getDocComment() . "\n";
|
||||
|
||||
$attributes = $val->getAttributes();
|
||||
if (!empty($attributes)) {
|
||||
foreach ($attributes as $attribute) {
|
||||
$explode = explode('\\', $attribute->getName());
|
||||
|
||||
$_array = [];
|
||||
foreach ($attribute->getArguments() as $_key => $argument) {
|
||||
$argument = $this->resolveArray($argument);
|
||||
if (is_numeric($_key)) {
|
||||
$_array[] = $argument;
|
||||
} else {
|
||||
$_array[] = $_key . ': ' . $argument . '';
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($_array)) {
|
||||
$end = " #[" . end($explode) . "]
|
||||
";
|
||||
} else {
|
||||
$end = " #[" . end($explode) . "(" . implode(',', $_array) . ")]
|
||||
";
|
||||
}
|
||||
if (str_contains($over, $end)) {
|
||||
$over = str_replace($end, '', $over);
|
||||
}
|
||||
$over .= $end;
|
||||
}
|
||||
}
|
||||
|
||||
$func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
|
||||
|
||||
$content[] = $over . $func;
|
||||
}
|
||||
return implode(PHP_EOL, $content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $argument
|
||||
* @return string
|
||||
*/
|
||||
private function resolveArray($argument): string
|
||||
{
|
||||
if (is_array($argument)) {
|
||||
$__array = [];
|
||||
foreach ($argument as $key => $value) {
|
||||
if (is_string($value)) {
|
||||
if (str_contains($value, '\\') && class_exists($value)) {
|
||||
$explode_class = explode('\\', $value);
|
||||
|
||||
$__array[] = end($explode_class) . '::class';
|
||||
} else {
|
||||
$__array[] = '\'' . $value . '\'';
|
||||
}
|
||||
} else {
|
||||
$value = str_replace('{', '[', Json::encode($value));
|
||||
$value = str_replace('}', ']', Json::encode($value));
|
||||
$value = str_replace(':', '=>', Json::encode($value));
|
||||
|
||||
$value = preg_replace('/"\d+"\=\>/', '', $value);
|
||||
|
||||
$__array[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$argument = '[' . implode(', ', $__array) . ']';
|
||||
} else {
|
||||
$argument = '\'' . $argument . '\'';
|
||||
}
|
||||
return $argument;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $fields
|
||||
* @return mixed 返回表主键
|
||||
* 返回表主键
|
||||
*/
|
||||
public function getPrimaryKey($fields): mixed
|
||||
{
|
||||
$condition = ['PRI', 'UNI'];
|
||||
foreach ($fields as $field) {
|
||||
if ($field['Extra'] == 'auto_increment') {
|
||||
return $field['Field'];
|
||||
}
|
||||
if (in_array($field['Key'], $condition)) {
|
||||
return $field['Field'];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $className
|
||||
* @return string
|
||||
*/
|
||||
private function getFilePath($className): string
|
||||
{
|
||||
if (strpos($className, '\\')) {
|
||||
$className = str_replace('\\', '/', $className);
|
||||
}
|
||||
if (strpos($className, '\\')) {
|
||||
$className = str_replace('\\', '/', $className);
|
||||
}
|
||||
|
||||
return APP_PATH . $className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $object
|
||||
* @param $className
|
||||
* @param $method
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getFuncLineContent(ReflectionClass $object, $className, $method): string
|
||||
{
|
||||
$fun = $object->getMethod($method);
|
||||
|
||||
$content = file_get_contents($this->getFilePath($className));
|
||||
$explode = explode(PHP_EOL, $content);
|
||||
$exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1);
|
||||
return implode(PHP_EOL, $exists);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getModelPath(): array
|
||||
{
|
||||
$dbName = $this->db->id;
|
||||
if (empty($dbName) || $dbName == 'db') {
|
||||
$dbName = '';
|
||||
}
|
||||
|
||||
$modelPath = [
|
||||
'namespace' => $this->modelNamespace,
|
||||
'path' => $this->modelPath,
|
||||
];
|
||||
if (!is_dir($modelPath['path'])) {
|
||||
mkdir($modelPath['path']);
|
||||
}
|
||||
if (!empty($dbName)) {
|
||||
$modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName);
|
||||
$modelPath['path'] = $this->modelPath . ucfirst($dbName);
|
||||
}
|
||||
|
||||
if (!is_dir($modelPath['path'])) {
|
||||
mkdir($modelPath['path']);
|
||||
}
|
||||
return $modelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $db
|
||||
*/
|
||||
public function setConnection($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
* @return string
|
||||
*/
|
||||
protected function checkIsRequired($val): string
|
||||
{
|
||||
return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFileLists(): array
|
||||
{
|
||||
return $this->fileList;
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Database\Connection;
|
||||
use Exception;
|
||||
use Kiri\Core\Json;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
/**
|
||||
* Class GiiBase
|
||||
* @package Gii
|
||||
*/
|
||||
abstract class GiiBase
|
||||
{
|
||||
|
||||
public array $fileList = [];
|
||||
|
||||
|
||||
protected InputInterface $input;
|
||||
|
||||
public string $modelPath = APP_PATH . 'app/Model/';
|
||||
public string $modelNamespace = 'App\Model\\';
|
||||
|
||||
public string $controllerPath = APP_PATH . 'app/Http/Controller/';
|
||||
public string $controllerNamespace = 'App\\Controller\\';
|
||||
|
||||
public ?string $module = null;
|
||||
|
||||
public array $rules = [];
|
||||
public array $type = [
|
||||
'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'],
|
||||
'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'],
|
||||
'date' => ['date'],
|
||||
'time' => ['time'],
|
||||
'year' => ['year'],
|
||||
'datetime' => ['datetime'],
|
||||
'timestamp' => ['timestamp'],
|
||||
'float' => ['float', 'double', 'decimal',],
|
||||
];
|
||||
public ?string $tableName = NULL;
|
||||
|
||||
public ?Connection $db = null;
|
||||
|
||||
/**
|
||||
* @param string $modelPath
|
||||
*/
|
||||
public function setModelPath(string $modelPath): void
|
||||
{
|
||||
$this->modelPath = $modelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $modelNamespace
|
||||
*/
|
||||
public function setModelNamespace(string $modelNamespace): void
|
||||
{
|
||||
$this->modelNamespace = $modelNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllerPath
|
||||
*/
|
||||
public function setControllerPath(string $controllerPath): void
|
||||
{
|
||||
$this->controllerPath = $controllerPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $module
|
||||
*/
|
||||
public function setModule($module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllerNamespace
|
||||
*/
|
||||
public function setControllerNamespace(string $controllerNamespace): void
|
||||
{
|
||||
$this->controllerNamespace = $controllerNamespace;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $object
|
||||
* @param $className
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUseContent(ReflectionClass $object, $className): string
|
||||
{
|
||||
if (empty($object)) {
|
||||
return '';
|
||||
}
|
||||
$file = $this->getFilePath($className);
|
||||
if (!file_exists($file)) {
|
||||
return '';
|
||||
}
|
||||
$content = file_get_contents($file);
|
||||
$explode = explode(PHP_EOL, $content);
|
||||
$exists = array_slice($explode, 0, $object->getStartLine());
|
||||
$_tmp = [];
|
||||
foreach ($exists as $key => $val) {
|
||||
if (trim($val) == '/**') {
|
||||
break;
|
||||
}
|
||||
$_tmp[] = $val;
|
||||
}
|
||||
return trim(implode(PHP_EOL, $_tmp));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param ReflectionClass $class
|
||||
* @return string
|
||||
*/
|
||||
protected function getImports(string $fileName, ReflectionClass $class): string
|
||||
{
|
||||
$startLine = 1;
|
||||
$array = [];
|
||||
$fileOpen = fopen($fileName, 'r');
|
||||
while (($content = fgets($fileOpen)) !== false) {
|
||||
if (str_starts_with($content, 'use ')) {
|
||||
$array[] = $content;
|
||||
}
|
||||
if ($startLine == $class->getStartLine()) {
|
||||
break;
|
||||
}
|
||||
++$startLine;
|
||||
}
|
||||
return implode($array);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class
|
||||
* @return string
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
protected function getClassProperty(ReflectionClass $class): string
|
||||
{
|
||||
$html = '';
|
||||
|
||||
$rc = $class->getParentClass()->getConstants();
|
||||
|
||||
foreach ($class->getConstants() as $key => $val) {
|
||||
if (isset($rc[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (is_numeric($val)) {
|
||||
$html .= '
|
||||
const ' . $key . ' = ' . $val . ';' . "\n";
|
||||
} else {
|
||||
$html .= '
|
||||
const ' . $key . ' = \'' . $val . '\';' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($class->getDefaultProperties() as $key => $val) {
|
||||
$property = $class->getProperty($key);
|
||||
if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') {
|
||||
continue;
|
||||
}
|
||||
if ($property->class != $class->getName()) continue;
|
||||
if (is_array($val)) {
|
||||
$val = '[\'' . implode('\', \'', $val) . '\']';
|
||||
} else if (!is_numeric($val)) {
|
||||
$val = '\'' . $val . '\'';
|
||||
}
|
||||
|
||||
if ($property->isProtected()) {
|
||||
$debug = 'protected';
|
||||
} else if ($property->isPrivate()) {
|
||||
$debug = 'private';
|
||||
} else {
|
||||
$debug = 'public';
|
||||
}
|
||||
if ($property->hasType()) {
|
||||
$type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n";
|
||||
} else {
|
||||
$type = ' $' . $key . ' = ' . $val . ';' . "\n";
|
||||
}
|
||||
if ($property->isStatic()) {
|
||||
$html .= '
|
||||
' . $debug . ' static' . $type;
|
||||
} else {
|
||||
$html .= '
|
||||
' . $debug . $type;
|
||||
}
|
||||
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class
|
||||
* @param array $filters
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getClassMethods(ReflectionClass $class, array $filters = []): string
|
||||
{
|
||||
$methods = $class->getMethods();
|
||||
|
||||
$classFileName = str_replace(APP_PATH, '', $class->getFileName());
|
||||
|
||||
$content = [];
|
||||
if (!empty($methods)) foreach ($methods as $key => $val) {
|
||||
if ($val->class != $class->getName()) continue;
|
||||
if (in_array($val->name, $filters)) continue;
|
||||
$over = "
|
||||
" . $val->getDocComment() . "\n";
|
||||
|
||||
$attributes = $val->getAttributes();
|
||||
if (!empty($attributes)) {
|
||||
foreach ($attributes as $attribute) {
|
||||
$explode = explode('\\', $attribute->getName());
|
||||
|
||||
$_array = [];
|
||||
foreach ($attribute->getArguments() as $_key => $argument) {
|
||||
$argument = $this->resolveArray($argument);
|
||||
if (is_numeric($_key)) {
|
||||
$_array[] = $argument;
|
||||
} else {
|
||||
$_array[] = $_key . ': ' . $argument . '';
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($_array)) {
|
||||
$end = " #[" . end($explode) . "]
|
||||
";
|
||||
} else {
|
||||
$end = " #[" . end($explode) . "(" . implode(',', $_array) . ")]
|
||||
";
|
||||
}
|
||||
if (str_contains($over, $end)) {
|
||||
$over = str_replace($end, '', $over);
|
||||
}
|
||||
$over .= $end;
|
||||
}
|
||||
}
|
||||
|
||||
$func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
|
||||
|
||||
$content[] = $over . $func;
|
||||
}
|
||||
return implode(PHP_EOL, $content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $argument
|
||||
* @return string
|
||||
*/
|
||||
private function resolveArray($argument): string
|
||||
{
|
||||
if (is_array($argument)) {
|
||||
$__array = [];
|
||||
foreach ($argument as $key => $value) {
|
||||
if (is_string($value)) {
|
||||
if (str_contains($value, '\\') && class_exists($value)) {
|
||||
$explode_class = explode('\\', $value);
|
||||
|
||||
$__array[] = end($explode_class) . '::class';
|
||||
} else {
|
||||
$__array[] = '\'' . $value . '\'';
|
||||
}
|
||||
} else {
|
||||
$value = str_replace('{', '[', Json::encode($value));
|
||||
$value = str_replace('}', ']', Json::encode($value));
|
||||
$value = str_replace(':', '=>', Json::encode($value));
|
||||
|
||||
$value = preg_replace('/"\d+"\=\>/', '', $value);
|
||||
|
||||
$__array[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$argument = '[' . implode(', ', $__array) . ']';
|
||||
} else {
|
||||
$argument = '\'' . $argument . '\'';
|
||||
}
|
||||
return $argument;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $fields
|
||||
* @return mixed 返回表主键
|
||||
* 返回表主键
|
||||
*/
|
||||
public function getPrimaryKey($fields): mixed
|
||||
{
|
||||
$condition = ['PRI', 'UNI'];
|
||||
foreach ($fields as $field) {
|
||||
if ($field['Extra'] == 'auto_increment') {
|
||||
return $field['Field'];
|
||||
}
|
||||
if (in_array($field['Key'], $condition)) {
|
||||
return $field['Field'];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $className
|
||||
* @return string
|
||||
*/
|
||||
private function getFilePath($className): string
|
||||
{
|
||||
if (strpos($className, '\\')) {
|
||||
$className = str_replace('\\', '/', $className);
|
||||
}
|
||||
if (strpos($className, '\\')) {
|
||||
$className = str_replace('\\', '/', $className);
|
||||
}
|
||||
|
||||
return APP_PATH . $className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $object
|
||||
* @param $className
|
||||
* @param $method
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getFuncLineContent(ReflectionClass $object, $className, $method): string
|
||||
{
|
||||
$fun = $object->getMethod($method);
|
||||
|
||||
$content = file_get_contents($this->getFilePath($className));
|
||||
$explode = explode(PHP_EOL, $content);
|
||||
$exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1);
|
||||
return implode(PHP_EOL, $exists);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getModelPath(): array
|
||||
{
|
||||
$dbName = $this->db->id;
|
||||
if (empty($dbName) || $dbName == 'db') {
|
||||
$dbName = '';
|
||||
}
|
||||
|
||||
$modelPath = [
|
||||
'namespace' => $this->modelNamespace,
|
||||
'path' => $this->modelPath,
|
||||
];
|
||||
if (!is_dir($modelPath['path'])) {
|
||||
mkdir($modelPath['path']);
|
||||
}
|
||||
if (!empty($dbName)) {
|
||||
$modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName);
|
||||
$modelPath['path'] = $this->modelPath . ucfirst($dbName);
|
||||
}
|
||||
|
||||
if (!is_dir($modelPath['path'])) {
|
||||
mkdir($modelPath['path']);
|
||||
}
|
||||
return $modelPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $db
|
||||
*/
|
||||
public function setConnection($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
* @return string
|
||||
*/
|
||||
protected function checkIsRequired($val): string
|
||||
{
|
||||
return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFileLists(): array
|
||||
{
|
||||
return $this->fileList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+76
-76
@@ -1,76 +1,76 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class Command
|
||||
* @package Http
|
||||
*/
|
||||
class GiiCommand extends Command
|
||||
{
|
||||
|
||||
public string $command = 'sw:gii';
|
||||
|
||||
|
||||
public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx';
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('sw:gii')
|
||||
->addOption('make','m', InputArgument::OPTIONAL)
|
||||
->addOption('name','t', InputArgument::OPTIONAL)
|
||||
->addOption('databases','d', InputArgument::OPTIONAL)
|
||||
->setDescription('./snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return int
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
/** @var Gii $gii */
|
||||
$gii = Kiri::app()->get('gii');
|
||||
|
||||
$connections = Kiri::app()->get('db');
|
||||
if (($db = $input->getOption('databases')) != null) {
|
||||
$gii->run($connections->get($db), $input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
$action = $input->getOption('make');
|
||||
if (!in_array($action, ['model', 'controller'])) {
|
||||
$gii->run(null, $input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
$array = [];
|
||||
foreach (Config::get('databases.connections') as $key => $connection) {
|
||||
$array[$key] = $gii->run($connections->get($key), $input);
|
||||
}
|
||||
|
||||
$output->writeln(json_encode($array, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class Command
|
||||
* @package Http
|
||||
*/
|
||||
class GiiCommand extends Command
|
||||
{
|
||||
|
||||
public string $command = 'sw:gii';
|
||||
|
||||
|
||||
public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx';
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('sw:gii')
|
||||
->addOption('make','m', InputArgument::OPTIONAL)
|
||||
->addOption('name','t', InputArgument::OPTIONAL)
|
||||
->addOption('databases','d', InputArgument::OPTIONAL)
|
||||
->setDescription('./snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return int
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
/** @var Gii $gii */
|
||||
$gii = Kiri::app()->get('gii');
|
||||
|
||||
$connections = Kiri::app()->get('db');
|
||||
if (($db = $input->getOption('databases')) != null) {
|
||||
$gii->run($connections->get($db), $input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
$action = $input->getOption('make');
|
||||
if (!in_array($action, ['model', 'controller'])) {
|
||||
$gii->run(null, $input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
$array = [];
|
||||
foreach (Config::get('databases.connections') as $key => $connection) {
|
||||
$array[$key] = $gii->run($connections->get($key), $input);
|
||||
}
|
||||
|
||||
$output->writeln(json_encode($array, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+536
-536
File diff suppressed because it is too large
Load Diff
+113
-113
@@ -1,113 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Gii;
|
||||
|
||||
class GiiJsonRpc extends GiiBase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function create(): array
|
||||
{
|
||||
return [
|
||||
$this->createInterface($this->input->getArgument('name')),
|
||||
$this->createProducers($this->input->getArgument('name')),
|
||||
$this->createConsumer($this->input->getArgument('name')),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function createInterface($name): string
|
||||
{
|
||||
$html = '<?php
|
||||
|
||||
namespace Rpc;
|
||||
|
||||
|
||||
interface ' . ucfirst($name) . 'RpcInterface
|
||||
{
|
||||
|
||||
|
||||
}';
|
||||
|
||||
|
||||
$name = ucfirst($name) . 'RpcInterface.php';
|
||||
if (!is_dir(APP_PATH . '/rpc/')) {
|
||||
mkdir(APP_PATH . '/rpc/');
|
||||
}
|
||||
file_put_contents(APP_PATH . '/rpc/' . $name, $html);
|
||||
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function createProducers($name): string
|
||||
{
|
||||
$html = '<?php
|
||||
|
||||
namespace Rpc\Producers;
|
||||
|
||||
|
||||
use Kiri\Annotation\Target;
|
||||
use Kiri\Annotation\Mapping;
|
||||
use Rpc\\' . ucfirst($name) . 'RpcInterface;
|
||||
use Exception;
|
||||
use Kiri\Rpc\JsonRpcConsumers;
|
||||
|
||||
|
||||
#[Target]
|
||||
#[Mapping(' . ucfirst($name) . 'RpcInterface::class)]
|
||||
class ' . ucfirst($name) . 'RpcService extends JsonRpcConsumers implements ' . ucfirst($name) . 'RpcInterface
|
||||
{
|
||||
|
||||
protected string $name = \'' . $name . '\';
|
||||
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$name = ucfirst($name) . 'RpcService.php';
|
||||
if (!is_dir(APP_PATH . '/rpc/Producers/')) {
|
||||
mkdir(APP_PATH . '/rpc/Producers/');
|
||||
}
|
||||
file_put_contents(APP_PATH . '/rpc/Producers/' . $name, $html);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
private function createConsumer($name): string
|
||||
{
|
||||
$html = '<?php
|
||||
|
||||
namespace Rpc\Consumers;
|
||||
|
||||
|
||||
use Kiri\Annotation\Target;
|
||||
use Kiri\Rpc\Annotation\JsonRpc;
|
||||
use Http\Handler\Controller;
|
||||
use Rpc\\' . ucfirst($name) . 'RpcInterface;
|
||||
|
||||
|
||||
#[Target]
|
||||
#[JsonRpc(service: \'' . $name . '\', version: \'2.0\')]
|
||||
class ' . ucfirst($name) . 'RpcConsumer extends Controller implements ' . ucfirst($name) . 'RpcInterface
|
||||
{
|
||||
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$name = ucfirst($name) . 'RpcConsumer.php';
|
||||
if (!is_dir(APP_PATH . '/rpc/Consumers/')) {
|
||||
mkdir(APP_PATH . '/rpc/Consumers/');
|
||||
}
|
||||
file_put_contents(APP_PATH . '/rpc/Consumers/' . $name, $html);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Gii;
|
||||
|
||||
class GiiJsonRpc extends GiiBase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function create(): array
|
||||
{
|
||||
return [
|
||||
$this->createInterface($this->input->getArgument('name')),
|
||||
$this->createProducers($this->input->getArgument('name')),
|
||||
$this->createConsumer($this->input->getArgument('name')),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function createInterface($name): string
|
||||
{
|
||||
$html = '<?php
|
||||
|
||||
namespace Rpc;
|
||||
|
||||
|
||||
interface ' . ucfirst($name) . 'RpcInterface
|
||||
{
|
||||
|
||||
|
||||
}';
|
||||
|
||||
|
||||
$name = ucfirst($name) . 'RpcInterface.php';
|
||||
if (!is_dir(APP_PATH . '/rpc/')) {
|
||||
mkdir(APP_PATH . '/rpc/');
|
||||
}
|
||||
file_put_contents(APP_PATH . '/rpc/' . $name, $html);
|
||||
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function createProducers($name): string
|
||||
{
|
||||
$html = '<?php
|
||||
|
||||
namespace Rpc\Producers;
|
||||
|
||||
|
||||
use Kiri\Annotation\Target;
|
||||
use Kiri\Annotation\Mapping;
|
||||
use Rpc\\' . ucfirst($name) . 'RpcInterface;
|
||||
use Exception;
|
||||
use Kiri\Rpc\JsonRpcConsumers;
|
||||
|
||||
|
||||
#[Target]
|
||||
#[Mapping(' . ucfirst($name) . 'RpcInterface::class)]
|
||||
class ' . ucfirst($name) . 'RpcService extends JsonRpcConsumers implements ' . ucfirst($name) . 'RpcInterface
|
||||
{
|
||||
|
||||
protected string $name = \'' . $name . '\';
|
||||
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$name = ucfirst($name) . 'RpcService.php';
|
||||
if (!is_dir(APP_PATH . '/rpc/Producers/')) {
|
||||
mkdir(APP_PATH . '/rpc/Producers/');
|
||||
}
|
||||
file_put_contents(APP_PATH . '/rpc/Producers/' . $name, $html);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
private function createConsumer($name): string
|
||||
{
|
||||
$html = '<?php
|
||||
|
||||
namespace Rpc\Consumers;
|
||||
|
||||
|
||||
use Kiri\Annotation\Target;
|
||||
use Kiri\Rpc\Annotation\JsonRpc;
|
||||
use Http\Handler\Controller;
|
||||
use Rpc\\' . ucfirst($name) . 'RpcInterface;
|
||||
|
||||
|
||||
#[Target]
|
||||
#[JsonRpc(service: \'' . $name . '\', version: \'2.0\')]
|
||||
class ' . ucfirst($name) . 'RpcConsumer extends Controller implements ' . ucfirst($name) . 'RpcInterface
|
||||
{
|
||||
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$name = ucfirst($name) . 'RpcConsumer.php';
|
||||
if (!is_dir(APP_PATH . '/rpc/Consumers/')) {
|
||||
mkdir(APP_PATH . '/rpc/Consumers/');
|
||||
}
|
||||
file_put_contents(APP_PATH . '/rpc/Consumers/' . $name, $html);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+72
-72
@@ -1,72 +1,72 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiMiddleware
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiMiddleware extends GiiBase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name');
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Server\Constrict\RequestInterface;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . 'Middleware
|
||||
* @package App\Middleware
|
||||
*/
|
||||
class ' . $managerName . 'Middleware implements Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Closure $closure
|
||||
* @return mixed
|
||||
*/
|
||||
public function handler(RequestInterface $request, Closure $closure)
|
||||
{
|
||||
return $closure($request);
|
||||
}
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$file = APP_PATH . 'app/Http/Middleware/' . $managerName . 'Middleware.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . 'Middleware.php'];
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiMiddleware
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiMiddleware extends GiiBase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name');
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Server\Constrict\RequestInterface;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . 'Middleware
|
||||
* @package App\Middleware
|
||||
*/
|
||||
class ' . $managerName . 'Middleware implements Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Closure $closure
|
||||
* @return mixed
|
||||
*/
|
||||
public function handler(RequestInterface $request, Closure $closure)
|
||||
{
|
||||
return $closure($request);
|
||||
}
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$file = APP_PATH . 'app/Http/Middleware/' . $managerName . 'Middleware.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . 'Middleware.php'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+426
-426
@@ -1,426 +1,426 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
use Database\Db;
|
||||
use Database\Model;
|
||||
use Exception;
|
||||
use ReflectionException;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiModel
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiModel extends GiiBase
|
||||
{
|
||||
|
||||
public ?string $classFileName;
|
||||
public ?array $visible;
|
||||
public ?array $res;
|
||||
public ?array $fields;
|
||||
|
||||
/**
|
||||
* GiiModel constructor.
|
||||
* @param string $classFileName
|
||||
* @param string $tableName
|
||||
* @param array $visible
|
||||
* @param array $res
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct(string $classFileName, string $tableName, array $visible, array $res, array $fields)
|
||||
{
|
||||
$this->classFileName = $classFileName;
|
||||
$this->tableName = $tableName;
|
||||
$this->visible = $visible;
|
||||
$this->res = $res;
|
||||
$this->fields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
$class = '';
|
||||
$modelPath = $this->getModelPath();
|
||||
$managerName = $this->classFileName;
|
||||
|
||||
$namespace = rtrim($modelPath['namespace'], '\\');
|
||||
|
||||
if (file_exists($modelPath['path'] . '/' . $managerName . '.php')) {
|
||||
try {
|
||||
$className = str_replace('\\\\', '\\', "{$modelPath['namespace']}\\{$managerName}");
|
||||
|
||||
$class = Kiri::getDi()->getReflect($className);
|
||||
|
||||
$html = '<?php
|
||||
namespace ' . $namespace . ';
|
||||
|
||||
';
|
||||
$imports = $this->getImports($modelPath['path'] . '/' . $managerName . '.php', $class);
|
||||
if (!empty($imports)) {
|
||||
$html .= $imports . PHP_EOL;
|
||||
}
|
||||
|
||||
if (!str_contains($imports, 'Database\Annotation\Set')) {
|
||||
$html .= 'use Database\Annotation\Set;' . PHP_EOL;
|
||||
}
|
||||
if (!str_contains($imports, 'Database\Annotation\Get')) {
|
||||
$html .= 'use Database\Annotation\Get;' . PHP_EOL;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
logger()->addError($e, 'throwable');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (empty($html)) {
|
||||
$html = '<?php
|
||||
namespace ' . $namespace . ';
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Annotation\Target;
|
||||
use Kiri\Core\Json;
|
||||
use Database\Connection;
|
||||
use Database\Annotation\Get;
|
||||
use Database\Annotation\Set;
|
||||
use Database\Relation;
|
||||
use Database\Model;
|
||||
' . PHP_EOL;
|
||||
}
|
||||
|
||||
$createSql = $this->setCreateSql($this->tableName);
|
||||
|
||||
if (!str_contains($html, $createSql)) {
|
||||
$html .= '
|
||||
' . $this->setCreateSql($this->tableName);
|
||||
}
|
||||
|
||||
$html .= '
|
||||
|
||||
/**
|
||||
* Class ' . $managerName . '
|
||||
* @package Inter\mysql
|
||||
*' . implode('', $this->visible) . '
|
||||
*/
|
||||
#[Target] class ' . $managerName . ' extends Model
|
||||
{
|
||||
|
||||
';
|
||||
|
||||
if (!empty($class)) {
|
||||
$html .= $this->getClassProperty($class);
|
||||
}
|
||||
|
||||
$primary = $this->createPrimary($this->fields);
|
||||
if (!empty($primary)) {
|
||||
$html .= $primary . "\n";
|
||||
}
|
||||
|
||||
$html .= $this->createTableName($this->tableName) . "\n";
|
||||
|
||||
$html .= $this->createDatabaseSource();
|
||||
|
||||
$html .= $this->createRules($this->fields);
|
||||
|
||||
if (is_object($class)) {
|
||||
$html .= $this->getClassMethods($class, ['rules', 'tableName', 'attributes', 'getDb']);
|
||||
} else {
|
||||
$other = $this->generate_json_function($html, $this->fields);
|
||||
if (!empty($other)) {
|
||||
$html .= implode($other);
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '
|
||||
}';
|
||||
|
||||
$file = rtrim($modelPath['path'], '/') . '/' . $managerName . '.php';
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return $managerName . '.php';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $html
|
||||
* @param $fields
|
||||
* @return array
|
||||
*/
|
||||
private function generate_json_function($html, $fields): array
|
||||
{
|
||||
$strings = [];
|
||||
foreach ($fields as $field) {
|
||||
if ($field['Type'] === 'json') {
|
||||
$function = '
|
||||
/**
|
||||
* @param $value
|
||||
* @return int|bool|string
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Set(\'' . $field['Field'] . '\')]
|
||||
public function set' . ucfirst($field['Field']) . 'Attribute($value): int|bool|string
|
||||
{
|
||||
if ( !is_string($value) ) {
|
||||
return JSON::encode($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
';
|
||||
|
||||
$get_function = '
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|null|bool
|
||||
*/
|
||||
#[Get(\'' . $field['Field'] . '\')]
|
||||
public function get' . ucfirst($field['Field']) . 'Attribute($value): array|null|bool
|
||||
{
|
||||
$value = stripcslashes($value);
|
||||
if ( is_string($value) ) {
|
||||
return JSON::decode($value, true);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
';
|
||||
|
||||
if (!str_contains($html, 'set' . ucfirst($field['Field']) . 'Attribute')) {
|
||||
$strings[] = $function;
|
||||
}
|
||||
|
||||
if (!str_contains($html, 'get' . ucfirst($field['Field']) . 'Attribute')) {
|
||||
$strings[] = $get_function;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @return string
|
||||
* 创建表名称
|
||||
*/
|
||||
private function createTableName($field): string
|
||||
{
|
||||
|
||||
$prefixed = $this->db->tablePrefix;
|
||||
if (!empty($prefixed)) {
|
||||
if (str_starts_with($field, $prefixed)) {
|
||||
$field = str_replace($prefixed, '', $field);
|
||||
}
|
||||
}
|
||||
|
||||
return '
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected string $table = \'' . $field . '\';
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fields
|
||||
* @return string
|
||||
* 创建效验规则
|
||||
*/
|
||||
private function createRules($fields): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($fields as $key => $val) {
|
||||
if ($val['Extra'] == 'auto_increment') continue;
|
||||
$type = preg_replace('/\(.*?\)|\s+\w+/', '', $val['Type']);
|
||||
foreach ($this->type as $_key => $_val) {
|
||||
if (in_array($type, $_val)) {
|
||||
$type = lcfirst(str_replace('get', '', $_key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
$data[$type][] = $val;
|
||||
}
|
||||
|
||||
$_field_one = '';
|
||||
$required = $this->getRequired($fields);
|
||||
if (!empty($required)) {
|
||||
$_field_one .= $required;
|
||||
}
|
||||
foreach ($data as $key => $val) {
|
||||
$field = '[\'' . implode('\', \'', array_column($val, 'Field')) . '\']';
|
||||
if (count($val) == 1) {
|
||||
$field = '\'' . current($val)['Field'] . '\'';
|
||||
}
|
||||
$_field_one .= '
|
||||
[' . $field . ', \'' . $key . '\'],';
|
||||
}
|
||||
foreach ($data as $key => $val) {
|
||||
$length = $this->getLength($val);
|
||||
if (!empty($length)) {
|
||||
$_field_one .= $length . ',';
|
||||
}
|
||||
}
|
||||
$required = $this->getUnique($fields);
|
||||
if (!empty($required)) {
|
||||
$_field_one .= $required;
|
||||
}
|
||||
return '
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [' . $_field_one . '
|
||||
];
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
* @return string
|
||||
*/
|
||||
public function getLength($val): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($val as $key => $_val) {
|
||||
$preg = preg_match('/(\w+)\((.*?)\)/', $_val['Type'], $results);
|
||||
if ($preg && isset($results[2])) {
|
||||
$results[] = $_val['Field'];
|
||||
|
||||
$data[$results[2]][] = $results;
|
||||
}
|
||||
}
|
||||
if (empty($data)) return '';
|
||||
$string = [];
|
||||
foreach ($data as $key => $_val) {
|
||||
if (in_array($_val[0][1], $this->type['float'])) {
|
||||
$e_x = explode(',', $key);
|
||||
$key = '\'round\' => ' . $e_x[1] . ', \'maxLength\' => ' . ((int)$e_x[0] + 1);
|
||||
} else if (is_string($key) && str_contains($key, ',')) {
|
||||
} else {
|
||||
$key = '\'maxLength\' => ' . $key;
|
||||
}
|
||||
if (count($_val) == 1) {
|
||||
$_tmp = '
|
||||
[\'' . $_val[0][3] . '\', ' . ($_val[0][1] == 'enum' ? '\'enum\' => [' . $key .']' : $key) . ']';
|
||||
} else {
|
||||
$_tmp = '
|
||||
[[\'' . implode('\', \'', array_column($_val, 3)) . '\'], ' . $key . ']';
|
||||
}
|
||||
$string[] = $_tmp;
|
||||
}
|
||||
return implode(',', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fields
|
||||
* @return string
|
||||
*/
|
||||
public function getUnique($fields): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($fields as $_val) {
|
||||
if ($_val['Extra'] == 'auto_increment') continue;
|
||||
if (str_contains($_val['Type'], 'unique')) {
|
||||
$data[] = $_val['Field'];
|
||||
}
|
||||
}
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
return '
|
||||
[[\'' . implode('\', \'', $data) . '\'], \'unique\'],';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
* @return string
|
||||
*/
|
||||
public function getRequired($val): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($val as $_key => $_val) {
|
||||
if ($_val['Extra'] == 'auto_increment') continue;
|
||||
if ($_val['Key'] == 'PRI' || $_val['Key'] == 'UNI' || $this->checkIsRequired($_val) === 'true') {
|
||||
array_push($data, $_val['Field']);
|
||||
}
|
||||
}
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
return '
|
||||
[[\'' . implode('\', \'', $data) . '\'], \'required\'],';
|
||||
}
|
||||
|
||||
/**
|
||||
* 用来生成文档的
|
||||
* 格式
|
||||
* @param $fields
|
||||
* @return null|string
|
||||
* array(
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* )
|
||||
*/
|
||||
private function createPrimary($fields): ?string
|
||||
{
|
||||
$field = $this->getPrimaryKey($fields);
|
||||
if (empty($field)) {
|
||||
return null;
|
||||
}
|
||||
return '
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected ?string $primary = \'' . $field . '\';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function createDatabaseSource(): string
|
||||
{
|
||||
return '
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $connection = \'' . $this->db->id . '\';
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setCreateSql($table): string
|
||||
{
|
||||
if (isset(Gii::$createSqls[$table])) {
|
||||
return Gii::$createSqls[$table];
|
||||
}
|
||||
|
||||
$text = Db::showCreateSql($table, $this->db)['Create Table'] ?? '';
|
||||
|
||||
$_tmp = [];
|
||||
foreach (explode(PHP_EOL, $text) as $val) {
|
||||
$_tmp[] = '// ' . $val;
|
||||
}
|
||||
|
||||
return Gii::$createSqls[$table] = implode(PHP_EOL, $_tmp);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
use Database\Db;
|
||||
use Database\Model;
|
||||
use Exception;
|
||||
use ReflectionException;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiModel
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiModel extends GiiBase
|
||||
{
|
||||
|
||||
public ?string $classFileName;
|
||||
public ?array $visible;
|
||||
public ?array $res;
|
||||
public ?array $fields;
|
||||
|
||||
/**
|
||||
* GiiModel constructor.
|
||||
* @param string $classFileName
|
||||
* @param string $tableName
|
||||
* @param array $visible
|
||||
* @param array $res
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct(string $classFileName, string $tableName, array $visible, array $res, array $fields)
|
||||
{
|
||||
$this->classFileName = $classFileName;
|
||||
$this->tableName = $tableName;
|
||||
$this->visible = $visible;
|
||||
$this->res = $res;
|
||||
$this->fields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): string
|
||||
{
|
||||
$class = '';
|
||||
$modelPath = $this->getModelPath();
|
||||
$managerName = $this->classFileName;
|
||||
|
||||
$namespace = rtrim($modelPath['namespace'], '\\');
|
||||
|
||||
if (file_exists($modelPath['path'] . '/' . $managerName . '.php')) {
|
||||
try {
|
||||
$className = str_replace('\\\\', '\\', "{$modelPath['namespace']}\\{$managerName}");
|
||||
|
||||
$class = Kiri::getDi()->getReflect($className);
|
||||
|
||||
$html = '<?php
|
||||
namespace ' . $namespace . ';
|
||||
|
||||
';
|
||||
$imports = $this->getImports($modelPath['path'] . '/' . $managerName . '.php', $class);
|
||||
if (!empty($imports)) {
|
||||
$html .= $imports . PHP_EOL;
|
||||
}
|
||||
|
||||
if (!str_contains($imports, 'Database\Annotation\Set')) {
|
||||
$html .= 'use Database\Annotation\Set;' . PHP_EOL;
|
||||
}
|
||||
if (!str_contains($imports, 'Database\Annotation\Get')) {
|
||||
$html .= 'use Database\Annotation\Get;' . PHP_EOL;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
logger()->addError($e, 'throwable');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (empty($html)) {
|
||||
$html = '<?php
|
||||
namespace ' . $namespace . ';
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Annotation\Target;
|
||||
use Kiri\Core\Json;
|
||||
use Database\Connection;
|
||||
use Database\Annotation\Get;
|
||||
use Database\Annotation\Set;
|
||||
use Database\Relation;
|
||||
use Database\Model;
|
||||
' . PHP_EOL;
|
||||
}
|
||||
|
||||
$createSql = $this->setCreateSql($this->tableName);
|
||||
|
||||
if (!str_contains($html, $createSql)) {
|
||||
$html .= '
|
||||
' . $this->setCreateSql($this->tableName);
|
||||
}
|
||||
|
||||
$html .= '
|
||||
|
||||
/**
|
||||
* Class ' . $managerName . '
|
||||
* @package Inter\mysql
|
||||
*' . implode('', $this->visible) . '
|
||||
*/
|
||||
#[Target] class ' . $managerName . ' extends Model
|
||||
{
|
||||
|
||||
';
|
||||
|
||||
if (!empty($class)) {
|
||||
$html .= $this->getClassProperty($class);
|
||||
}
|
||||
|
||||
$primary = $this->createPrimary($this->fields);
|
||||
if (!empty($primary)) {
|
||||
$html .= $primary . "\n";
|
||||
}
|
||||
|
||||
$html .= $this->createTableName($this->tableName) . "\n";
|
||||
|
||||
$html .= $this->createDatabaseSource();
|
||||
|
||||
$html .= $this->createRules($this->fields);
|
||||
|
||||
if (is_object($class)) {
|
||||
$html .= $this->getClassMethods($class, ['rules', 'tableName', 'attributes', 'getDb']);
|
||||
} else {
|
||||
$other = $this->generate_json_function($html, $this->fields);
|
||||
if (!empty($other)) {
|
||||
$html .= implode($other);
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '
|
||||
}';
|
||||
|
||||
$file = rtrim($modelPath['path'], '/') . '/' . $managerName . '.php';
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return $managerName . '.php';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $html
|
||||
* @param $fields
|
||||
* @return array
|
||||
*/
|
||||
private function generate_json_function($html, $fields): array
|
||||
{
|
||||
$strings = [];
|
||||
foreach ($fields as $field) {
|
||||
if ($field['Type'] === 'json') {
|
||||
$function = '
|
||||
/**
|
||||
* @param $value
|
||||
* @return int|bool|string
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Set(\'' . $field['Field'] . '\')]
|
||||
public function set' . ucfirst($field['Field']) . 'Attribute($value): int|bool|string
|
||||
{
|
||||
if ( !is_string($value) ) {
|
||||
return JSON::encode($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
';
|
||||
|
||||
$get_function = '
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|null|bool
|
||||
*/
|
||||
#[Get(\'' . $field['Field'] . '\')]
|
||||
public function get' . ucfirst($field['Field']) . 'Attribute($value): array|null|bool
|
||||
{
|
||||
$value = stripcslashes($value);
|
||||
if ( is_string($value) ) {
|
||||
return JSON::decode($value, true);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
';
|
||||
|
||||
if (!str_contains($html, 'set' . ucfirst($field['Field']) . 'Attribute')) {
|
||||
$strings[] = $function;
|
||||
}
|
||||
|
||||
if (!str_contains($html, 'get' . ucfirst($field['Field']) . 'Attribute')) {
|
||||
$strings[] = $get_function;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @return string
|
||||
* 创建表名称
|
||||
*/
|
||||
private function createTableName($field): string
|
||||
{
|
||||
|
||||
$prefixed = $this->db->tablePrefix;
|
||||
if (!empty($prefixed)) {
|
||||
if (str_starts_with($field, $prefixed)) {
|
||||
$field = str_replace($prefixed, '', $field);
|
||||
}
|
||||
}
|
||||
|
||||
return '
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected string $table = \'' . $field . '\';
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fields
|
||||
* @return string
|
||||
* 创建效验规则
|
||||
*/
|
||||
private function createRules($fields): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($fields as $key => $val) {
|
||||
if ($val['Extra'] == 'auto_increment') continue;
|
||||
$type = preg_replace('/\(.*?\)|\s+\w+/', '', $val['Type']);
|
||||
foreach ($this->type as $_key => $_val) {
|
||||
if (in_array($type, $_val)) {
|
||||
$type = lcfirst(str_replace('get', '', $_key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
$data[$type][] = $val;
|
||||
}
|
||||
|
||||
$_field_one = '';
|
||||
$required = $this->getRequired($fields);
|
||||
if (!empty($required)) {
|
||||
$_field_one .= $required;
|
||||
}
|
||||
foreach ($data as $key => $val) {
|
||||
$field = '[\'' . implode('\', \'', array_column($val, 'Field')) . '\']';
|
||||
if (count($val) == 1) {
|
||||
$field = '\'' . current($val)['Field'] . '\'';
|
||||
}
|
||||
$_field_one .= '
|
||||
[' . $field . ', \'' . $key . '\'],';
|
||||
}
|
||||
foreach ($data as $key => $val) {
|
||||
$length = $this->getLength($val);
|
||||
if (!empty($length)) {
|
||||
$_field_one .= $length . ',';
|
||||
}
|
||||
}
|
||||
$required = $this->getUnique($fields);
|
||||
if (!empty($required)) {
|
||||
$_field_one .= $required;
|
||||
}
|
||||
return '
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [' . $_field_one . '
|
||||
];
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
* @return string
|
||||
*/
|
||||
public function getLength($val): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($val as $key => $_val) {
|
||||
$preg = preg_match('/(\w+)\((.*?)\)/', $_val['Type'], $results);
|
||||
if ($preg && isset($results[2])) {
|
||||
$results[] = $_val['Field'];
|
||||
|
||||
$data[$results[2]][] = $results;
|
||||
}
|
||||
}
|
||||
if (empty($data)) return '';
|
||||
$string = [];
|
||||
foreach ($data as $key => $_val) {
|
||||
if (in_array($_val[0][1], $this->type['float'])) {
|
||||
$e_x = explode(',', $key);
|
||||
$key = '\'round\' => ' . $e_x[1] . ', \'maxLength\' => ' . ((int)$e_x[0] + 1);
|
||||
} else if (is_string($key) && str_contains($key, ',')) {
|
||||
} else {
|
||||
$key = '\'maxLength\' => ' . $key;
|
||||
}
|
||||
if (count($_val) == 1) {
|
||||
$_tmp = '
|
||||
[\'' . $_val[0][3] . '\', ' . ($_val[0][1] == 'enum' ? '\'enum\' => [' . $key .']' : $key) . ']';
|
||||
} else {
|
||||
$_tmp = '
|
||||
[[\'' . implode('\', \'', array_column($_val, 3)) . '\'], ' . $key . ']';
|
||||
}
|
||||
$string[] = $_tmp;
|
||||
}
|
||||
return implode(',', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fields
|
||||
* @return string
|
||||
*/
|
||||
public function getUnique($fields): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($fields as $_val) {
|
||||
if ($_val['Extra'] == 'auto_increment') continue;
|
||||
if (str_contains($_val['Type'], 'unique')) {
|
||||
$data[] = $_val['Field'];
|
||||
}
|
||||
}
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
return '
|
||||
[[\'' . implode('\', \'', $data) . '\'], \'unique\'],';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $val
|
||||
* @return string
|
||||
*/
|
||||
public function getRequired($val): string
|
||||
{
|
||||
$data = [];
|
||||
foreach ($val as $_key => $_val) {
|
||||
if ($_val['Extra'] == 'auto_increment') continue;
|
||||
if ($_val['Key'] == 'PRI' || $_val['Key'] == 'UNI' || $this->checkIsRequired($_val) === 'true') {
|
||||
array_push($data, $_val['Field']);
|
||||
}
|
||||
}
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
return '
|
||||
[[\'' . implode('\', \'', $data) . '\'], \'required\'],';
|
||||
}
|
||||
|
||||
/**
|
||||
* 用来生成文档的
|
||||
* 格式
|
||||
* @param $fields
|
||||
* @return null|string
|
||||
* array(
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* 'field' ,'字段類型' ,'是否必填' ,'字段长度' , '字段解释',
|
||||
* )
|
||||
*/
|
||||
private function createPrimary($fields): ?string
|
||||
{
|
||||
$field = $this->getPrimaryKey($fields);
|
||||
if (empty($field)) {
|
||||
return null;
|
||||
}
|
||||
return '
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected ?string $primary = \'' . $field . '\';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function createDatabaseSource(): string
|
||||
{
|
||||
return '
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $connection = \'' . $this->db->id . '\';
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setCreateSql($table): string
|
||||
{
|
||||
if (isset(Gii::$createSqls[$table])) {
|
||||
return Gii::$createSqls[$table];
|
||||
}
|
||||
|
||||
$text = Db::showCreateSql($table, $this->db)['Create Table'] ?? '';
|
||||
|
||||
$_tmp = [];
|
||||
foreach (explode(PHP_EOL, $text) as $val) {
|
||||
$_tmp[] = '// ' . $val;
|
||||
}
|
||||
|
||||
return Gii::$createSqls[$table] = implode(PHP_EOL, $_tmp);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+34
-34
@@ -1,34 +1,34 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Providers;
|
||||
use Kiri\Application;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class DatabasesProviders
|
||||
* @package Database
|
||||
*/
|
||||
class GiiProviders extends Providers
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onImport(Application $application)
|
||||
{
|
||||
$application->set('gii', ['class' => Gii::class]);
|
||||
|
||||
$container = Kiri::getDi();
|
||||
|
||||
$console = $container->get(\Symfony\Component\Console\Application::class);
|
||||
$console->add($container->get(GiiCommand::class));
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Providers;
|
||||
use Kiri\Application;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class DatabasesProviders
|
||||
* @package Database
|
||||
*/
|
||||
class GiiProviders extends Providers
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onImport(Application $application)
|
||||
{
|
||||
$application->set('gii', ['class' => Gii::class]);
|
||||
|
||||
$container = Kiri::getDi();
|
||||
|
||||
$console = $container->get(\Symfony\Component\Console\Application::class);
|
||||
$console->add($container->get(GiiCommand::class));
|
||||
}
|
||||
}
|
||||
|
||||
+99
-99
@@ -1,99 +1,99 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiRpcClient
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiRpcClient extends GiiBase
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name', null);
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
|
||||
$service = $this->input->getArgument('service', strtolower($managerName));
|
||||
|
||||
$port = $this->input->getArgument('port', 443);
|
||||
$mode = $this->input->getArgument('mode', 'SWOOLE_SOCK_TCP');
|
||||
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Client\Rpc;
|
||||
|
||||
use Kiri\Annotation\Rpc\Consumer;
|
||||
use Kiri\Annotation\Rpc\RpcClient;
|
||||
use Kiri\Annotation\Target;
|
||||
use Exception;
|
||||
use Rpc\Client;
|
||||
use Kiri\Core\Json;
|
||||
use Kiri\Kiri;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . 'Consumer
|
||||
* @package App\Client\Rpc
|
||||
*/
|
||||
#[Target]
|
||||
#[RpcClient(cmd: \'' . $service . '\', port: ' . $port . ', timeout: 1, mode: ' . $mode . ')]
|
||||
class ' . $managerName . 'Consumer extends \Rpc\Consumer
|
||||
{
|
||||
|
||||
public array $node = [\'host\' => \'127.0.0.1\', \'port\' => 5377];
|
||||
|
||||
|
||||
/**
|
||||
* @return Client
|
||||
* @throws Exception
|
||||
*/
|
||||
public function initClient(): Client
|
||||
{
|
||||
// TODO: Implement initClient() method.
|
||||
return $this->client = $this->rpc->getClient(\'' . $service . '\');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $event
|
||||
* @param array $params
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Consumer(\'default\')]
|
||||
public function push(string $event, array $params)
|
||||
{
|
||||
|
||||
}
|
||||
}';
|
||||
|
||||
if (!is_dir(APP_PATH . 'app/Client/Rpc/')) {
|
||||
mkdir(APP_PATH . 'app/Client/Rpc/', 0777, true);
|
||||
}
|
||||
|
||||
$file = APP_PATH . 'app/Client/Rpc/' . $managerName . 'Middleware.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . 'Middleware.php'];
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiRpcClient
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiRpcClient extends GiiBase
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name', null);
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
|
||||
$service = $this->input->getArgument('service', strtolower($managerName));
|
||||
|
||||
$port = $this->input->getArgument('port', 443);
|
||||
$mode = $this->input->getArgument('mode', 'SWOOLE_SOCK_TCP');
|
||||
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Client\Rpc;
|
||||
|
||||
use Kiri\Annotation\Rpc\Consumer;
|
||||
use Kiri\Annotation\Rpc\RpcClient;
|
||||
use Kiri\Annotation\Target;
|
||||
use Exception;
|
||||
use Rpc\Client;
|
||||
use Kiri\Core\Json;
|
||||
use Kiri\Kiri;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . 'Consumer
|
||||
* @package App\Client\Rpc
|
||||
*/
|
||||
#[Target]
|
||||
#[RpcClient(cmd: \'' . $service . '\', port: ' . $port . ', timeout: 1, mode: ' . $mode . ')]
|
||||
class ' . $managerName . 'Consumer extends \Rpc\Consumer
|
||||
{
|
||||
|
||||
public array $node = [\'host\' => \'127.0.0.1\', \'port\' => 5377];
|
||||
|
||||
|
||||
/**
|
||||
* @return Client
|
||||
* @throws Exception
|
||||
*/
|
||||
public function initClient(): Client
|
||||
{
|
||||
// TODO: Implement initClient() method.
|
||||
return $this->client = $this->rpc->getClient(\'' . $service . '\');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $event
|
||||
* @param array $params
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Consumer(\'default\')]
|
||||
public function push(string $event, array $params)
|
||||
{
|
||||
|
||||
}
|
||||
}';
|
||||
|
||||
if (!is_dir(APP_PATH . 'app/Client/Rpc/')) {
|
||||
mkdir(APP_PATH . 'app/Client/Rpc/', 0777, true);
|
||||
}
|
||||
|
||||
$file = APP_PATH . 'app/Client/Rpc/' . $managerName . 'Middleware.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . 'Middleware.php'];
|
||||
}
|
||||
}
|
||||
|
||||
+78
-78
@@ -1,78 +1,78 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiRpcClient
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiRpcService extends GiiBase
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name', null);
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
|
||||
$port = $this->input->getArgument('port', 443);
|
||||
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Rpc;
|
||||
|
||||
use Kiri\Annotation\Route\RpcProducer;
|
||||
use Kiri\Annotation\Target;
|
||||
use Exception;
|
||||
use Http\Controller;
|
||||
use Kiri\Core\Json;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . 'Consumer
|
||||
* @package App\Client\Rpc
|
||||
*/
|
||||
#[Target]
|
||||
class ' . $managerName . 'Producer extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @throws Exception
|
||||
*/
|
||||
#[RpcProducer(cmd: \'default\', port: ' . $port . ')]
|
||||
public function actionIndex(array $params)
|
||||
{
|
||||
|
||||
}
|
||||
}';
|
||||
|
||||
if (!is_dir(APP_PATH . 'app/Http/Rpc/')) {
|
||||
mkdir(APP_PATH . 'app/Http/Rpc/', 0777, true);
|
||||
}
|
||||
|
||||
$file = APP_PATH . 'app/Http/Rpc/' . $managerName . 'Producer.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . 'Producer.php'];
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiRpcClient
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiRpcService extends GiiBase
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name', null);
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
|
||||
$port = $this->input->getArgument('port', 443);
|
||||
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Rpc;
|
||||
|
||||
use Kiri\Annotation\Route\RpcProducer;
|
||||
use Kiri\Annotation\Target;
|
||||
use Exception;
|
||||
use Http\Controller;
|
||||
use Kiri\Core\Json;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . 'Consumer
|
||||
* @package App\Client\Rpc
|
||||
*/
|
||||
#[Target]
|
||||
class ' . $managerName . 'Producer extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @throws Exception
|
||||
*/
|
||||
#[RpcProducer(cmd: \'default\', port: ' . $port . ')]
|
||||
public function actionIndex(array $params)
|
||||
{
|
||||
|
||||
}
|
||||
}';
|
||||
|
||||
if (!is_dir(APP_PATH . 'app/Http/Rpc/')) {
|
||||
mkdir(APP_PATH . 'app/Http/Rpc/', 0777, true);
|
||||
}
|
||||
|
||||
$file = APP_PATH . 'app/Http/Rpc/' . $managerName . 'Producer.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . 'Producer.php'];
|
||||
}
|
||||
}
|
||||
|
||||
+90
-90
@@ -1,90 +1,90 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiModel
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiTask extends GiiBase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name', null);
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Async;
|
||||
|
||||
use Server\Contract\OnTaskInterface;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . '
|
||||
* @package App\Async
|
||||
*/
|
||||
class ' . $managerName . ' implements Task
|
||||
{
|
||||
|
||||
protected $params = [];
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function onHandler()
|
||||
{
|
||||
// TODO: Implement handler() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
* @return $this
|
||||
*/
|
||||
public function setParams(array $params)
|
||||
{
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$file = APP_PATH . 'app/Async/' . $managerName . '.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . '.php'];
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Gii;
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class GiiModel
|
||||
* @package Gii
|
||||
*/
|
||||
class GiiTask extends GiiBase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generate(): array
|
||||
{
|
||||
|
||||
$managerName = $this->input->getArgument('name', null);
|
||||
if (empty($managerName)) {
|
||||
throw new Exception('文件名称不能为空~');
|
||||
}
|
||||
$html = '<?php
|
||||
|
||||
|
||||
namespace App\Async;
|
||||
|
||||
use Server\Contract\OnTaskInterface;
|
||||
|
||||
';
|
||||
|
||||
$managerName = ucfirst($managerName);
|
||||
$html .= '
|
||||
/**
|
||||
* Class ' . $managerName . '
|
||||
* @package App\Async
|
||||
*/
|
||||
class ' . $managerName . ' implements Task
|
||||
{
|
||||
|
||||
protected $params = [];
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function onHandler()
|
||||
{
|
||||
// TODO: Implement handler() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
* @return $this
|
||||
*/
|
||||
public function setParams(array $params)
|
||||
{
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
|
||||
}';
|
||||
|
||||
$file = APP_PATH . 'app/Async/' . $managerName . '.php';
|
||||
if (file_exists($file)) {
|
||||
throw new Exception('File exists.');
|
||||
}
|
||||
|
||||
Kiri::writeFile($file, $html);
|
||||
return [$managerName . '.php'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user