This commit is contained in:
2020-09-07 17:12:46 +08:00
parent 08298ba09e
commit a19e1c4f24
5 changed files with 1450 additions and 1 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ use Snowflake\Abstracts\Component;
/**
* Class Relation
* @package BeReborn\db
* @package Snowflake\db
*/
class Relation extends Component
{
+289
View File
@@ -0,0 +1,289 @@
<?php
/**
* Created by PhpStorm.
* User: 向林
* Date: 2016/8/9 0009
* Time: 17:43
*/
namespace Snowflake\Gii;
use Database\Connection;
use Database\Db;
use Exception;
use Snowflake\Exception\ComponentException;
use Snowflake\Exception\ConfigException;
use Snowflake\Snowflake;
/**
* Class gii
*
* @package Inter\utility
*/
class Gii
{
private $tableName = NULL;
/** @var Connection */
private $db;
public $modelPath = APP_PATH . '/models/';
public $modelNamespace = 'models\\';
public $controllerPath = APP_PATH . '/app/Controllers/';
public $controllerNamespace = 'App\\Controllers\\';
public $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'
];
/**
* @var bool
*/
private $isUpdate = false;
/**
* @param Connection|null $db
*
* @return array
* @throws ComponentException
* @throws ConfigException
* @throws Exception
*/
public static function run(Connection $db = NULL)
{
$gii = new Gii();
if (!empty($db)) $gii->db = $db;
if (!$gii->db) {
$db = Input()->get('databases', 'db');
$gii->db = Snowflake::app()->db->get($db);
}
$redis = Snowflake::app()->getRedis();
if (!empty(Input()->get('t'))) {
$gii->tableName = Input()->get('t');
$redis->del('column:' . $gii->tableName);
}
if (Input()->get('m', NULL)) {
$model = 1;
}
if (Input()->get('c', NULL)) {
$c = 1;
}
if (Input()->get('isUpdate') == 1) {
$gii->isUpdate = TRUE;
}
return $gii->getTable($c, $model);
}
/**
* @param $m
* @param $c
* @return array
*
* @throws Exception
*/
private function getTable(&$c, &$m)
{
$tables = $this->getFields($this->getTables());
if (empty($tables)) {
return [];
}
$fileList = [];
foreach ($tables as $key => $val) {
$data = $this->createModelFile($key, $val);
if ($m == 1) {
$fileList[] = $this->generateModel($data);
}
if ($c == 1) {
$fileList[] = $this->generateController($data);
}
}
return $fileList;
}
/**
* @param array $data
* @return string
* @throws Exception
*/
private function generateModel(array $data)
{
$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->setModule(Input()->get('module', null));
$controller->setControllerPath($this->controllerPath);
$controller->setControllerNamespace($this->controllerNamespace);
return $controller->generate();
}
/**
* @param array $data
* @return string
* @throws Exception
*/
private function generateController(array $data)
{
$controller = new GiiController($data['classFileName'], $data['fields']);
$controller->setConnection($this->db);
$controller->setModelPath($this->modelPath);
$controller->setModelNamespace($this->modelNamespace);
$controller->setControllerPath($this->controllerPath);
$controller->setModule(Input()->get('module', null));
$controller->setControllerNamespace($this->controllerNamespace);
return $controller->generate();
}
/**
* @return array|null
* @throws Exception
*/
private function getTables()
{
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()
{
$res = [];
$_tables = Db::findAllBySql('show tables', [], $this->db);
if (empty($_tables)) {
return $res;
}
foreach ($_tables as $key => $val) {
$res[] = array_shift($val);
}
return $res;
}
/**
* @param $table
* @return bool|int
* @throws Exception
*/
private function getIndex($table)
{
$data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db);
return empty($data) ? NULL : $data[0];
}
/**
* @param $tables
*
* @return array
* @throws
*/
private function getFields($tables)
{
$res = [];
if (!is_array($tables)) {
$tables = [$tables];
}
foreach ($tables as $key => $val) {
if (empty($val)) continue;
$_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM ' . $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)
{
$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)
{
return '
* @property $' . $field;
}
/**
* @param $field
* @param $comment
* @return string
* 暂时不知道干嘛用的
*/
private function createSetFunc($field, $comment)
{
return '
' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
}
/**
* @param $tableName
* @return string
* 构建类名称
*/
private function getClassName($tableName)
{
$res = [];
foreach (explode('_', $tableName) as $n => $val) {
$res[] = ucfirst($val);
}
$name = ucfirst(rtrim($this->db->tablePrefix, '_'));
return implode('', $res);
return str_replace($name, '', implode('', $res)) . 'Comply';
}
}
+218
View File
@@ -0,0 +1,218 @@
<?php
namespace Snowflake\Gii;
use Database\Connection;
/**
* Class GiiBase
* @package Snowflake\Gii
*/
abstract class GiiBase
{
public $fileList = [];
public $modelPath = APP_PATH . '/models/';
public $modelNamespace = 'models\\';
public $controllerPath = APP_PATH . '/app/Controllers/';
public $controllerNamespace = 'App\\Controllers\\';
public $module = null;
public $rules = [];
public $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 $tableName = NULL;
/** @var Connection */
public $db;
/**
* @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 \ReflectionClass $object
* @param $className
*
* @return string
*/
public function getUseContent($object, $className)
{
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 $fields
* @return mixed|null
* 返回表主键
*/
public function getPrimaryKey($fields)
{
$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)
{
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($object, $className, $method)
{
$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()
{
$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)
{
return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false';
}
/**
* @return array
*/
public function getFileLists()
{
return $this->fileList;
}
}
+486
View File
@@ -0,0 +1,486 @@
<?php
namespace Snowflake\Gii;
use Snowflake\Snowflake;
/**
* Class GiiController
* @package Snowflake\Gii
*/
class GiiController extends GiiBase
{
public $className;
public $fields;
public function __construct($className, $fields)
{
$this->className = $className;
$this->fields = $fields;
}
/**
* @return string
* @throws \Exception
*/
public function generate()
{
$path = $this->getControllerPath();
$modelPath = $this->getModelPath();
$managerName = $this->className;
$namespace = rtrim($path['namespace'], '\\');
$model_namespace = rtrim($modelPath['namespace'], '\\');
$prefix = str_replace('_', '', $this->db->tablePrefix);
$managerName = str_replace(ucfirst($prefix), '', $managerName);
$class = '';
$controller = $namespace . '\\' . $managerName . 'Controller';
if (file_exists($path['path'] . '/' . $managerName . 'Controller.php')) {
$class = new \ReflectionClass($controller);
}
$controllerName = $managerName;
$html = $this->getUseContent($class, $controller);
if (empty($html)) {
$html .= "<?php
namespace {$namespace};
use Snowflake;
use Code;
use exception;
use Snowflake\Core\Str;
use Snowflake\Core\JSON;
use Snowflake\Http\Request;
use Snowflake\Http\Response;
use components\ActiveController;
use {$model_namespace}\\{$managerName};
";
}
$historyModel = "use {$model_namespace}\\{$managerName};";
if (strpos($html, $historyModel) === false) {
$html .= $historyModel;
}
$html .= "
/**
* Class {$controllerName}Controller
*
* @package controller
*/
class {$controllerName}Controller extends ActiveController
{
";
$funcNames = [];
if (is_object($class)) {
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
$funcNames = array_column($methods, 'name');
$classFileName = str_replace(APP_PATH, '', $class->getFileName());
if (!empty($methods)) foreach ($methods as $key => $val) {
if ($val->class != $class->getName()) continue;
$html .= "
" . $val->getDocComment() . "\n";
$html .= $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
}
}
if (!Input()->get('--controller-empty', false)) {
$default = ['actionLoadParam', 'actionAdd', 'actionUpdate', 'actionDetail', 'actionDelete', 'actionBatchDelete', 'actionList'];
foreach ($default as $key => $val) {
if (in_array($val, $funcNames)) continue;
$html .= $this->{'controllerMethod' . str_replace('action', '', $val)}($this->fields, $managerName, $managerName) . "\n";
}
}
$html .= '
}';
$file = $path['path'] . '/' . $controllerName . 'Controller.php';
if (file_exists($file)) {
unlink($file);
}
Snowflake::writeFile($file, $html);
return $controllerName . 'Controller.php';
}
/**
* @return array
*/
private function getControllerPath()
{
$dbName = $this->db->id;
if (empty($dbName) || $dbName == 'db') {
$dbName = '';
}
$module = empty($this->module) ? '' : $this->module;
$modelPath['namespace'] = $this->controllerNamespace . $module;
$modelPath['path'] = $this->controllerPath . $module;
if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']);
}
if (!empty($dbName)) {
$modelPath['namespace'] = $this->controllerNamespace . ucfirst($dbName);
$modelPath['path'] = $this->controllerPath . ucfirst($dbName);
}
$modelPath['namespace'] = rtrim($modelPath['namespace'], '\\');
$modelPath['path'] = rtrim($modelPath['path'], '\\');
if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']);
}
return $modelPath;
}
/**
* @param $fields
* @param $className
* @param null $object
* @return string
* 新增
*/
public function controllerMethodAdd($fields, $className, $object = NULL)
{
return '
/**
* @return array
* @throws exception
*/
public function actionAdd()
{
$model = new ' . $className . '();
$model->attributes = $this->loadParam();
if (!$model->save()) {
return JSON::to(500, $model->getLastError());
}
return JSON::to(Code::SUCCESS, $model->toArray());
}';
}
/**
* @param $fields
* @param $className
* @param null $object
* @return string
* 通用
*/
public function controllerMethodLoadParam($fields, $className, $object = NULL)
{
return '
/**
* @return array
* @throws Exception
*/
private function loadParam()
{
return [' . $this->getData($fields) . '
];
}';
}
/**
* @param $fields
* @param $className
* @param null $object
* @return string
* 构建更新
*/
public function controllerMethodUpdate($fields, $className, $object = NULL)
{
return '
/**
* @return array
* @throws exception
*/
public function actionUpdate()
{
$model = ' . $className . '::findOne(Input()->post(\'id\', 0));
if (empty($model)) {
return JSON::to(500, \'指定数据不存在\');
}
$model->attributes = $this->loadParam();
if (!$model->save()) {
return JSON::to(500, $model->getLastError());
}
return JSON::to(Code::SUCCESS, $model->toArray());
}';
}
/**
* @param $fields
* @param $className
* @param null $object
* @return string
* 构建更新
*/
public function controllerMethodBatchDelete($fields, $className, $object = NULL)
{
return '
/**
* @return array
* @throws exception
*/
public function actionBatchDelete()
{
$_key = Input()->array(\'ids\');
$pass = Input()->string(\'password\', true, 32);
if (empty($_key)) {
return JSON::to(500, \'IDS集合不能为空\');
}
$user = $this->request->identity;
if (strcmp(Str::encrypt($pass), $user->password)) {
return JSON::to(500, \'密码错误\');
}
$model = ' . $className . '::find()->in(\'id\', $_key);
if(!$model->delete()){
return JSON::to(500, \'系统繁忙, 请稍后再试!\');
}
return JSON::to(Code::SUCCESS, $model->toArray());
}';
}
/**
* @param $fields
* @param $className
* @param $managerName
* @return string
* 构建详情
*/
public function controllerMethodDetail($fields, $className, $managerName)
{
return '
/**
* @return array
* @throws exception
*/
public function actionDetail()
{
$model = ' . $managerName . '::findOne(Input()->get(\'id\'));
if(empty($model)){
return JSON::to(404, \'Data Not Exists\');
}
return JSON::to(Code::SUCCESS, $model->toArray());
}';
}
/**
* @param $fields
* @param $className
* @param $managerName
* @return string
* 构建删除操作
*/
public function controllerMethodDelete($fields, $className, $managerName)
{
return '
/**
* @return array
* @throws exception
*/
public function actionDelete()
{
$_key = Input()->int(\'id\', true);
$pass = Input()->string(\'password\', true, 32);
$user = $this->request->identity;
if (strcmp(Str::encrypt($pass), $user->password)) {
return JSON::to(500, \'密码错误\');
}
$model = ' . $managerName . '::findOne($_key);
if (empty($model)) {
return JSON::to(500, \'指定数据不存在\');
}
if(!$model->delete()){
return JSON::to(500, $model->getLastError());
}
return JSON::to(Code::SUCCESS, $model);
}';
}
/**
* @param $fields
* @param $className
* @param $managerName
* @param null $object
* @return string
* 构建查询列表
*/
public function controllerMethodList($fields, $className, $managerName, $object = NULL)
{
return '
/**
* @return array
* @throws exception
*/
public function actionList()
{
$pWhere = array();' . $this->getWhere($fields) . '
//分页处理
$count = Input()->get(\'count\', -1);
$order = Input()->get(\'order\', \'id\');
if(!empty($order)) {
$order .= !Input()->get(\'isDesc\', 0) ? \' asc\' : \' desc\';
}else{
$order = \'id desc\';
}
//列表输出
$model = ' . $managerName . '::find()->where($pWhere)->orderBy($order);
if((int) $count === 1){
$count = $model->count();
}
if($count != -100){
$model->limit(Input()->offset() ,Input()->size());
}
$data = $model->all()->toArray();
return JSON::to(Code::SUCCESS, $data, $count);
}
';
}
private function getData($fields)
{
$html = '';
$length = $this->getMaxLength($fields);
foreach ($fields as $key => $val) {
preg_match('/\((\d+)(,(\d+))*\)/', $val['Type'], $number);
$type = strtolower(preg_replace('/\(\d+(,\d+)*\)/', '', $val['Type']));
$first = preg_replace('/\s+\w+/', '', $type);
if ($val['Field'] == 'id') continue;
if ($type == 'timestamp') continue;
$_field = [];
$_field['required'] = $this->checkIsRequired($val);
foreach ($this->type as $_key => $value) {
if (!in_array(strtolower($first), $value)) continue;
$comment = '//' . $val['Comment'];
$_field['type'] = $_key;
if ($type == 'date' || $type == 'datetime' || $type == 'time') {
switch ($type) {
case 'date':
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', date(\'Y-m-d\'))';
break;
case 'time':
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', date(\'H:i:s\'))';
break;
default:
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', date(\'Y-m-d H:i:s\'))';
}
$html .= '
\'' . str_pad($val['Field'] . '\'', $length, ' ', STR_PAD_RIGHT) . ' => ' . str_pad($_tps . ',', 60, ' ', STR_PAD_RIGHT) . $comment;
} else {
$tmp = 'null';
if (isset($number[0])) {
if (strpos(',', $number[0])) {
$tmp = '[' . $number[1] . ',' . $number[3] . ']';
$_field['min'] = $number[1];
$_field['max'] = $number[3];
} else {
$tmp = '[0,' . $number[1] . ']';
$_field['min'] = 0;
$_field['max'] = $number[1];
}
}
if ($key == 'string') {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ', ' . $tmp . ')';
} else if ($type == 'int') {
if ($number[0] == 10) {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', time())';
} else {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ')';
}
} else if ($type == 'float') {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ', ' . ($number[3] ?? '2') . ')';
} else if ($key == 'email') {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ')';
} else if ($key == 'timestamp') {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', time())';
} else {
$_tps = 'Input()->' . $_key . '(\'' . $val['Field'] . '\', ' . $_field['required'] . ')';
}
$html .= '
\'' . str_pad($val['Field'] . '\'', $length, ' ', STR_PAD_RIGHT) . ' => ' . str_pad($_tps . ',', 60, ' ', STR_PAD_RIGHT) . $comment;
}
}
$this->rules[$val['Field']] = $_field;
}
return $html;
}
private function getMaxLength($fields)
{
$length = 0;
foreach ($fields as $key => $val) {
if (mb_strlen($val['Field'] . ' >=') > $length) $length = mb_strlen($val['Field'] . ' >=');
}
return $length;
}
private function getWhere($fields)
{
$html = '';
$length = $this->getMaxLength($fields);
foreach ($fields as $key => $val) {
preg_match('/\d+/', $val['Type'], $number);
$type = strtolower(preg_replace('/\(\d+\)/', '', $val['Type']));
$first = preg_replace('/\s+\w+/', '', $type);
if ($type == 'timestamp') continue;
if ($type == 'json') continue;
foreach ($this->type as $_key => $value) {
if (!in_array(strtolower($first), $value)) continue;
$comment = '//' . $val['Comment'];
if ($type == 'date' || $type == 'datetime' || $type == 'time') {
$_tps = 'Input()->get(\'' . $val['Field'] . '\', null)';
$html .= '
$pWhere[\'' . str_pad($val['Field'] . ' <=\']', $length, ' ', STR_PAD_RIGHT) . ' = ' . str_pad($_tps . ';', 60, ' ', STR_PAD_RIGHT) . $comment;
$html .= '
$pWhere[\'' . str_pad($val['Field'] . ' >=\']', $length, ' ', STR_PAD_RIGHT) . ' = ' . str_pad($_tps . ';', 60, ' ', STR_PAD_RIGHT) . $comment;
} else {
$_tps = 'Input()->get(\'' . $val['Field'] . '\', null)';
$html .= '
$pWhere[\'' . str_pad($val['Field'] . '\']', $length, ' ', STR_PAD_RIGHT) . ' = ' . str_pad($_tps . ';', 60, ' ', STR_PAD_RIGHT) . $comment;
}
}
}
return $html;
}
}
+456
View File
@@ -0,0 +1,456 @@
<?php
namespace Snowflake\Gii;
use Database\Db;
use Snowflake\Snowflake;
use Swoole\Coroutine\System;
/**
* Class GiiModel
* @package Snowflake\Gii
*/
class GiiModel extends GiiBase
{
public $classFileName;
public $tableName;
public $visible;
public $res;
public $fields;
/**
* ModelFile constructor.
* @param $classFileName
* @param $tableName
* @param $visible
* @param $res
* @param $fields
*/
public function __construct($classFileName, $tableName, $visible, $res, $fields)
{
$this->classFileName = $classFileName;
$this->tableName = $tableName;
$this->visible = $visible;
$this->res = $res;
$this->fields = $fields;
}
/**
* @throws \ReflectionException
* @throws \Exception
*/
public function generate()
{
$class = '';
$modelPath = $this->getModelPath();
$managerName = $this->classFileName;
$namespace = rtrim($modelPath['namespace'], '\\');
$classFileName = rtrim($modelPath['namespace'], '\\') . '\\' . $managerName;
$prefix = str_replace('_', '', $this->db->tablePrefix);
$managerName = str_replace(ucfirst($prefix), '', $managerName);
if (file_exists($modelPath['path'] . '/' . $managerName . '.php')) {
try {
$class = new \ReflectionClass($modelPath['namespace'] . '\\' . $managerName);
} catch (\Exception $e) {
var_dump($e->getMessage());
}
}
$html = $this->getUseContent($class, $classFileName);
if (empty($html)) {
$html = '<?php
namespace ' . $namespace . ';
use Exception;
use Snowflake\Core\JSON;
use Snowflake\Database\Connection;
use Snowflake\Database\ActiveRecord;';
}
$createSql = $this->setCreateSql($this->tableName);
if (strpos($html, $createSql) === false) {
$html .= '
' . $this->setCreateSql($this->tableName);
}
$html .= '
/**
* Class ' . $managerName . '
* @package Inter\mysql
*' . implode('', $this->visible) . '
* @sql
*/
class ' . $managerName . ' extends ActiveRecord
{';
if (!empty($class)) {
foreach ($class->getConstants() as $key => $val) {
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 ($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->isStatic()) {
$html .= '
' . $debug . ' static $' . $key . ' = ' . $val . ';' . "\n";
} else {
$html .= '
' . $debug . ' $' . $key . ' = ' . $val . ';' . "\n";
}
}
} else {
$primary = $this->createPrimary($this->fields);
if (!empty($primary)) {
$html .= $primary . "\n";
}
}
$html .= $this->createTableName($this->tableName) . "\n";
$html .= $this->createRules($this->fields);
$html .= '
/**
* @return array
*/
public function attributes() : array
{
return [' . implode('', $this->res) . '
];
}' . "\n";
$out = ['rules', 'tableName', 'attributes'];
if (is_object($class)) {
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
$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, $out)) continue;
$over = "
" . $val->getDocComment() . "\n";
$func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
$content[] = $over . $func;
}
if (!empty($content)) {
$html .= implode($content);
}
} else {
$html .= $this->createDatabaseSource();
$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);
}
Snowflake::writeFile($file, $html);
return $managerName . '.php';
}
private function generate_json_function($html, $fields)
{
$strings = [];
foreach ($fields as $field) {
if ($field['Type'] === 'json') {
$function = '
/**
* @param $value
* @return false|string
*/
public function set' . ucfirst($field['Field']) . 'Attribute($value)
{
if ( !is_string($value) ) {
return JSON::encode($value);
}
return $value;
}
';
$get_function = '
/**
* @param $value
* @return mixed
*/
public function get' . ucfirst($field['Field']) . 'Attribute($value)
{
$value = stripcslashes($value)
if ( is_string($value) ) {
return JSON::decode($value, true);
}
return $value;
}
';
if (strpos($html, 'set' . ucfirst($field['Field']) . 'Attribute') === false) {
$strings[] = $function;
}
if (strpos($html, 'get' . ucfirst($field['Field']) . 'Attribute') === false) {
$strings[] = $get_function;
}
}
}
return $strings;
}
/**
* @param $field
* @return string
* 创建表名称
*/
private function createTableName($field)
{
$prefixed = $this->db->tablePrefix;
if (!empty($prefixed)) {
$field = str_replace($prefixed, '', $field);
$field = '{{%' . $field . '}}';
}
return '
/**
* @inheritdoc
*/
public static function tableName(){
return \'' . $field . '\';
}
';
}
/**
* @param $fields
* @return string
* 创建效验规则
*/
private function createRules($fields)
{
$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)
{
$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 (strpos($key, ',') !== false) {
$key = '[' . $key . ']';
}
if (count($_val) == 1) {
[$typeRule, $type, $rule, $field] = current($_val);
$_tmp = '
[\'' . $field . '\', \'' . ($type == 'enum' ? 'enum' : 'maxLength') . '\' => ' . $key . ']';
} else {
$_tmp = '
[[\'' . implode('\', \'', array_column($_val, 3)) . '\'], \'maxLength\' => ' . $key . ']';
}
$string[] = $_tmp;
}
return implode(',', $string);
}
/**
* @param $fields
* @return string
*/
public function getUnique($fields)
{
$data = [];
foreach ($fields as $_key => $_val) {
if ($_val['Extra'] == 'auto_increment') continue;
if (strpos($_val['Type'], 'unique') !== FALSE) {
$data[] = $_val['Field'];
}
}
if (empty($data)) {
return '';
}
return '
[[\'' . implode('\', \'', $data) . '\'], \'unique\'],';
}
/**
* @param $val
* @return string
*/
public function getRequired($val)
{
$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)
{
$field = $this->getPrimaryKey($fields);
if (empty($field)) {
return null;
}
return '
public static $primary = \'' . $field . '\';';
}
/**
* @return string
*/
private function createDatabaseSource()
{
return '
/**
* @return mixed|Connection
* @throws Exception
*/
public static function getDb()
{
return static::setDatabaseConnect(\'' . $this->db->id . '\');
}
';
}
/**
* @param $table
* @return string
* @throws \Exception
*/
private function setCreateSql($table)
{
$text = Db::showCreateSql($table, $this->db)['Create Table'] ?? '';
$_tmp = [];
foreach (explode(PHP_EOL, $text) as $val) {
$_tmp[] = '// ' . $val;
}
return implode(PHP_EOL, $_tmp);
}
}