/var/www/vhosts/nabawater/common/modules/gii/model
Edit: /var/www/vhosts/nabawater/common/modules/gii/model/Generator.php (10521B)
* @since 2.0
*
* @modified A Vijay
*/
use common\components\CModel;
use Yii;
use yii\base\NotSupportedException;
use yii\db\Exception;
use yii\db\Schema;
use yii\gii\CodeFile;
use yii\helpers\ArrayHelper;
class Generator extends \yii\gii\generators\model\Generator
{
/**
* @var array
*/
private $defaultApps = ['backend', 'frontend'];
/**
* @var array
*/
public $apps = [];
/**
* @var string
*/
public $ns = 'common\models';
/**
* @var string
*/
public $baseClass = CModel::class;
/**
* @return array
* @throws \yii\base\InvalidParamException
*/
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,
'labels' => $this->generateLabels($tableSchema),
'rules' => $this->generateRules($tableSchema),
'relations' => isset($relations[$tableName]) ? $relations[$tableName] : [],
];
$apps = ArrayHelper::merge(['base', 'common'], $this->defaultApps, $this->apps);
foreach ($apps as $app) {
$app = str_ireplace(DIRECTORY_SEPARATOR, '\\', $app);
$params['ns'] = sprintf('%s\models%s', $app === 'base' ? 'common' : $app,
$app === 'base' ? "\\$app" : '');
$fileName = $modelClassName;
switch ($app) {
case 'base':
$template = 'baseModel';
$fileName = "Base$modelClassName";
break;
case 'common':
$template = 'commonModel';
break;
default:
$template = 'model';
break;
}
try {
$files[] = new CodeFile(
Yii::getAlias('@' . str_replace('\\', '/', $params['ns'])) . '/' . $fileName . '.php',
$this->render(sprintf('%s.php', $template), $params)
);
} catch (Exception $e) {
}
}
// 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 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 'double': // Schema::TYPE_DOUBLE, which is available since Yii 2.0.3
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:
$types['safe'][] = $column->name;
break;
default: // strings
if ($column->size > 0) {
$lengths[$column->size][] = $column->name;
} else {
$types['string'][] = $column->name;
}
}
}
$rules = [];
foreach ($types as $type => $columns) {
$rules[] = "[['" . implode("', '", $columns) . "'], '$type']";
}
foreach ($lengths as $length => $columns) {
$rules[] = "[['" . implode("', '", $columns) . "'], 'string', 'max' => $length]";
}
$db = $this->getDbConnection();
// Unique indexes rules
try {
$uniqueIndexes = $db->getSchema()->findUniqueIndexes($table);
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) {
$labels = array_intersect_key($this->generateLabels($table), array_flip($uniqueColumns));
$lastLabel = array_pop($labels);
$columnsList = implode("', '", $uniqueColumns);
$rules[] = "[['$columnsList'], 'unique', 'targetAttribute' => ['$columnsList'], 'message' => 'The combination of " . implode(', ',
$labels) . " and $lastLabel has already been taken.']";
}
}
}
} 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 = 'Base' . $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;
}
/**
* @return array the generated relation declarations
*/
protected function generateRelations()
{
if ($this->generateRelations === self::RELATIONS_NONE) {
return [];
}
$db = $this->getDbConnection();
$relations = [];
foreach ($this->getSchemaNames() 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(Base$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') . "(Base$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;
}
}