/** * Retrieves form fields configuration. Fields can be config arrays, ActiveField objects or closures. * * @param \yii\base\Model|\netis\crud\db\ActiveRecord $model * @param array $fields * @param bool $multiple true for multiple values inputs, usually used for search forms * @param array $hiddenAttributes list of attribute names to render as hidden fields * * @return array form fields * @throws InvalidConfigException */ public static function getFormFields($model, $fields, $multiple = false, $hiddenAttributes = []) { if (!$model instanceof \yii\db\ActiveRecord) { return $model->safeAttributes(); } $keys = Action::getModelKeys($model); $hiddenAttributes = array_flip($hiddenAttributes); list($behaviorAttributes, $blameableAttributes) = Action::getModelBehaviorAttributes($model); $attributes = $model->safeAttributes(); $relations = $model->relations(); if (($versionAttribute = $model->optimisticLock()) !== null) { $hiddenAttributes[$versionAttribute] = true; } $formFields = []; foreach ($fields as $key => $field) { if ($field instanceof ActiveField) { $formFields[$key] = $field; continue; } elseif (!is_string($field) && is_callable($field)) { $formFields[$key] = call_user_func($field, $model); if (!is_string($formFields[$key])) { throw new InvalidConfigException('Field definition must be either an ActiveField or a callable.'); } continue; } elseif (!is_string($field)) { throw new InvalidConfigException('Field definition must be either an ActiveField or a callable.'); } $attributeName = Html::getAttributeName($field); if (in_array($attributeName, $relations)) { $formFields = static::addRelationField($formFields, $model, $field, $hiddenAttributes, $attributes, $multiple); } elseif (in_array($attributeName, $attributes)) { if (in_array($attributeName, $keys) || in_array($attributeName, $behaviorAttributes)) { continue; } $formFields = static::addFormField($formFields, $model, $field, $hiddenAttributes, $multiple); } } return $formFields; }