Massive improvements to RelationController, most button types are available

This commit is contained in:
Samuel Georges 2015-01-25 13:02:06 +11:00
parent 7a23976f1c
commit b58666b4a0
6 changed files with 155 additions and 32 deletions

View File

@ -22,6 +22,11 @@ class RelationController extends ControllerBehavior
*/ */
const PARAM_FIELD = '_relation_field'; const PARAM_FIELD = '_relation_field';
/**
* @var const Postback parameter for the active management mode.
*/
const PARAM_MODE = '_relation_mode';
/** /**
* @var Backend\Classes\WidgetBase Reference to the search widget object. * @var Backend\Classes\WidgetBase Reference to the search widget object.
*/ */
@ -107,6 +112,16 @@ class RelationController extends ControllerBehavior
*/ */
protected $alias; protected $alias;
/**
* @var array The set of buttons to display in view mode.
*/
protected $toolbarButtons;
/**
* @var Model Reference to the model used for viewing (form only).
*/
protected $viewModel;
/** /**
* @var string Relation has many (multi) or has one (single). * @var string Relation has many (multi) or has one (single).
*/ */
@ -200,8 +215,9 @@ class RelationController extends ControllerBehavior
$this->relationModel = $this->relationObject->getRelated(); $this->relationModel = $this->relationObject->getRelated();
$this->readOnly = $this->getConfig('readOnly'); $this->readOnly = $this->getConfig('readOnly');
$this->viewMode = $this->evalViewMode(); $this->toolbarButtons = $this->evalToolbarButtons();
$this->manageMode = $this->evalManageMode(); $this->viewMode = $this->viewMode ?: $this->evalViewMode();
$this->manageMode = $this->manageMode ?: $this->evalManageMode();
$this->manageId = post('manage_id'); $this->manageId = post('manage_id');
/* /*
@ -235,6 +251,33 @@ class RelationController extends ControllerBehavior
} }
} }
/**
* Determine the default buttons based on the model relationship type.
* @return string
*/
protected function evalToolbarButtons()
{
if ($buttons = $this->getConfig('view[toolbarButtons]')) {
return is_array($buttons)
? $buttons
: array_map('trim', explode('|', $buttons));
}
switch ($this->relationType) {
case 'hasMany':
return ['add', 'create', 'delete', 'remove'];
case 'belongsToMany':
return ['create', 'add', 'remove'];
case 'belongsTo':
return ['create', 'update', 'link', 'delete', 'unlink'];
case 'hasOne':
return ['create', 'update', 'link', 'delete', 'unlink'];
}
}
/** /**
* Determine the view mode based on the model relationship type. * Determine the view mode based on the model relationship type.
* @return string * @return string
@ -258,6 +301,10 @@ class RelationController extends ControllerBehavior
*/ */
protected function evalManageMode() protected function evalManageMode()
{ {
if ($mode = post(self::PARAM_MODE)) {
return $mode;
}
switch ($this->relationType) { switch ($this->relationType) {
case 'belongsTo': case 'belongsTo':
$mode = 'list'; $mode = 'list';
@ -386,8 +433,10 @@ class RelationController extends ControllerBehavior
$this->vars['relationToolbarWidget'] = $this->toolbarWidget; $this->vars['relationToolbarWidget'] = $this->toolbarWidget;
$this->vars['relationManageMode'] = $this->manageMode; $this->vars['relationManageMode'] = $this->manageMode;
$this->vars['relationManageWidget'] = $this->manageWidget; $this->vars['relationManageWidget'] = $this->manageWidget;
$this->vars['relationToolbarButtons'] = $this->toolbarButtons;
$this->vars['relationViewMode'] = $this->viewMode; $this->vars['relationViewMode'] = $this->viewMode;
$this->vars['relationViewWidget'] = $this->viewWidget; $this->vars['relationViewWidget'] = $this->viewWidget;
$this->vars['relationViewModel'] = $this->viewModel;
$this->vars['relationPivotWidget'] = $this->pivotWidget; $this->vars['relationPivotWidget'] = $this->pivotWidget;
$this->vars['relationSessionKey'] = $this->relationGetSessionKey(); $this->vars['relationSessionKey'] = $this->relationGetSessionKey();
} }
@ -482,11 +531,13 @@ class RelationController extends ControllerBehavior
public function onRelationButtonAdd() public function onRelationButtonAdd()
{ {
$this->manageMode = 'list';
return $this->onRelationManageForm(); return $this->onRelationManageForm();
} }
public function onRelationButtonCreate() public function onRelationButtonCreate()
{ {
$this->manageMode = 'form';
return $this->onRelationManageForm(); return $this->onRelationManageForm();
} }
@ -497,6 +548,7 @@ class RelationController extends ControllerBehavior
public function onRelationButtonLink() public function onRelationButtonLink()
{ {
$this->manageMode = 'list';
return $this->onRelationManageForm(); return $this->onRelationManageForm();
} }
@ -512,6 +564,7 @@ class RelationController extends ControllerBehavior
public function onRelationButtonUpdate() public function onRelationButtonUpdate()
{ {
$this->manageMode = 'form';
return $this->onRelationManageForm(); return $this->onRelationManageForm();
} }
@ -539,16 +592,32 @@ class RelationController extends ControllerBehavior
*/ */
public function onRelationManageCreate() public function onRelationManageCreate()
{ {
$this->manageMode = 'form';
$this->beforeAjax(); $this->beforeAjax();
$saveData = $this->manageWidget->getSaveData(); $saveData = $this->manageWidget->getSaveData();
if ($this->viewMode == 'multi') { if ($this->viewMode == 'multi') {
$newModel = $this->relationObject->create($saveData, $this->relationGetSessionKey(true)); if ($this->relationType == 'hasMany') {
$newModel = $this->relationObject->create($saveData, $this->relationGetSessionKey(true));
}
elseif ($this->relationType == 'belongsToMany') {
$newModel = $this->relationObject->create($saveData, [], $this->relationGetSessionKey(true));
}
$newModel->commitDeferred($this->manageWidget->getSessionKey()); $newModel->commitDeferred($this->manageWidget->getSessionKey());
} }
elseif ($this->viewMode == 'single') { elseif ($this->viewMode == 'single') {
$newModel = $this->viewModel;
$this->viewWidget->setFormValues($saveData); $this->viewWidget->setFormValues($saveData);
$this->viewWidget->model->save();
if ($this->relationType == 'belongsTo') {
$newModel->save();
$this->relationObject->associate($newModel);
$this->relationObject->getParent()->save();
}
elseif ($this->relationType == 'hasOne') {
$this->relationObject->add($newModel);
}
} }
return $this->relationRefresh(); return $this->relationRefresh();
@ -559,6 +628,7 @@ class RelationController extends ControllerBehavior
*/ */
public function onRelationManageUpdate() public function onRelationManageUpdate()
{ {
$this->manageMode = 'form';
$this->beforeAjax(); $this->beforeAjax();
$saveData = $this->manageWidget->getSaveData(); $saveData = $this->manageWidget->getSaveData();
@ -568,7 +638,7 @@ class RelationController extends ControllerBehavior
} }
elseif ($this->viewMode == 'single') { elseif ($this->viewMode == 'single') {
$this->viewWidget->setFormValues($saveData); $this->viewWidget->setFormValues($saveData);
$this->viewWidget->model->save(); $this->viewModel->save();
} }
return ['#'.$this->relationGetId('view') => $this->relationRenderView()]; return ['#'.$this->relationGetId('view') => $this->relationRenderView()];
@ -600,13 +670,13 @@ class RelationController extends ControllerBehavior
* Single (belongs to, has one) * Single (belongs to, has one)
*/ */
elseif ($this->viewMode == 'single') { elseif ($this->viewMode == 'single') {
$relatedModel = $this->viewWidget->model; $relatedModel = $this->viewModel;
if ($relatedModel->exists) { if ($relatedModel->exists) {
$relatedModel->delete(); $relatedModel->delete();
} }
$this->viewWidget->setFormValues([]); $this->viewWidget->setFormValues([]);
$this->viewWidget->model = $this->relationModel; $this->viewModel = $this->relationModel;
} }
return $this->relationRefresh(); return $this->relationRefresh();
@ -654,9 +724,16 @@ class RelationController extends ControllerBehavior
*/ */
elseif ($this->viewMode == 'single') { elseif ($this->viewMode == 'single') {
if ($recordId && ($model = $this->relationModel->find($recordId))) { if ($recordId && ($model = $this->relationModel->find($recordId))) {
$this->relationObject->associate($model);
$this->relationObject->getParent()->save(); if ($this->relationType == 'belongsTo') {
$this->relationObject->associate($model);
$this->relationObject->getParent()->save();
}
elseif ($this->relationType == 'hasOne') {
$this->relationObject->add($model);
}
$this->viewWidget->setFormValues($model->attributes); $this->viewWidget->setFormValues($model->attributes);
} }
} }
@ -664,7 +741,7 @@ class RelationController extends ControllerBehavior
} }
/** /**
* Remove an existing related model from the primary model (join table only) * Remove an existing related model from the primary model
*/ */
public function onRelationManageRemove() public function onRelationManageRemove()
{ {
@ -680,15 +757,38 @@ class RelationController extends ControllerBehavior
$checkedIds = $recordId ? [$recordId] : post('checked'); $checkedIds = $recordId ? [$recordId] : post('checked');
if (is_array($checkedIds)) { if (is_array($checkedIds)) {
$this->relationObject->detach($checkedIds);
if ($this->relationType == 'belongsToMany') {
$this->relationObject->detach($checkedIds);
}
elseif ($this->relationType == 'hasMany') {
$relatedModel = $this->relationObject->getRelated();
foreach ($checkedIds as $relationId) {
if ($obj = $relatedModel->find($relationId)) {
$this->relationObject->remove($obj);
}
}
}
} }
} }
/* /*
* Unlink * Unlink
*/ */
elseif ($this->viewMode == 'single') { elseif ($this->viewMode == 'single') {
$this->relationObject->dissociate(); if ($this->relationType == 'belongsTo') {
$this->relationObject->getParent()->save(); $this->relationObject->dissociate();
$this->relationObject->getParent()->save();
}
elseif ($this->relationType == 'hasOne') {
if ($obj = $this->relationModel->find($recordId)) {
$this->relationObject->remove($obj);
}
elseif ($this->viewModel->exists) {
$this->relationObject->remove($this->viewModel);
}
}
$this->viewWidget->setFormValues([]); $this->viewWidget->setFormValues([]);
} }
@ -762,7 +862,7 @@ class RelationController extends ControllerBehavior
$defaultButtons = '~/modules/backend/behaviors/relationcontroller/partials/_toolbar.htm'; $defaultButtons = '~/modules/backend/behaviors/relationcontroller/partials/_toolbar.htm';
} }
$defaultConfig['buttons'] = $this->getConfig('view[toolbarButtons]', $defaultButtons); $defaultConfig['buttons'] = $this->getConfig('view[toolbarPartial]', $defaultButtons);
/* /*
* Make config * Make config
@ -856,10 +956,10 @@ class RelationController extends ControllerBehavior
elseif ($this->viewMode == 'single') { elseif ($this->viewMode == 'single') {
$query = $this->relationObject; $query = $this->relationObject;
$this->controller->relationExtendQuery($query, $this->field); $this->controller->relationExtendQuery($query, $this->field);
$model = $query->getResults() ?: $this->relationModel; $this->viewModel = $query->getResults() ?: $this->relationModel;
$config = $this->makeConfig($this->config->form); $config = $this->makeConfig($this->config->form);
$config->model = $model; $config->model = $this->viewModel;
$config->arrayName = class_basename($this->relationModel); $config->arrayName = class_basename($this->relationModel);
$config->context = 'relation'; $config->context = 'relation';
$config->alias = $this->alias . 'ViewForm'; $config->alias = $this->alias . 'ViewForm';

View File

@ -2,6 +2,6 @@
data-control="popup" data-control="popup"
data-handler="onRelationButtonCreate" data-handler="onRelationButtonCreate"
href="javascript:;" href="javascript:;"
class="btn btn-sm btn-primary oc-icon-plus"> class="btn btn-sm btn-primary oc-icon-file-o">
<?= e(trans('backend::lang.relation.create_name', ['name'=>trans($relationLabel)])) ?> <?= e(trans('backend::lang.relation.create_name', ['name'=>trans($relationLabel)])) ?>
</a> </a>

View File

@ -1,13 +1,22 @@
<button <?php if ($relationViewMode == 'single'): ?>
class="btn btn-sm btn-default oc-icon-trash-o" <button
onclick="$(this).data('request-data', { class="btn btn-sm btn-default oc-icon-minus"
checked: $('#<?= $this->relationGetId('view') ?> .control-list').listWidget('getChecked') data-request="onRelationButtonRemove"
})" data-stripe-load-indicator>
disabled="disabled" <?= e(trans('backend::lang.relation.remove')) ?>
data-request="onRelationButtonRemove" </button>
data-trigger-type="enable" <?php else: ?>
data-trigger="#<?= $this->relationGetId('view') ?> .control-list input[type=checkbox]" <button
data-trigger-condition="checked" class="btn btn-sm btn-default oc-icon-minus"
data-stripe-load-indicator> onclick="$(this).data('request-data', {
<?= e(trans('backend::lang.relation.remove')) ?> checked: $('#<?= $this->relationGetId('view') ?> .control-list').listWidget('getChecked')
</button> })"
disabled="disabled"
data-request="onRelationButtonRemove"
data-trigger-type="enable"
data-trigger="#<?= $this->relationGetId('view') ?> .control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.remove')) ?>
</button>
<?php endif ?>

View File

@ -4,5 +4,5 @@
data-request="onRelationButtonUnlink" data-request="onRelationButtonUnlink"
data-request-confirm="<?= e(trans('backend::lang.relation.unlink_confirm')) ?>" data-request-confirm="<?= e(trans('backend::lang.relation.unlink_confirm')) ?>"
data-stripe-load-indicator> data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.unlink_name', ['name'=>trans($relationLabel)])) ?> <?= e(trans('backend::lang.relation.unlink')) ?>
</a> </a>

View File

@ -1,5 +1,18 @@
<div data-control="toolbar"> <div data-control="toolbar">
<?php foreach ($relationToolbarButtons as $button): ?>
<?php if ($button == 'update'): ?>
<?= $this->relationMakePartial('button_update', [
'relationManageId' => $relationViewModel->id
]) ?>
<?php else: ?>
<?= $this->relationMakePartial('button_'.$button) ?>
<?php endif ?>
<?php endforeach ?>
<?php /*
<?php if ($relationType == 'hasMany'): ?> <?php if ($relationType == 'hasMany'): ?>
<?= $this->relationMakePartial('button_create') ?> <?= $this->relationMakePartial('button_create') ?>
@ -25,7 +38,7 @@
<?php endif ?> <?php endif ?>
<?php endif ?> <?php endif ?>
*/ ?>
</div> </div>

View File

@ -187,6 +187,7 @@ return [
'concurrency_file_changed_description' => "The file you're editing has been changed on disk by another user. You can either reload the file and lose your changes or override the file on the disk." 'concurrency_file_changed_description' => "The file you're editing has been changed on disk by another user. You can either reload the file and lose your changes or override the file on the disk."
], ],
'relation' => [ 'relation' => [
'missing_config' => "Relation behavior does not have any configuration for ':config'.",
'missing_definition' => "Relation behavior does not contain a definition for ':field'.", 'missing_definition' => "Relation behavior does not contain a definition for ':field'.",
'missing_model' => "Relation behavior used in :class does not have a model defined.", 'missing_model' => "Relation behavior used in :class does not have a model defined.",
'invalid_action_single' => "This action cannot be performed on a singular relationship.", 'invalid_action_single' => "This action cannot be performed on a singular relationship.",