ORIENT/modules/backend/formwidgets/Relation.php

162 lines
4.3 KiB
PHP
Raw Normal View History

2014-05-14 13:24:20 +00:00
<?php namespace Backend\FormWidgets;
use Lang;
use Backend\Classes\FormWidgetBase;
2015-01-28 07:03:35 +00:00
use SystemException;
use Illuminate\Database\Eloquent\Relations\Relation as RelationBase;
2014-05-14 13:24:20 +00:00
/**
* Form Relationship
* Renders a field prepopulated with a belongsTo and belongsToHasMany relation.
*
* @package october\backend
* @author Alexey Bobkov, Samuel Georges
*/
class Relation extends FormWidgetBase
{
//
// Configurable properties
//
2014-05-14 13:24:20 +00:00
/**
* @var string Model column to use for the name reference
2014-05-14 13:24:20 +00:00
*/
public $nameFrom = 'name';
2014-05-14 13:24:20 +00:00
/**
* @var string Model column to use for the description reference
2014-05-14 13:24:20 +00:00
*/
public $descriptionFrom = 'description';
2014-05-14 13:24:20 +00:00
/**
* @var string Empty value to use if the relation is singluar (belongsTo)
2014-05-14 13:24:20 +00:00
*/
public $emptyOption;
//
// Object properties
//
2014-05-14 13:24:20 +00:00
/**
* {@inheritDoc}
2014-05-14 13:24:20 +00:00
*/
protected $defaultAlias = 'relation';
2014-05-14 13:24:20 +00:00
/**
* @var FormField Object used for rendering a simple field type
*/
public $renderFormField;
2014-05-14 13:24:20 +00:00
/**
* {@inheritDoc}
*/
public function init()
{
$this->fillFromConfig([
'nameFrom',
'descriptionFrom',
'emptyOption',
]);
2014-05-14 13:24:20 +00:00
}
/**
* {@inheritDoc}
*/
public function render()
{
$this->prepareVars();
return $this->makePartial('relation');
}
/**
* Prepares the view data
*/
public function prepareVars()
{
$this->vars['field'] = $this->makeRenderFormField();
}
/**
* Makes the form object used for rendering a simple field type
*/
protected function makeRenderFormField()
{
2014-10-10 21:50:05 +00:00
return $this->renderFormField = RelationBase::noConstraints(function () {
$field = clone $this->formField;
$relationObject = $this->getRelationObject();
$query = $relationObject->newQuery();
list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
$relationType = $model->getRelationType($attribute);
$relationModel = $model->makeRelation($attribute);
if (in_array($relationType, ['belongsToMany', 'morphToMany', 'morphedByMany', 'hasMany'])) {
$field->type = 'checkboxlist';
}
elseif (in_array($relationType, ['belongsTo', 'hasOne'])) {
$field->type = 'dropdown';
}
2015-01-21 06:01:07 +00:00
$field->placeholder = $this->emptyOption;
2014-10-10 21:50:05 +00:00
// 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($relationModel))) {
$query->where($relationModel->getKeyName(), '<>', $model->getKey());
}
// Even though "no constraints" is applied, belongsToMany constrains the query
// by joining its pivot table. Remove all joins from the query.
$query->getQuery()->getQuery()->joins = [];
$treeTraits = ['October\Rain\Database\Traits\NestedTree', 'October\Rain\Database\Traits\SimpleTree'];
if (count(array_intersect($treeTraits, class_uses($relationModel))) > 0) {
$field->options = $query->listsNested($this->nameFrom, $relationModel->getKeyName());
2014-11-04 06:41:48 +00:00
}
else {
$field->options = $query->lists($this->nameFrom, $relationModel->getKeyName());
2014-10-10 21:50:05 +00:00
}
return $field;
});
2014-05-14 13:24:20 +00:00
}
/**
* {@inheritDoc}
*/
2015-01-04 22:43:39 +00:00
public function getSaveValue($value)
{
2014-10-10 21:50:05 +00:00
if (is_string($value) && !strlen($value)) {
2014-05-29 09:35:46 +00:00
return null;
2014-10-10 21:50:05 +00:00
}
2014-05-29 09:35:46 +00:00
2014-10-10 21:50:05 +00:00
if (is_array($value) && !count($value)) {
2014-05-29 09:35:46 +00:00
return null;
2014-10-10 21:50:05 +00:00
}
2014-05-29 09:35:46 +00:00
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}();
}
2014-10-10 21:50:05 +00:00
}