Browse Source
新建linyao文件夹;开发gii的生成model的模板linyaomodel;修改environments/skeleton/kcadmin/config/main-local.php文件,自动生成linyaomodel模板所需的相应配置;
wechat_public_accounts
新建linyao文件夹;开发gii的生成model的模板linyaomodel;修改environments/skeleton/kcadmin/config/main-local.php文件,自动生成linyaomodel模板所需的相应配置;
wechat_public_accounts
linyao
5 years ago
6 changed files with 1203 additions and 1 deletions
-
3common/config/main.php
-
6environments/skeleton/kcadmin/config/main-local.php
-
992vendor/linyao/generators/model/Generator.php
-
117vendor/linyao/generators/model/default/model.php
-
56vendor/linyao/generators/model/default/query.php
-
30vendor/linyao/generators/model/form.php
@ -0,0 +1,992 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @link http://www.yiiframework.com/ |
||||
|
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
|
* @license http://www.yiiframework.com/license/ |
||||
|
*/ |
||||
|
|
||||
|
namespace linyao\generators\model; |
||||
|
|
||||
|
use Yii; |
||||
|
use yii\base\NotSupportedException; |
||||
|
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; |
||||
|
|
||||
|
/** |
||||
|
* This generator will generate one or multiple ActiveRecord classes for the specified database table. |
||||
|
* |
||||
|
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
|
* @since 2.0 |
||||
|
*/ |
||||
|
class Generator extends \yii\gii\Generator |
||||
|
{ |
||||
|
const RELATIONS_NONE = 'none'; |
||||
|
const RELATIONS_ALL = 'all'; |
||||
|
const RELATIONS_ALL_INVERSE = 'all-inverse'; |
||||
|
|
||||
|
public $db = 'db'; |
||||
|
public $ns = 'app\models'; |
||||
|
public $tableName; |
||||
|
public $modelClass; |
||||
|
public $baseClass = 'yii\db\ActiveRecord'; |
||||
|
public $generateRelations = self::RELATIONS_ALL; |
||||
|
public $generateRelationsFromCurrentSchema = true; |
||||
|
public $generateLabelsFromComments = false; |
||||
|
public $useTablePrefix = false; |
||||
|
public $standardizeCapitals = false; |
||||
|
public $singularize = false; |
||||
|
public $useSchemaName = true; |
||||
|
public $generateQuery = false; |
||||
|
public $queryNs = 'app\models'; |
||||
|
public $queryClass; |
||||
|
public $queryBaseClass = 'yii\db\ActiveQuery'; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function getName() |
||||
|
{ |
||||
|
return 'Model Generator'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function getDescription() |
||||
|
{ |
||||
|
return 'This generator generates an ActiveRecord class for the specified database table.'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function rules() |
||||
|
{ |
||||
|
return array_merge(parent::rules(), [ |
||||
|
[['db', 'ns', 'tableName', 'modelClass', 'baseClass', 'queryNs', 'queryClass', 'queryBaseClass'], 'filter', 'filter' => 'trim'], |
||||
|
[['ns', 'queryNs'], 'filter', 'filter' => function ($value) { return trim($value, '\\'); }], |
||||
|
|
||||
|
[['db', 'ns', 'tableName', 'baseClass', 'queryNs', 'queryBaseClass'], 'required'], |
||||
|
[['db', 'modelClass', 'queryClass'], 'match', 'pattern' => '/^\w+$/', 'message' => 'Only word characters are allowed.'], |
||||
|
[['ns', 'baseClass', 'queryNs', 'queryBaseClass'], 'match', 'pattern' => '/^[\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'], |
||||
|
[['tableName'], 'match', 'pattern' => '/^([\w ]+\.)?([\w\* ]+)$/', 'message' => 'Only word characters, and optionally spaces, an asterisk and/or a dot are allowed.'], |
||||
|
[['db'], 'validateDb'], |
||||
|
[['ns', 'queryNs'], 'validateNamespace'], |
||||
|
[['tableName'], 'validateTableName'], |
||||
|
[['modelClass'], 'validateModelClass', 'skipOnEmpty' => false], |
||||
|
[['baseClass'], 'validateClass', 'params' => ['extends' => ActiveRecord::className()]], |
||||
|
[['queryBaseClass'], 'validateClass', 'params' => ['extends' => ActiveQuery::className()]], |
||||
|
[['generateRelations'], 'in', 'range' => [self::RELATIONS_NONE, self::RELATIONS_ALL, self::RELATIONS_ALL_INVERSE]], |
||||
|
[['generateLabelsFromComments', 'useTablePrefix', 'useSchemaName', 'generateQuery', 'generateRelationsFromCurrentSchema'], 'boolean'], |
||||
|
[['enableI18N', 'standardizeCapitals', 'singularize'], 'boolean'], |
||||
|
[['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false], |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function attributeLabels() |
||||
|
{ |
||||
|
return array_merge(parent::attributeLabels(), [ |
||||
|
'ns' => 'Namespace', |
||||
|
'db' => 'Database Connection ID', |
||||
|
'tableName' => 'Table Name', |
||||
|
'standardizeCapitals' => 'Standardize Capitals', |
||||
|
'singularize' => 'Singularize', |
||||
|
'modelClass' => 'Model Class Name', |
||||
|
'baseClass' => 'Base Class', |
||||
|
'generateRelations' => 'Generate Relations', |
||||
|
'generateRelationsFromCurrentSchema' => 'Generate Relations from Current Schema', |
||||
|
'generateLabelsFromComments' => 'Generate Labels from DB Comments', |
||||
|
'generateQuery' => 'Generate ActiveQuery', |
||||
|
'queryNs' => 'ActiveQuery Namespace', |
||||
|
'queryClass' => 'ActiveQuery Class', |
||||
|
'queryBaseClass' => 'ActiveQuery Base Class', |
||||
|
'useSchemaName' => 'Use Schema Name', |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function hints() |
||||
|
{ |
||||
|
return array_merge(parent::hints(), [ |
||||
|
'ns' => 'This is the namespace of the ActiveRecord class to be generated, e.g., <code>app\models</code>', |
||||
|
'db' => 'This is the ID of the DB application component.', |
||||
|
'tableName' => 'This is the name of the DB table that the new ActiveRecord class is associated with, e.g. <code>post</code>. |
||||
|
The table name may consist of the DB schema part if needed, e.g. <code>public.post</code>. |
||||
|
The table name may end with asterisk to match multiple table names, e.g. <code>tbl_*</code> |
||||
|
will match tables who name starts with <code>tbl_</code>. In this case, multiple ActiveRecord classes |
||||
|
will be generated, one for each matching table name; and the class names will be generated from |
||||
|
the matching characters. For example, table <code>tbl_post</code> will generate <code>Post</code> |
||||
|
class.', |
||||
|
'modelClass' => 'This is the name of the ActiveRecord class to be generated. The class name should not contain |
||||
|
the namespace part as it is specified in "Namespace". You do not need to specify the class name |
||||
|
if "Table Name" ends with asterisk, in which case multiple ActiveRecord classes will be generated.', |
||||
|
'standardizeCapitals' => 'This indicates whether the generated class names should have standardized capitals. For example, |
||||
|
table names like <code>SOME_TABLE</code> or <code>Other_Table</code> will have class names <code>SomeTable</code> |
||||
|
and <code>OtherTable</code>, respectively. If not checked, the same tables will have class names <code>SOMETABLE</code> |
||||
|
and <code>OtherTable</code> instead.', |
||||
|
'singularize' => 'This indicates whether the generated class names should be singularized. For example, |
||||
|
table names like <code>some_tables</code> will have class names <code>SomeTable</code>.', |
||||
|
'baseClass' => 'This is the base class of the new ActiveRecord class. It should be a fully qualified namespaced class name.', |
||||
|
'generateRelations' => 'This indicates whether the generator should generate relations based on |
||||
|
foreign key constraints it detects in the database. Note that if your database contains too many tables, |
||||
|
you may want to uncheck this option to accelerate the code generation process.', |
||||
|
'generateRelationsFromCurrentSchema' => 'This indicates whether the generator should generate relations from current schema or from all available schemas.', |
||||
|
'generateLabelsFromComments' => 'This indicates whether the generator should generate attribute labels |
||||
|
by using the comments of the corresponding DB columns.', |
||||
|
'useTablePrefix' => 'This indicates whether the table name returned by the generated ActiveRecord class |
||||
|
should consider the <code>tablePrefix</code> setting of the DB connection. For example, if the |
||||
|
table name is <code>tbl_post</code> and <code>tablePrefix=tbl_</code>, the ActiveRecord class |
||||
|
will return the table name as <code>{{%post}}</code>.', |
||||
|
'useSchemaName' => 'This indicates whether to include the schema name in the ActiveRecord class |
||||
|
when it\'s auto generated. Only non default schema would be used.', |
||||
|
'generateQuery' => 'This indicates whether to generate ActiveQuery for the ActiveRecord class.', |
||||
|
'queryNs' => 'This is the namespace of the ActiveQuery class to be generated, e.g., <code>app\models</code>', |
||||
|
'queryClass' => 'This is the name of the ActiveQuery class to be generated. The class name should not contain |
||||
|
the namespace part as it is specified in "ActiveQuery Namespace". You do not need to specify the class name |
||||
|
if "Table Name" ends with asterisk, in which case multiple ActiveQuery classes will be generated.', |
||||
|
'queryBaseClass' => 'This is the base class of the new ActiveQuery class. It should be a fully qualified namespaced class name.', |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function autoCompleteData() |
||||
|
{ |
||||
|
$db = $this->getDbConnection(); |
||||
|
if ($db !== null) { |
||||
|
return [ |
||||
|
'tableName' => function () use ($db) { |
||||
|
return $db->getSchema()->getTableNames(); |
||||
|
}, |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
return []; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function requiredTemplates() |
||||
|
{ |
||||
|
// @todo make 'query.php' to be required before 2.1 release
|
||||
|
return ['model.php'/*, 'query.php'*/]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function stickyAttributes() |
||||
|
{ |
||||
|
return array_merge(parent::stickyAttributes(), ['ns', 'db', 'baseClass', 'generateRelations', 'generateLabelsFromComments', 'queryNs', 'queryBaseClass', 'useTablePrefix', 'generateQuery']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the `tablePrefix` property of the DB connection as specified |
||||
|
* |
||||
|
* @return string |
||||
|
* @since 2.0.5 |
||||
|
* @see getDbConnection |
||||
|
*/ |
||||
|
public function getTablePrefix() |
||||
|
{ |
||||
|
$db = $this->getDbConnection(); |
||||
|
if ($db !== null) { |
||||
|
return $db->tablePrefix; |
||||
|
} |
||||
|
|
||||
|
return ''; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function generate() |
||||
|
{ |
||||
|
$files = []; |
||||
|
$relations = $this->generateRelations(); |
||||
|
$db = $this->getDbConnection(); |
||||
|
foreach ($this->getTableNames() as $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), |
||||
|
'rules' => $this->generateRules($tableSchema), |
||||
|
'relations' => isset($relations[$tableName]) ? $relations[$tableName] : [], |
||||
|
]; |
||||
|
$files[] = new CodeFile( |
||||
|
Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/' . $modelClassName . '.php', |
||||
|
$this->render('model.php', $params) |
||||
|
); |
||||
|
|
||||
|
// query :
|
||||
|
if ($queryClassName) { |
||||
|
$params['className'] = $queryClassName; |
||||
|
$params['modelClassName'] = $modelClassName; |
||||
|
$files[] = new CodeFile( |
||||
|
Yii::getAlias('@' . str_replace('\\', '/', $this->queryNs)) . '/' . $queryClassName . '.php', |
||||
|
$this->render('query.php', $params) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $files; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates the properties for the specified table. |
||||
|
* @param \yii\db\TableSchema $table the table schema |
||||
|
* @return array the generated properties (property => type) |
||||
|
* @since 2.0.6 |
||||
|
*/ |
||||
|
protected function generateProperties($table) |
||||
|
{ |
||||
|
$properties = []; |
||||
|
foreach ($table->columns as $column) { |
||||
|
$columnPhpType = $column->phpType; |
||||
|
if ($columnPhpType === 'integer') { |
||||
|
$type = 'int'; |
||||
|
} elseif ($columnPhpType === 'boolean') { |
||||
|
$type = 'bool'; |
||||
|
} else { |
||||
|
$type = $columnPhpType; |
||||
|
} |
||||
|
$properties[$column->name] = [ |
||||
|
'type' => $type, |
||||
|
'name' => $column->name, |
||||
|
'comment' => $column->comment, |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
return $properties; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates the attribute labels for the specified table. |
||||
|
* @param \yii\db\TableSchema $table the table schema |
||||
|
* @return array the generated attribute labels (name => label) |
||||
|
*/ |
||||
|
public function generateLabels($table) |
||||
|
{ |
||||
|
// $labels = [];
|
||||
|
// foreach ($table->columns as $column) {
|
||||
|
// if ($this->generateLabelsFromComments && !empty($column->comment)) {
|
||||
|
// $labels[$column->name] = $column->comment;
|
||||
|
// } elseif (!strcasecmp($column->name, 'id')) {
|
||||
|
// $labels[$column->name] = 'ID';
|
||||
|
// } else {
|
||||
|
// $label = Inflector::camel2words($column->name);
|
||||
|
// if (!empty($label) && substr_compare($label, ' id', -3, 3, true) === 0) {
|
||||
|
// $label = substr($label, 0, -3) . ' ID';
|
||||
|
// }
|
||||
|
// $labels[$column->name] = $label;
|
||||
|
// }
|
||||
|
// }
|
||||
|
//
|
||||
|
// return $labels;
|
||||
|
|
||||
|
$labels=array(); |
||||
|
|
||||
|
$sql ="SELECT COLUMN_NAME, COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$table->name'"; |
||||
|
|
||||
|
$res = Yii::$app->getDb()->createCommand($sql)->query(); |
||||
|
|
||||
|
foreach ($res as $column){ |
||||
|
|
||||
|
if (!empty($column['COLUMN_COMMENT'])) |
||||
|
|
||||
|
$labels[$column['COLUMN_NAME']]= $column['COLUMN_COMMENT']; |
||||
|
|
||||
|
else |
||||
|
|
||||
|
$labels[$column['COLUMN_NAME']]= $column['COLUMN_NAME']; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return $labels; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates validation rules for the specified table. |
||||
|
* @param \yii\db\TableSchema $table the table schema |
||||
|
* @return array the generated validation rules |
||||
|
*/ |
||||
|
public function generateRules($table) |
||||
|
{ |
||||
|
$types = []; |
||||
|
$lengths = []; |
||||
|
foreach ($table->columns as $column) { |
||||
|
if ($column->autoIncrement) { |
||||
|
continue; |
||||
|
} |
||||
|
if (!$column->allowNull && $column->defaultValue === null) { |
||||
|
$types['required'][] = $column->name; |
||||
|
} |
||||
|
switch ($column->type) { |
||||
|
case Schema::TYPE_SMALLINT: |
||||
|
case Schema::TYPE_INTEGER: |
||||
|
case Schema::TYPE_BIGINT: |
||||
|
case Schema::TYPE_TINYINT: |
||||
|
$types['integer'][] = $column->name; |
||||
|
break; |
||||
|
case Schema::TYPE_BOOLEAN: |
||||
|
$types['boolean'][] = $column->name; |
||||
|
break; |
||||
|
case Schema::TYPE_FLOAT: |
||||
|
case Schema::TYPE_DOUBLE: |
||||
|
case Schema::TYPE_DECIMAL: |
||||
|
case Schema::TYPE_MONEY: |
||||
|
$types['number'][] = $column->name; |
||||
|
break; |
||||
|
case Schema::TYPE_DATE: |
||||
|
case Schema::TYPE_TIME: |
||||
|
case Schema::TYPE_DATETIME: |
||||
|
case Schema::TYPE_TIMESTAMP: |
||||
|
case Schema::TYPE_JSON: |
||||
|
$types['safe'][] = $column->name; |
||||
|
break; |
||||
|
default: // strings
|
||||
|
if ($column->size > 0) { |
||||
|
$lengths[$column->size][] = $column->name; |
||||
|
} else { |
||||
|
$types['string'][] = $column->name; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$rules = []; |
||||
|
$driverName = $this->getDbDriverName(); |
||||
|
foreach ($types as $type => $columns) { |
||||
|
if ($driverName === 'pgsql' && $type === 'integer') { |
||||
|
$rules[] = "[['" . implode("', '", $columns) . "'], 'default', 'value' => null]"; |
||||
|
} |
||||
|
$rules[] = "[['" . implode("', '", $columns) . "'], '$type']"; |
||||
|
} |
||||
|
foreach ($lengths as $length => $columns) { |
||||
|
$rules[] = "[['" . implode("', '", $columns) . "'], 'string', 'max' => $length]"; |
||||
|
} |
||||
|
|
||||
|
$db = $this->getDbConnection(); |
||||
|
|
||||
|
// Unique indexes rules
|
||||
|
try { |
||||
|
$uniqueIndexes = array_merge($db->getSchema()->findUniqueIndexes($table), [$table->primaryKey]); |
||||
|
$uniqueIndexes = array_unique($uniqueIndexes, SORT_REGULAR); |
||||
|
foreach ($uniqueIndexes as $uniqueColumns) { |
||||
|
// Avoid validating auto incremental columns
|
||||
|
if (!$this->isColumnAutoIncremental($table, $uniqueColumns)) { |
||||
|
$attributesCount = count($uniqueColumns); |
||||
|
|
||||
|
if ($attributesCount === 1) { |
||||
|
$rules[] = "[['" . $uniqueColumns[0] . "'], 'unique']"; |
||||
|
} elseif ($attributesCount > 1) { |
||||
|
$columnsList = implode("', '", $uniqueColumns); |
||||
|
$rules[] = "[['$columnsList'], 'unique', 'targetAttribute' => ['$columnsList']]"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} catch (NotSupportedException $e) { |
||||
|
// doesn't support unique indexes information...do nothing
|
||||
|
} |
||||
|
|
||||
|
// Exist rules for foreign keys
|
||||
|
foreach ($table->foreignKeys as $refs) { |
||||
|
$refTable = $refs[0]; |
||||
|
$refTableSchema = $db->getTableSchema($refTable); |
||||
|
if ($refTableSchema === null) { |
||||
|
// Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
|
||||
|
continue; |
||||
|
} |
||||
|
$refClassName = $this->generateClassName($refTable); |
||||
|
unset($refs[0]); |
||||
|
$attributes = implode("', '", array_keys($refs)); |
||||
|
$targetAttributes = []; |
||||
|
foreach ($refs as $key => $value) { |
||||
|
$targetAttributes[] = "'$key' => '$value'"; |
||||
|
} |
||||
|
$targetAttributes = implode(', ', $targetAttributes); |
||||
|
$rules[] = "[['$attributes'], 'exist', 'skipOnError' => true, 'targetClass' => $refClassName::className(), 'targetAttribute' => [$targetAttributes]]"; |
||||
|
} |
||||
|
|
||||
|
return $rules; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates relations using a junction table by adding an extra viaTable(). |
||||
|
* @param \yii\db\TableSchema the table being checked |
||||
|
* @param array $fks obtained from the checkJunctionTable() method |
||||
|
* @param array $relations |
||||
|
* @return array modified $relations |
||||
|
*/ |
||||
|
private function generateManyManyRelations($table, $fks, $relations) |
||||
|
{ |
||||
|
$db = $this->getDbConnection(); |
||||
|
|
||||
|
foreach ($fks as $pair) { |
||||
|
list($firstKey, $secondKey) = $pair; |
||||
|
$table0 = $firstKey[0]; |
||||
|
$table1 = $secondKey[0]; |
||||
|
unset($firstKey[0], $secondKey[0]); |
||||
|
$className0 = $this->generateClassName($table0); |
||||
|
$className1 = $this->generateClassName($table1); |
||||
|
$table0Schema = $db->getTableSchema($table0); |
||||
|
$table1Schema = $db->getTableSchema($table1); |
||||
|
|
||||
|
// @see https://github.com/yiisoft/yii2-gii/issues/166
|
||||
|
if ($table0Schema === null || $table1Schema === null) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
$link = $this->generateRelationLink(array_flip($secondKey)); |
||||
|
$viaLink = $this->generateRelationLink($firstKey); |
||||
|
$relationName = $this->generateRelationName($relations, $table0Schema, key($secondKey), true); |
||||
|
$relations[$table0Schema->fullName][$relationName] = [ |
||||
|
"return \$this->hasMany($className1::className(), $link)->viaTable('" |
||||
|
. $this->generateTableName($table->name) . "', $viaLink);", |
||||
|
$className1, |
||||
|
true, |
||||
|
]; |
||||
|
|
||||
|
$link = $this->generateRelationLink(array_flip($firstKey)); |
||||
|
$viaLink = $this->generateRelationLink($secondKey); |
||||
|
$relationName = $this->generateRelationName($relations, $table1Schema, key($firstKey), true); |
||||
|
$relations[$table1Schema->fullName][$relationName] = [ |
||||
|
"return \$this->hasMany($className0::className(), $link)->viaTable('" |
||||
|
. $this->generateTableName($table->name) . "', $viaLink);", |
||||
|
$className0, |
||||
|
true, |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
return $relations; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return string[] all db schema names or an array with a single empty string |
||||
|
* @throws NotSupportedException |
||||
|
* @since 2.0.5 |
||||
|
*/ |
||||
|
protected function getSchemaNames() |
||||
|
{ |
||||
|
$db = $this->getDbConnection(); |
||||
|
|
||||
|
if ($this->generateRelationsFromCurrentSchema) { |
||||
|
if ($db->schema->defaultSchema !== null) { |
||||
|
return [$db->schema->defaultSchema]; |
||||
|
} |
||||
|
return ['']; |
||||
|
} |
||||
|
|
||||
|
$schema = $db->getSchema(); |
||||
|
if ($schema->hasMethod('getSchemaNames')) { // keep BC to Yii versions < 2.0.4
|
||||
|
try { |
||||
|
$schemaNames = $schema->getSchemaNames(); |
||||
|
} catch (NotSupportedException $e) { |
||||
|
// schema names are not supported by schema
|
||||
|
} |
||||
|
} |
||||
|
if (!isset($schemaNames)) { |
||||
|
if (($pos = strpos($this->tableName, '.')) !== false) { |
||||
|
$schemaNames = [substr($this->tableName, 0, $pos)]; |
||||
|
} else { |
||||
|
$schemaNames = ['']; |
||||
|
} |
||||
|
} |
||||
|
return $schemaNames; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array the generated relation declarations |
||||
|
*/ |
||||
|
protected function generateRelations() |
||||
|
{ |
||||
|
if ($this->generateRelations === self::RELATIONS_NONE) { |
||||
|
return []; |
||||
|
} |
||||
|
|
||||
|
$db = $this->getDbConnection(); |
||||
|
$relations = []; |
||||
|
$schemaNames = $this->getSchemaNames(); |
||||
|
foreach ($schemaNames as $schemaName) { |
||||
|
foreach ($db->getSchema()->getTableSchemas($schemaName) as $table) { |
||||
|
$className = $this->generateClassName($table->fullName); |
||||
|
foreach ($table->foreignKeys as $refs) { |
||||
|
$refTable = $refs[0]; |
||||
|
$refTableSchema = $db->getTableSchema($refTable); |
||||
|
if ($refTableSchema === null) { |
||||
|
// Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
|
||||
|
continue; |
||||
|
} |
||||
|
unset($refs[0]); |
||||
|
$fks = array_keys($refs); |
||||
|
$refClassName = $this->generateClassName($refTable); |
||||
|
|
||||
|
// Add relation for this table
|
||||
|
$link = $this->generateRelationLink(array_flip($refs)); |
||||
|
$relationName = $this->generateRelationName($relations, $table, $fks[0], false); |
||||
|
$relations[$table->fullName][$relationName] = [ |
||||
|
"return \$this->hasOne($refClassName::className(), $link);", |
||||
|
$refClassName, |
||||
|
false, |
||||
|
]; |
||||
|
|
||||
|
// Add relation for the referenced table
|
||||
|
$hasMany = $this->isHasManyRelation($table, $fks); |
||||
|
$link = $this->generateRelationLink($refs); |
||||
|
$relationName = $this->generateRelationName($relations, $refTableSchema, $className, $hasMany); |
||||
|
$relations[$refTableSchema->fullName][$relationName] = [ |
||||
|
"return \$this->" . ($hasMany ? 'hasMany' : 'hasOne') . "($className::className(), $link);", |
||||
|
$className, |
||||
|
$hasMany, |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
if (($junctionFks = $this->checkJunctionTable($table)) === false) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
$relations = $this->generateManyManyRelations($table, $junctionFks, $relations); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($this->generateRelations === self::RELATIONS_ALL_INVERSE) { |
||||
|
return $this->addInverseRelations($relations); |
||||
|
} |
||||
|
|
||||
|
return $relations; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Adds inverse relations |
||||
|
* |
||||
|
* @param array $relations relation declarations |
||||
|
* @return array relation declarations extended with inverse relation names |
||||
|
* @since 2.0.5 |
||||
|
*/ |
||||
|
protected function addInverseRelations($relations) |
||||
|
{ |
||||
|
$db = $this->getDbConnection(); |
||||
|
$relationNames = []; |
||||
|
|
||||
|
$schemaNames = $this->getSchemaNames(); |
||||
|
foreach ($schemaNames as $schemaName) { |
||||
|
foreach ($db->schema->getTableSchemas($schemaName) as $table) { |
||||
|
$className = $this->generateClassName($table->fullName); |
||||
|
foreach ($table->foreignKeys as $refs) { |
||||
|
$refTable = $refs[0]; |
||||
|
$refTableSchema = $db->getTableSchema($refTable); |
||||
|
if ($refTableSchema === null) { |
||||
|
// Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
|
||||
|
continue; |
||||
|
} |
||||
|
unset($refs[0]); |
||||
|
$fks = array_keys($refs); |
||||
|
|
||||
|
$leftRelationName = $this->generateRelationName($relationNames, $table, $fks[0], false); |
||||
|
$relationNames[$table->fullName][$leftRelationName] = true; |
||||
|
$hasMany = $this->isHasManyRelation($table, $fks); |
||||
|
$rightRelationName = $this->generateRelationName( |
||||
|
$relationNames, |
||||
|
$refTableSchema, |
||||
|
$className, |
||||
|
$hasMany |
||||
|
); |
||||
|
$relationNames[$refTableSchema->fullName][$rightRelationName] = true; |
||||
|
|
||||
|
$relations[$table->fullName][$leftRelationName][0] = |
||||
|
rtrim($relations[$table->fullName][$leftRelationName][0], ';') |
||||
|
. "->inverseOf('".lcfirst($rightRelationName)."');"; |
||||
|
$relations[$refTableSchema->fullName][$rightRelationName][0] = |
||||
|
rtrim($relations[$refTableSchema->fullName][$rightRelationName][0], ';') |
||||
|
. "->inverseOf('".lcfirst($leftRelationName)."');"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return $relations; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determines if relation is of has many type |
||||
|
* |
||||
|
* @param TableSchema $table |
||||
|
* @param array $fks |
||||
|
* @return bool |
||||
|
* @since 2.0.5 |
||||
|
*/ |
||||
|
protected function isHasManyRelation($table, $fks) |
||||
|
{ |
||||
|
$uniqueKeys = [$table->primaryKey]; |
||||
|
try { |
||||
|
$uniqueKeys = array_merge($uniqueKeys, $this->getDbConnection()->getSchema()->findUniqueIndexes($table)); |
||||
|
} catch (NotSupportedException $e) { |
||||
|
// ignore
|
||||
|
} |
||||
|
foreach ($uniqueKeys as $uniqueKey) { |
||||
|
if (count(array_diff(array_merge($uniqueKey, $fks), array_intersect($uniqueKey, $fks))) === 0) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates the link parameter to be used in generating the relation declaration. |
||||
|
* @param array $refs reference constraint |
||||
|
* @return string the generated link parameter. |
||||
|
*/ |
||||
|
protected function generateRelationLink($refs) |
||||
|
{ |
||||
|
$pairs = []; |
||||
|
foreach ($refs as $a => $b) { |
||||
|
$pairs[] = "'$a' => '$b'"; |
||||
|
} |
||||
|
|
||||
|
return '[' . implode(', ', $pairs) . ']'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks if the given table is a junction table, that is it has at least one pair of unique foreign keys. |
||||
|
* @param \yii\db\TableSchema the table being checked |
||||
|
* @return array|bool all unique foreign key pairs if the table is a junction table, |
||||
|
* or false if the table is not a junction table. |
||||
|
*/ |
||||
|
protected function checkJunctionTable($table) |
||||
|
{ |
||||
|
if (count($table->foreignKeys) < 2) { |
||||
|
return false; |
||||
|
} |
||||
|
$uniqueKeys = [$table->primaryKey]; |
||||
|
try { |
||||
|
$uniqueKeys = array_merge($uniqueKeys, $this->getDbConnection()->getSchema()->findUniqueIndexes($table)); |
||||
|
} catch (NotSupportedException $e) { |
||||
|
// ignore
|
||||
|
} |
||||
|
$result = []; |
||||
|
// find all foreign key pairs that have all columns in an unique constraint
|
||||
|
$foreignKeys = array_values($table->foreignKeys); |
||||
|
$foreignKeysCount = count($foreignKeys); |
||||
|
|
||||
|
for ($i = 0; $i < $foreignKeysCount; $i++) { |
||||
|
$firstColumns = $foreignKeys[$i]; |
||||
|
unset($firstColumns[0]); |
||||
|
|
||||
|
for ($j = $i + 1; $j < $foreignKeysCount; $j++) { |
||||
|
$secondColumns = $foreignKeys[$j]; |
||||
|
unset($secondColumns[0]); |
||||
|
|
||||
|
$fks = array_merge(array_keys($firstColumns), array_keys($secondColumns)); |
||||
|
foreach ($uniqueKeys as $uniqueKey) { |
||||
|
if (count(array_diff(array_merge($uniqueKey, $fks), array_intersect($uniqueKey, $fks))) === 0) { |
||||
|
// save the foreign key pair
|
||||
|
$result[] = [$foreignKeys[$i], $foreignKeys[$j]]; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return empty($result) ? false : $result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generate a relation name for the specified table and a base name. |
||||
|
* @param array $relations the relations being generated currently. |
||||
|
* @param \yii\db\TableSchema $table the table schema |
||||
|
* @param string $key a base name that the relation name may be generated from |
||||
|
* @param bool $multiple whether this is a has-many relation |
||||
|
* @return string the relation name |
||||
|
*/ |
||||
|
protected function generateRelationName($relations, $table, $key, $multiple) |
||||
|
{ |
||||
|
static $baseModel; |
||||
|
/* @var $baseModel \yii\db\ActiveRecord */ |
||||
|
if ($baseModel === null) { |
||||
|
$baseClass = $this->baseClass; |
||||
|
$baseClassReflector = new \ReflectionClass($baseClass); |
||||
|
if ($baseClassReflector->isAbstract()) { |
||||
|
$baseClassWrapper = |
||||
|
'namespace ' . __NAMESPACE__ . ';'. |
||||
|
'class GiiBaseClassWrapper extends \\' . $baseClass . ' {' . |
||||
|
'public static function tableName(){' . |
||||
|
'return "' . addslashes($table->fullName) . '";' . |
||||
|
'}' . |
||||
|
'};' . |
||||
|
'return new GiiBaseClassWrapper();'; |
||||
|
$baseModel = eval($baseClassWrapper); |
||||
|
} else { |
||||
|
$baseModel = new $baseClass(); |
||||
|
} |
||||
|
$baseModel->setAttributes([]); |
||||
|
} |
||||
|
|
||||
|
if (!empty($key) && strcasecmp($key, 'id')) { |
||||
|
if (substr_compare($key, 'id', -2, 2, true) === 0) { |
||||
|
$key = rtrim(substr($key, 0, -2), '_'); |
||||
|
} elseif (substr_compare($key, 'id', 0, 2, true) === 0) { |
||||
|
$key = ltrim(substr($key, 2, strlen($key)), '_'); |
||||
|
} |
||||
|
} |
||||
|
if ($multiple) { |
||||
|
$key = Inflector::pluralize($key); |
||||
|
} |
||||
|
$name = $rawName = Inflector::id2camel($key, '_'); |
||||
|
$i = 0; |
||||
|
while ($baseModel->hasProperty(lcfirst($name))) { |
||||
|
$name = $rawName . ($i++); |
||||
|
} |
||||
|
while (isset($table->columns[lcfirst($name)])) { |
||||
|
$name = $rawName . ($i++); |
||||
|
} |
||||
|
while (isset($relations[$table->fullName][$name])) { |
||||
|
$name = $rawName . ($i++); |
||||
|
} |
||||
|
|
||||
|
return $name; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Validates the [[db]] attribute. |
||||
|
*/ |
||||
|
public function validateDb() |
||||
|
{ |
||||
|
if (!Yii::$app->has($this->db)) { |
||||
|
$this->addError('db', 'There is no application component named "db".'); |
||||
|
} elseif (!Yii::$app->get($this->db) instanceof Connection) { |
||||
|
$this->addError('db', 'The "db" application component must be a DB connection instance.'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Validates the namespace. |
||||
|
* |
||||
|
* @param string $attribute Namespace variable. |
||||
|
*/ |
||||
|
public function validateNamespace($attribute) |
||||
|
{ |
||||
|
$value = $this->$attribute; |
||||
|
$value = ltrim($value, '\\'); |
||||
|
$path = Yii::getAlias('@' . str_replace('\\', '/', $value), false); |
||||
|
if ($path === false) { |
||||
|
$this->addError($attribute, 'Namespace must be associated with an existing directory.'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Validates the [[modelClass]] attribute. |
||||
|
*/ |
||||
|
public function validateModelClass() |
||||
|
{ |
||||
|
if ($this->isReservedKeyword($this->modelClass)) { |
||||
|
$this->addError('modelClass', 'Class name cannot be a reserved PHP keyword.'); |
||||
|
} |
||||
|
if ((empty($this->tableName) || substr_compare($this->tableName, '*', -1, 1)) && $this->modelClass == '') { |
||||
|
$this->addError('modelClass', 'Model Class cannot be blank if table name does not end with asterisk.'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Validates the [[tableName]] attribute. |
||||
|
*/ |
||||
|
public function validateTableName() |
||||
|
{ |
||||
|
if (strpos($this->tableName, '*') !== false && substr_compare($this->tableName, '*', -1, 1)) { |
||||
|
$this->addError('tableName', 'Asterisk is only allowed as the last character.'); |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
$tables = $this->getTableNames(); |
||||
|
if (empty($tables)) { |
||||
|
$this->addError('tableName', "Table '{$this->tableName}' does not exist."); |
||||
|
} else { |
||||
|
foreach ($tables as $table) { |
||||
|
$class = $this->generateClassName($table); |
||||
|
if ($this->isReservedKeyword($class)) { |
||||
|
$this->addError('tableName', "Table '$table' will generate a class which is a reserved PHP keyword."); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected $tableNames; |
||||
|
protected $classNames; |
||||
|
|
||||
|
/** |
||||
|
* @return array the table names that match the pattern specified by [[tableName]]. |
||||
|
*/ |
||||
|
protected function getTableNames() |
||||
|
{ |
||||
|
if ($this->tableNames !== null) { |
||||
|
return $this->tableNames; |
||||
|
} |
||||
|
$db = $this->getDbConnection(); |
||||
|
if ($db === null) { |
||||
|
return []; |
||||
|
} |
||||
|
$tableNames = []; |
||||
|
if (strpos($this->tableName, '*') !== false) { |
||||
|
if (($pos = strrpos($this->tableName, '.')) !== false) { |
||||
|
$schema = substr($this->tableName, 0, $pos); |
||||
|
$pattern = '/^' . str_replace('*', '\w+', substr($this->tableName, $pos + 1)) . '$/'; |
||||
|
} else { |
||||
|
$schema = ''; |
||||
|
$pattern = '/^' . str_replace('*', '\w+', $this->tableName) . '$/'; |
||||
|
} |
||||
|
|
||||
|
foreach ($db->schema->getTableNames($schema) as $table) { |
||||
|
if (preg_match($pattern, $table)) { |
||||
|
$tableNames[] = $schema === '' ? $table : ($schema . '.' . $table); |
||||
|
} |
||||
|
} |
||||
|
} elseif (($table = $db->getTableSchema($this->tableName, true)) !== null) { |
||||
|
$tableNames[] = $this->tableName; |
||||
|
$this->classNames[$this->tableName] = $this->modelClass; |
||||
|
} |
||||
|
|
||||
|
return $this->tableNames = $tableNames; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates the table name by considering table prefix. |
||||
|
* If [[useTablePrefix]] is false, the table name will be returned without change. |
||||
|
* @param string $tableName the table name (which may contain schema prefix) |
||||
|
* @return string the generated table name |
||||
|
*/ |
||||
|
public function generateTableName($tableName) |
||||
|
{ |
||||
|
if (!$this->useTablePrefix) { |
||||
|
return $tableName; |
||||
|
} |
||||
|
|
||||
|
$db = $this->getDbConnection(); |
||||
|
if (preg_match("/^{$db->tablePrefix}(.*?)$/", $tableName, $matches)) { |
||||
|
$tableName = '{{%' . $matches[1] . '}}'; |
||||
|
} elseif (preg_match("/^(.*?){$db->tablePrefix}$/", $tableName, $matches)) { |
||||
|
$tableName = '{{' . $matches[1] . '%}}'; |
||||
|
} |
||||
|
return $tableName; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates a class name from the specified table name. |
||||
|
* @param string $tableName the table name (which may contain schema prefix) |
||||
|
* @param bool $useSchemaName should schema name be included in the class name, if present |
||||
|
* @return string the generated class name |
||||
|
*/ |
||||
|
protected function generateClassName($tableName, $useSchemaName = null) |
||||
|
{ |
||||
|
if (isset($this->classNames[$tableName])) { |
||||
|
return $this->classNames[$tableName]; |
||||
|
} |
||||
|
|
||||
|
$schemaName = ''; |
||||
|
$fullTableName = $tableName; |
||||
|
if (($pos = strrpos($tableName, '.')) !== false) { |
||||
|
if (($useSchemaName === null && $this->useSchemaName) || $useSchemaName) { |
||||
|
$schemaName = substr($tableName, 0, $pos) . '_'; |
||||
|
} |
||||
|
$tableName = substr($tableName, $pos + 1); |
||||
|
} |
||||
|
|
||||
|
$db = $this->getDbConnection(); |
||||
|
$patterns = []; |
||||
|
$patterns[] = "/^{$db->tablePrefix}(.*?)$/"; |
||||
|
$patterns[] = "/^(.*?){$db->tablePrefix}$/"; |
||||
|
if (strpos($this->tableName, '*') !== false) { |
||||
|
$pattern = $this->tableName; |
||||
|
if (($pos = strrpos($pattern, '.')) !== false) { |
||||
|
$pattern = substr($pattern, $pos + 1); |
||||
|
} |
||||
|
$patterns[] = '/^' . str_replace('*', '(\w+)', $pattern) . '$/'; |
||||
|
} |
||||
|
$className = $tableName; |
||||
|
foreach ($patterns as $pattern) { |
||||
|
if (preg_match($pattern, $tableName, $matches)) { |
||||
|
$className = $matches[1]; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($this->standardizeCapitals) { |
||||
|
$schemaName = ctype_upper(preg_replace('/[_-]/', '', $schemaName)) ? strtolower($schemaName) : $schemaName; |
||||
|
$className = ctype_upper(preg_replace('/[_-]/', '', $className)) ? strtolower($className) : $className; |
||||
|
$this->classNames[$fullTableName] = Inflector::camelize(Inflector::camel2words($schemaName.$className)); |
||||
|
} else { |
||||
|
$this->classNames[$fullTableName] = Inflector::id2camel($schemaName.$className, '_'); |
||||
|
} |
||||
|
|
||||
|
if ($this->singularize) { |
||||
|
$this->classNames[$fullTableName] = Inflector::singularize($this->classNames[$fullTableName]); |
||||
|
} |
||||
|
|
||||
|
return $this->classNames[$fullTableName]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generates a query class name from the specified model class name. |
||||
|
* @param string $modelClassName model class name |
||||
|
* @return string generated class name |
||||
|
*/ |
||||
|
protected function generateQueryClassName($modelClassName) |
||||
|
{ |
||||
|
$queryClassName = $this->queryClass; |
||||
|
if (empty($queryClassName) || strpos($this->tableName, '*') !== false) { |
||||
|
$queryClassName = $modelClassName . 'Query'; |
||||
|
} |
||||
|
return $queryClassName; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Connection the DB connection as specified by [[db]]. |
||||
|
*/ |
||||
|
protected function getDbConnection() |
||||
|
{ |
||||
|
return Yii::$app->get($this->db, false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return string|null driver name of db connection. |
||||
|
* In case db is not instance of \yii\db\Connection null will be returned. |
||||
|
* @since 2.0.6 |
||||
|
*/ |
||||
|
protected function getDbDriverName() |
||||
|
{ |
||||
|
/** @var Connection $db */ |
||||
|
$db = $this->getDbConnection(); |
||||
|
return $db instanceof \yii\db\Connection ? $db->driverName : null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks if any of the specified columns is auto incremental. |
||||
|
* @param \yii\db\TableSchema $table the table schema |
||||
|
* @param array $columns columns to check for autoIncrement property |
||||
|
* @return bool whether any of the specified columns is auto incremental. |
||||
|
*/ |
||||
|
protected function isColumnAutoIncremental($table, $columns) |
||||
|
{ |
||||
|
foreach ($columns as $column) { |
||||
|
if (isset($table->columns[$column]) && $table->columns[$column]->autoIncrement) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
<?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) */ |
||||
|
|
||||
|
echo "<?php\n"; |
||||
|
?>
|
||||
|
|
||||
|
namespace <?= $generator->ns ?>;
|
||||
|
|
||||
|
use Yii; |
||||
|
use yii\behaviors\TimestampBehavior; |
||||
|
|
||||
|
/** |
||||
|
* This is the model class for table "<?= $generator->generateTableName($tableName) ?>". |
||||
|
* |
||||
|
<?php foreach ($properties as $property => $data): ?>
|
||||
|
* @property <?= "{$data['type']} \${$property}" . ($data['comment'] ? ' ' . strtr($data['comment'], ["\n" => ' ']) : '') . "\n" ?>
|
||||
|
<?php endforeach; ?>
|
||||
|
<?php if (!empty($relations)): ?>
|
||||
|
* |
||||
|
<?php foreach ($relations as $name => $relation): ?>
|
||||
|
* @property <?= $relation[1] . ($relation[2] ? '[]' : '') . ' $' . lcfirst($name) . "\n" ?>
|
||||
|
<?php endforeach; ?>
|
||||
|
<?php endif; ?>
|
||||
|
*/ |
||||
|
class <?= $className ?> extends <?= '\\' . ltrim($generator->baseClass, '\\') . "\n" ?>
|
||||
|
{ |
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public static function tableName() |
||||
|
{ |
||||
|
return '<?= $generator->generateTableName($tableName) ?>'; |
||||
|
} |
||||
|
<?php if ($generator->db !== 'db'): ?>
|
||||
|
|
||||
|
/** |
||||
|
* @return \yii\db\Connection the database connection used by this AR class. |
||||
|
*/ |
||||
|
public static function getDb() |
||||
|
{ |
||||
|
return Yii::$app->get('<?= $generator->db ?>'); |
||||
|
} |
||||
|
<?php endif; ?>
|
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function rules() |
||||
|
{ |
||||
|
return [<?= empty($rules) ? '' : ("\n " . implode(",\n ", $rules) . ",\n ") ?>];
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
*/ |
||||
|
public function attributeLabels() |
||||
|
{ |
||||
|
return [ |
||||
|
<?php foreach ($labels as $name => $label): ?>
|
||||
|
<?= "'$name' => " . $generator->generateString($label) . ",\n" ?>
|
||||
|
<?php endforeach; ?>
|
||||
|
]; |
||||
|
} |
||||
|
<?php foreach ($relations as $name => $relation): ?>
|
||||
|
|
||||
|
/** |
||||
|
* @return \yii\db\ActiveQuery |
||||
|
*/ |
||||
|
public function get<?= $name ?>()
|
||||
|
{ |
||||
|
<?= $relation[0] . "\n" ?>
|
||||
|
} |
||||
|
<?php endforeach; ?>
|
||||
|
<?php if ($queryClassName): ?>
|
||||
|
<?php |
||||
|
$queryClassFullName = ($generator->ns === $generator->queryNs) ? $queryClassName : '\\' . $generator->queryNs . '\\' . $queryClassName; |
||||
|
echo "\n"; |
||||
|
?>
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
* @return <?= $queryClassFullName ?> the active query used by this AR class.
|
||||
|
*/ |
||||
|
public static function find() |
||||
|
{ |
||||
|
return new <?= $queryClassFullName ?>(get_called_class());
|
||||
|
} |
||||
|
<?php endif; ?>
|
||||
|
|
||||
|
<?php if (array_key_exists('created_at', $labels) && array_key_exists('updated_at', $labels)): ?>
|
||||
|
public function behaviors() |
||||
|
{ |
||||
|
return [ |
||||
|
[ |
||||
|
'class' => TimestampBehavior::className(), |
||||
|
'createdAtAttribute' => 'created_at', |
||||
|
'updatedAtAttribute' => 'updated_at', |
||||
|
'value' => function() { |
||||
|
return time(); |
||||
|
}, |
||||
|
], |
||||
|
]; |
||||
|
} |
||||
|
<?php endif; ?>
|
||||
|
} |
@ -0,0 +1,56 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* This is the template for generating the ActiveQuery class. |
||||
|
*/ |
||||
|
|
||||
|
/* @var $this yii\web\View */ |
||||
|
/* @var $generator yii\gii\generators\model\Generator */ |
||||
|
/* @var $tableName string full table name */ |
||||
|
/* @var $className string class name */ |
||||
|
/* @var $tableSchema yii\db\TableSchema */ |
||||
|
/* @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 $className string class name */ |
||||
|
/* @var $modelClassName string related model class name */ |
||||
|
|
||||
|
$modelFullClassName = $modelClassName; |
||||
|
if ($generator->ns !== $generator->queryNs) { |
||||
|
$modelFullClassName = '\\' . $generator->ns . '\\' . $modelFullClassName; |
||||
|
} |
||||
|
|
||||
|
echo "<?php\n"; |
||||
|
?>
|
||||
|
|
||||
|
namespace <?= $generator->queryNs ?>;
|
||||
|
|
||||
|
/** |
||||
|
* This is the ActiveQuery class for [[<?= $modelFullClassName ?>]].
|
||||
|
* |
||||
|
* @see <?= $modelFullClassName . "\n" ?>
|
||||
|
*/ |
||||
|
class <?= $className ?> extends <?= '\\' . ltrim($generator->queryBaseClass, '\\') . "\n" ?>
|
||||
|
{ |
||||
|
/*public function active() |
||||
|
{ |
||||
|
return $this->andWhere('[[status]]=1'); |
||||
|
}*/ |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
* @return <?= $modelFullClassName ?>[]|array
|
||||
|
*/ |
||||
|
public function all($db = null) |
||||
|
{ |
||||
|
return parent::all($db); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* {@inheritdoc} |
||||
|
* @return <?= $modelFullClassName ?>|array|null
|
||||
|
*/ |
||||
|
public function one($db = null) |
||||
|
{ |
||||
|
return parent::one($db); |
||||
|
} |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use yii\gii\generators\model\Generator; |
||||
|
|
||||
|
/* @var $this yii\web\View */ |
||||
|
/* @var $form yii\widgets\ActiveForm */ |
||||
|
/* @var $generator yii\gii\generators\model\Generator */ |
||||
|
|
||||
|
echo $form->field($generator, 'tableName')->textInput(['table_prefix' => $generator->getTablePrefix()]); |
||||
|
echo $form->field($generator, 'modelClass'); |
||||
|
echo $form->field($generator, 'standardizeCapitals')->checkbox(); |
||||
|
echo $form->field($generator, 'singularize')->checkbox(); |
||||
|
echo $form->field($generator, 'ns'); |
||||
|
echo $form->field($generator, 'baseClass'); |
||||
|
echo $form->field($generator, 'db'); |
||||
|
echo $form->field($generator, 'useTablePrefix')->checkbox(); |
||||
|
echo $form->field($generator, 'generateRelations')->dropDownList([ |
||||
|
Generator::RELATIONS_NONE => 'No relations', |
||||
|
Generator::RELATIONS_ALL => 'All relations', |
||||
|
Generator::RELATIONS_ALL_INVERSE => 'All relations with inverse', |
||||
|
]); |
||||
|
echo $form->field($generator, 'generateRelationsFromCurrentSchema')->checkbox(); |
||||
|
echo $form->field($generator, 'generateLabelsFromComments')->checkbox(); |
||||
|
echo $form->field($generator, 'generateQuery')->checkbox(); |
||||
|
echo $form->field($generator, 'queryNs'); |
||||
|
echo $form->field($generator, 'queryClass'); |
||||
|
echo $form->field($generator, 'queryBaseClass'); |
||||
|
echo $form->field($generator, 'enableI18N')->checkbox(); |
||||
|
echo $form->field($generator, 'messageCategory'); |
||||
|
echo $form->field($generator, 'useSchemaName')->checkbox(); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue