Update Relation Form widget to new approach, now supports nested field names

This commit is contained in:
Samuel Georges 2015-03-23 20:02:59 +11:00
parent da95d7dcea
commit 6bb1ee3b9a
1 changed files with 33 additions and 30 deletions

View File

@ -42,16 +42,6 @@ class Relation extends FormWidgetBase
*/
protected $defaultAlias = 'relation';
/**
* @var string Relationship type
*/
public $relationType;
/**
* @var string Relationship name
*/
public $relationName;
/**
* @var FormField Object used for rendering a simple field type
*/
@ -67,16 +57,6 @@ class Relation extends FormWidgetBase
'descriptionFrom',
'emptyOption',
]);
$this->relationName = $this->valueFrom;
$this->relationType = $this->model->getRelationType($this->relationName);
if (!$this->model->hasRelation($this->relationName)) {
throw new SystemException(Lang::get(
'backend::lang.model.missing_relation',
['class'=>get_class($this->model), 'relation'=>$this->relationName]
));
}
}
/**
@ -104,15 +84,17 @@ class Relation extends FormWidgetBase
return $this->renderFormField = RelationBase::noConstraints(function () {
$field = clone $this->formField;
$relationObject = $this->getRelationObject();
$query = $relationObject->newQuery();
list($model, $attribute) = $this->resolveModelAttribute($this->relationName);
$relatedObj = $model->makeRelation($attribute);
$query = $model->{$attribute}()->newQuery();
list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
$relationType = $model->getRelationType($attribute);
$relationModel = $model->makeRelation($attribute);
if (in_array($this->relationType, ['belongsToMany', 'morphToMany', 'morphedByMany', 'hasMany'])) {
if (in_array($relationType, ['belongsToMany', 'morphToMany', 'morphedByMany', 'hasMany'])) {
$field->type = 'checkboxlist';
}
elseif (in_array($this->relationType, ['belongsTo', 'hasOne'])) {
elseif (in_array($relationType, ['belongsTo', 'hasOne'])) {
$field->type = 'dropdown';
}
@ -120,8 +102,8 @@ class Relation extends FormWidgetBase
// It is safe to assume that if the model and related model are of
// the exact same class, then it cannot be related to itself
if ($model->exists && (get_class($model) == get_class($relatedObj))) {
$query->where($relatedObj->getKeyName(), '<>', $model->getKey());
if ($model->exists && (get_class($model) == get_class($relationModel))) {
$query->where($relationModel->getKeyName(), '<>', $model->getKey());
}
// Even though "no constraints" is applied, belongsToMany constrains the query
@ -129,11 +111,11 @@ class Relation extends FormWidgetBase
$query->getQuery()->getQuery()->joins = [];
$treeTraits = ['October\Rain\Database\Traits\NestedTree', 'October\Rain\Database\Traits\SimpleTree'];
if (count(array_intersect($treeTraits, class_uses($relatedObj))) > 0) {
$field->options = $query->listsNested($this->nameFrom, $relatedObj->getKeyName());
if (count(array_intersect($treeTraits, class_uses($relationModel))) > 0) {
$field->options = $query->listsNested($this->nameFrom, $relationModel->getKeyName());
}
else {
$field->options = $query->lists($this->nameFrom, $relatedObj->getKeyName());
$field->options = $query->lists($this->nameFrom, $relationModel->getKeyName());
}
return $field;
@ -155,4 +137,25 @@ class Relation extends FormWidgetBase
return $value;
}
/**
* Returns the value as a relation object from the model,
* supports nesting via HTML array.
* @return Relation
*/
protected function getRelationObject()
{
list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
if (!$model->hasRelation($attribute)) {
throw new ApplicationException(Lang::get('backend::lang.model.missing_relation', [
'class' => get_class($model),
'relation' => $attribute
]));
}
return $model->{$attribute}();
}
}