【注意】最后更新于 December 10, 2019,文中内容可能已过时,请谨慎使用。
开发是需要用到 gii,但是 gii 并不是完全符合自己的开发需求,所以需要对他做一点改造
这里先拿 basic
版举例, advance
版同理
1.修改配置文件 web.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// file path: @app/config/web.php
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// 这里把原来的 model generator 给覆盖成自己的
'generators' => [
'model' => [
// 自定义的模板生成器
'class' => 'app\common\gii\model\Generator',
//设置我们自己的模板
'templates' => [
//模板名 => 模板路径
'default' => '@app/common/gii/model/default',
'original' => '@app/common/gii/model/original_tpl',
]
]
],
];
}
|
现在在配置中指定了两种model 生成模板了
2.设置自定义的 Geneartor 和 template
现在进@app/vendor/yiisoft/yii2-gii/src/generators/model
把这个目录拷贝到 @app/common/gii/
这里,位置随意, 只要保证 config 中能找到这个路径就行,现在我们就在 @app/common/gii/model
这里操作
因为 Generator 继承的 \yii\gii\Generator, 需要实现两个方法, 一个是 getName() 另一个是 generate(), 我们主要修改的就是 generate(),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
// file path: @app/common/gii/model/Generator
namespace app\common\gii\model;
use Yii;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
use yii\db\Connection;
use yii\db\Schema;
use yii\db\TableSchema;
use yii\gii\CodeFile;
use yii\helpers\Inflector;
use yii\base\NotSupportedException;
class Generator extends \yii\gii\Generator{
/**
some code .....
*/
/**
* {@inheritdoc}
*/
public function generate()
{
$files = [];
$relations = $this->generateRelations();
$db = $this->getDbConnection();
foreach ($this->getTableNames() as $index => $tableName) {
// model :
$modelClassName = $this->generateClassName($tableName);
$queryClassName = ($this->generateQuery) ? $this->generateQueryClassName($modelClassName) : false;
$tableSchema = $db->getTableSchema($tableName);
$params = [
'tableName' => $tableName,
'className' => $modelClassName,
'queryClassName' => $queryClassName,
'tableSchema' => $tableSchema,
'properties' => $this->generateProperties($tableSchema),
'labels' => $this->generateLabels($tableSchema),
// 这是新增的
'constMap' => $this->generateConstMap($tableSchema),
'rules' => $this->generateRules($tableSchema),
'relations' => isset($relations[$tableName]) ? $relations[$tableName] : [],
];
// 同一个库中只生成一个 Model.php 之后的 model 都要继承这个 model
if ($index == 0) {
$files[] = new CodeFile(
Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/Model.php',
$this->render('cModel.php', $params)
);
}
$files[] = new CodeFile(
Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/' . $modelClassName . '.php',
$this->render('model.php', $params)
);
}
return $files;
}
protected function generateConstMap($table){
// some code
}
/**
some code .....
*/
}
|
在generate()
这个方法里的 $params
这里就是给模板准备参数, new CodeFile
这里就是生成指定的模板
现在我们在模板中搞一下
3.设置 model 模板
在@app/common/gii/model
目录下有一个default
目录,就是默认的 template,咱们在config.php
中设置了
1
2
3
4
5
|
'templates' => [
//模板名 => 模板路径
'default' => '@app/common/gii/model/default',
'original' => '@app/common/gii/model/original_tpl',
]
|
这两个, 把 default/
复制一份叫 original_tpl/
这在 gii 页面端选模板的时候能看到这写别名,如果是console
模式的话只能使用default
模板了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// path: @app/common/gii/default/model.php
<?php
/**
* This is the template for generating the model class of a specified table.
*/
/* @var $this yii\web\View */
/* @var $generator yii\gii\generators\model\Generator */
/* @var $tableName string full table name */
/* @var $className string class name */
/* @var $queryClassName string query class name */
/* @var $tableSchema yii\db\TableSchema */
/* @var $properties array list of properties (property => [type, name. comment]) */
/* @var $labels string[] list of attribute labels (name => label) */
/* @var $rules string[] list of validation rules */
/* @var $relations array list of relations (name => relation declaration) */
/* @var $constMap string[] list of attribute labels (name => label) */
echo "<?php\n";
?>
namespace <?= $generator->ns ?>;
use Yii;
/**
* This is the model class for table "<?= $generator->generateTableName($tableName) ?>".
*
<?php foreach ($properties as $property => $data): ?>
...底下一些乱七八糟的代码....
|
这里就看着办吧,就是正常的渲染模板
因为在generate()
中还设置了一个
1
2
3
4
5
6
7
|
// 同一个库中只生成一个 Model.php 之后的 model 都要继承这个 model
if ($index == 0) {
$files[] = new CodeFile(
Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/Model.php',
$this->render('cModel.php', $params)
);
}
|
新增了一个cModel.php
,这个是我自己的业务需求, 同库的 model 全部继承这个 model, 这里只是设置了一下getDb()
方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
<?php
/**
* This is the template for generating the model class of a specified table.
*/
/* @var $this yii\web\View */
/* @var $generator yii\gii\generators\model\Generator */
/* @var $tableName string full table name */
/* @var $className string class name */
/* @var $queryClassName string query class name */
/* @var $tableSchema yii\db\TableSchema */
/* @var $properties array list of properties (property => [type, name. comment]) */
/* @var $labels string[] list of attribute labels (name => label) */
/* @var $rules string[] list of validation rules */
/* @var $relations array list of relations (name => relation declaration) */
/* @var $constMap string[] list of attribute labels (name => label) */
$date = date('Y/m/d H:i');
$date = explode(' ', $date);
$model = <<<str
<?php
/**
* Created by Gii.
* TemplatePath: @app\common\gii\model\default\cModel.php
* Date: {$date[0]}
* Time: {$date[1]}
*/
namespace {$generator->ns};
use yii\db\ActiveRecord;
use Yii;
/**
* 同文件夹下都要继承一下这个 model,目前是用来改库的链接地址
* Class Model
* @package app\modules\v1\models\passport
*/
class Model extends ActiveRecord
{
/**
* 重写表所对应的数据库链接信息 (如果函数不存在则默认为 db 的配置)
* @return \yii\db\Connection
*/
public static function getDb()
{
return Yii::\$app->get('{$generator->db}');
}
}
str;
echo $model;
?>
|
这样依赖 gii 的模板自定义就算是完事了
4. console 模式下的 gii
照例首先需要设置console.php
的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//path @app/console.php
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'app\common\gii\Module',
'generators' => [
'model' => [
// 自定义的模板生成器
'class' => 'app\common\gii\model\Generator',
//设置我们自己的模板 console 默认就是 default 模板
'templates' => []
]
],
];
}
|
generators
和 之前的配置一样,区别就是 module 下的 class 设置成自己的 Module
这里把@app/vendor/yiisoft/yii2-gii/src/Module.php
复制一份到@app/common/gii/Module.php
改一下命名空间并且继承\yii\gii\Module
毕竟咱们是定制的, 这个代码不能在 vendor 中改,不然以后你再装新的 composer 包的时候会非常麻烦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// path: @app/common/gii/Module.php
/**
代码块
*/
public function bootstrap($app)
{
if ($app instanceof \yii\web\Application) {
$app->getUrlManager()->addRules([
['class' => 'yii\web\UrlRule', 'pattern' => $this->id, 'route' => $this->id . '/default/index'],
['class' => 'yii\web\UrlRule', 'pattern' => $this->id . '/<id:\w+>', 'route' => $this->id . '/default/view'],
['class' => 'yii\web\UrlRule', 'pattern' => $this->id . '/<controller:[\w\-]+>/<action:[\w\-]+>', 'route' => $this->id . '/<controller>/<action>'],
], false);
} elseif ($app instanceof \yii\console\Application) {
$app->controllerMap[$this->id] = [
// 这里改成自己定制的 consoleController
'class' => 'app\common\gii\console\GenerateController',
'generators' => array_merge($this->coreGenerators(), $this->generators),
'module' => $this,
];
}
}
/**
代码块
*/
|
只用把 console 的 GenerateController 指向咱们自定义的控制器, 复制目录@app/vendor/yiisoft/yii2-gii/src/console/
到 @app/common/gii/console/
, 这时我们就能对 gii console 模式下的代码进行调整了
可能在@app/common/gii/console/GenerateController.php
中的代码让你摸不到头脑, 这里是在 actions()
来着注册 router, 具体的 action 实现则是在 class 中指定了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// path: @app/common/gii/console/GenerateController.php
public function actions()
{
$actions = [];
foreach ($this->generators as $name => $generator) {
$actions[$name] = [
'class' => 'yii\gii\console\GenerateAction',
'generator' => $generator,
];
// 依赖model generator 重新定义一个 gii 命令
if($name == 'model') {
$actions['all'] = [
'class' => 'app\common\gii\console\GenerateAllAction',
'generator' => $generator,
];
}
}
return $actions;
}
|
因为所有的 Generator 都实现了 getName()
和 generate()
这两个方法,action 也是只使用了这两个方法,可以自己翻下代码,这里就不详细讲了
文章作者
GPF
上次更新
2019-12-10
(77997d9)