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:
$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
// 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 = $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;
}