Generator.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. namespace gii\generators\model;
  3. use ReflectionClass;
  4. use yii\base\NotSupportedException;
  5. use yii\db\Schema;
  6. class Generator extends \yii\gii\generators\model\Generator
  7. {
  8. public $skipRuleColumns = ['created_at', 'updated_at'];
  9. /**
  10. * Generates validation rules for the specified table.
  11. * @param \yii\db\TableSchema $table the table schema
  12. * @return array the generated validation rules
  13. */
  14. public function generateRules($table)
  15. {
  16. $types = [];
  17. $lengths = [];
  18. foreach ($table->columns as $column) {
  19. if ($column->autoIncrement || in_array($column->name, $this->skipRuleColumns)) {
  20. continue;
  21. }
  22. if (!$column->allowNull && $column->defaultValue === null) {
  23. $types['required'][] = $column->name;
  24. }
  25. switch ($column->type) {
  26. case Schema::TYPE_SMALLINT:
  27. case Schema::TYPE_INTEGER:
  28. case Schema::TYPE_BIGINT:
  29. $types['integer'][] = $column->name;
  30. break;
  31. case Schema::TYPE_BOOLEAN:
  32. $types['boolean'][] = $column->name;
  33. break;
  34. case Schema::TYPE_FLOAT:
  35. case 'double': // Schema::TYPE_DOUBLE, which is available since Yii 2.0.3
  36. case Schema::TYPE_DECIMAL:
  37. case Schema::TYPE_MONEY:
  38. $types['number'][] = $column->name;
  39. break;
  40. case Schema::TYPE_DATE:
  41. case Schema::TYPE_TIME:
  42. case Schema::TYPE_DATETIME:
  43. case Schema::TYPE_TIMESTAMP:
  44. $types['safe'][] = $column->name;
  45. break;
  46. default: // strings
  47. if ($column->size > 0) {
  48. $lengths[$column->size][] = $column->name;
  49. } else {
  50. $types['string'][] = $column->name;
  51. }
  52. }
  53. }
  54. $rules = [];
  55. foreach ($types as $type => $columns) {
  56. $rules[] = "[['" . implode("', '", $columns) . "'], '$type']";
  57. }
  58. foreach ($lengths as $length => $columns) {
  59. $rules[] = "[['" . implode("', '", $columns) . "'], 'string', 'max' => $length]";
  60. }
  61. $db = $this->getDbConnection();
  62. // Unique indexes rules
  63. try {
  64. $uniqueIndexes = $db->getSchema()->findUniqueIndexes($table);
  65. foreach ($uniqueIndexes as $uniqueColumns) {
  66. // Avoid validating auto incremental columns
  67. if (!$this->isColumnAutoIncremental($table, $uniqueColumns)) {
  68. $attributesCount = count($uniqueColumns);
  69. if ($attributesCount === 1) {
  70. $rules[] = "[['" . $uniqueColumns[0] . "'], 'unique']";
  71. } elseif ($attributesCount > 1) {
  72. $labels = array_intersect_key($this->generateLabels($table), array_flip($uniqueColumns));
  73. $lastLabel = array_pop($labels);
  74. $columnsList = implode("', '", $uniqueColumns);
  75. $rules[] = "[['$columnsList'], 'unique', 'targetAttribute' => ['$columnsList'], 'message' => 'The combination of " . implode(', ', $labels) . " and $lastLabel has already been taken.']";
  76. }
  77. }
  78. }
  79. } catch (NotSupportedException $e) {
  80. // doesn't support unique indexes information...do nothing
  81. }
  82. // Exist rules for foreign keys
  83. foreach ($table->foreignKeys as $refs) {
  84. $refTable = $refs[0];
  85. $refTableSchema = $db->getTableSchema($refTable);
  86. if ($refTableSchema === null) {
  87. // Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
  88. continue;
  89. }
  90. $refClassName = $this->generateClassName($refTable);
  91. unset($refs[0]);
  92. $attributes = implode("', '", array_keys($refs));
  93. $targetAttributes = [];
  94. foreach ($refs as $key => $value) {
  95. $targetAttributes[] = "'$key' => '$value'";
  96. }
  97. $targetAttributes = implode(', ', $targetAttributes);
  98. $rules[] = "[['$attributes'], 'exist', 'skipOnError' => true, 'targetClass' => $refClassName::className(), 'targetAttribute' => [$targetAttributes]]";
  99. }
  100. return $rules;
  101. }
  102. public function formView()
  103. {
  104. $class = new ReflectionClass(get_parent_class());
  105. return dirname($class->getFileName()) . '/form.php';
  106. }
  107. }