protected function prepareColumns($modelClass) { $model = new $modelClass(); $validKeys = $model->attributes(); $columns = ModelHelper::normalizeBrackets(ModelHelper::expandBrackets($this->columns ?: ModelHelper::gridColumns($modelClass), $validKeys), array_merge($validKeys, ['action-column'])); foreach ($model->getBehaviors() as $behavior) { if ($behavior instanceof DatetimeBehavior) { foreach ($behavior->attributes as $datetimeAttribute) { if (array_key_exists($datetimeAttribute, $columns) && !array_key_exists('type', $columns[$datetimeAttribute])) { $columns[$datetimeAttribute]['type'] = 'datetime'; } } } elseif ($behavior instanceof SoftDeleteBehavior) { if (array_key_exists($behavior->deletedAttribute, $columns)) { $columns[$behavior->deletedAttribute]['visible'] = false; } } elseif ($behavior instanceof TimeDeleteBehavior) { if (array_key_exists($behavior->deletedAtAttribute, $columns)) { $columns[$behavior->deletedAtAttribute]['visible'] = false; } } } $tableSchema = $modelClass::getTableSchema(); foreach ($tableSchema->foreignKeys as $foreignKey) { if (count($foreignKey) == 2) { $relatedQueryMethod = 'get' . Inflector::classify($foreignKey[0]); if (method_exists($model, $relatedQueryMethod) && is_callable([$model, $relatedQueryMethod])) { $relatedAttribute = array_keys($foreignKey)[1]; $columns[$relatedAttribute]['type'] = 'listItem'; $columns[$relatedAttribute]['items'] = ModelHelper::listItems($model->{$relatedQueryMethod}()); } } } if (!array_key_exists('action-column', $columns)) { $columns['action-column'] = ['type' => 'action']; } foreach ($columns as $attribute => $options) { $options['attribute'] = $attribute; if (!array_key_exists('type', $options)) { $listItemsMethod = Inflector::variablize($attribute) . 'ListItems'; if (method_exists($modelClass, $listItemsMethod) && is_callable([$modelClass, $listItemsMethod])) { $options['type'] = 'listItem'; $options['items'] = $modelClass::$listItemsMethod($model); } } $columnSchema = $tableSchema->getColumn($attribute); if ($columnSchema) { if ($columnSchema->isPrimaryKey) { $options['readOnly'] = true; } if (!array_key_exists('type', $options)) { $options['type'] = $columnSchema->type; if (in_array($columnSchema->type, ['tinyint', 'smallint', 'integer', 'bigint'])) { if ($columnSchema->size == 1 && $columnSchema->unsigned) { $options['type'] = 'boolean'; } else { $options['size'] = $columnSchema->size; $options['unsigned'] = $columnSchema->unsigned; } } elseif (in_array($columnSchema->type, ['decimal', 'numeric', 'money'])) { $options['size'] = $columnSchema->size; $options['scale'] = $columnSchema->scale; $options['unsigned'] = $columnSchema->unsigned; } elseif ($columnSchema->type == 'string') { $options['size'] = $columnSchema->size; } } } if (array_key_exists('type', $options)) { if ($options['type'] && is_string($options['type'])) { if ($options['type'] == 'invisible') { $options['visible'] = false; } elseif (!array_key_exists('class', $options)) { $fieldClass = 'yii\\mozayka\\grid\\' . Inflector::id2camel($options['type']) . 'Column'; if (class_exists($fieldClass)) { $options['class'] = $fieldClass; } } } unset($options['type']); } $columns[$attribute] = $options; } unset($columns['action-column']['attribute']); return array_values(array_filter($columns, function ($options) { return !array_key_exists('visible', $options) || $options['visible']; })); }