Refactor form widget to use an approach much like ReportContainer

This commit is contained in:
Samuel Georges 2015-02-28 13:37:06 +11:00
parent 6e54fea23f
commit f9e287e173
2 changed files with 121 additions and 117 deletions

View File

@ -28,7 +28,7 @@ class Filter extends WidgetBase
* @var string The context of this filter, scopes that do not belong
* to this context will not be shown.
*/
protected $context = null;
public $context = null;
//
// Object properties

View File

@ -23,27 +23,24 @@ use October\Rain\Database\Model;
*/
class Form extends WidgetBase
{
/**
* @var array Expected configuration:
*
* - fields: outside form field definitions
* - tabs: primary tab form field definitions
* - secondaryTabs: secondary tab form field definitions
* - arrayName: a HTML array name to use for each element
* - context: apply a context to this form and its fields
*/
public $config = [
'fields' => [],
'tabs' => [],
'secondaryTabs' => [],
'arrayName' => null,
'context' => null,
];
//
// Configurable properties
//
/**
* {@inheritDoc}
* @var array Form field configuration.
*/
protected $defaultAlias = 'form';
public $fields;
/**
* @var array Primary tab configuration.
*/
public $tabs;
/**
* @var array Secondary tab configuration.
*/
public $secondaryTabs;
/**
* @var Model Form model object.
@ -56,34 +53,10 @@ class Form extends WidgetBase
public $data;
/**
* @var boolean Determines if field definitions have been created.
* @var string The context of this form, fields that do not belong
* to this context will not be shown.
*/
protected $fieldsDefined = false;
/**
* @var array Collection of all fields used in this form.
*/
protected $fields = [];
/**
* @var array Collection of all form widgets used in this form.
*/
protected $formWidgets = [];
/**
* @var Backend\Classes\FormTabs Collection of fields not contained in a tab.
*/
protected $outsideTabs;
/**
* @var Backend\Classes\FormTabs Collection of fields inside the primary tabs.
*/
protected $primaryTabs;
/**
* @var Backend\Classes\FormTabs Collection of fields inside the secondary tabs.
*/
protected $secondaryTabs;
public $context = null;
/**
* @var string If the field element names should be contained in an array.
@ -91,11 +64,40 @@ class Form extends WidgetBase
*/
public $arrayName;
//
// Object properties
//
/**
* @var string The context of this form, fields that do not belong
* to this context will not be shown.
* {@inheritDoc}
*/
protected $activeContext = null;
protected $defaultAlias = 'form';
/**
* @var boolean Determines if field definitions have been created.
*/
protected $fieldsDefined = false;
/**
* @var array Collection of all fields used in this form.
* @see Backend\Classes\FormField
*/
protected $allFields = [];
/**
* @var object Collection of tab sections used in this form.
* @see Backend\Classes\FormTabs
*/
protected $allTabs = [
'outside' => null,
'primary' => null,
'secondary' => null,
];
/**
* @var array Collection of all form widgets used in this form.
*/
protected $formWidgets = [];
/**
* @var string Active session key, used for editing forms and deferred bindings.
@ -117,9 +119,18 @@ class Form extends WidgetBase
*/
public function init()
{
$this->fillFromConfig([
'fields',
'tabs',
'secondaryTabs',
'model',
'data',
'arrayName',
'context',
]);
$this->widgetManager = WidgetManager::instance();
$this->arrayName = $this->getConfig('arrayName');
$this->activeContext = $this->getConfig('context');
$this->allTabs = (object) $this->allTabs;
$this->validateModel();
}
@ -174,17 +185,10 @@ class Form extends WidgetBase
* Determine the partial to use based on the supplied section option
*/
if ($section = $options['section']) {
$section = strtolower($section);
switch (strtolower($section)) {
case 'outside':
$extraVars['tabs'] = $this->outsideTabs;
break;
case 'primary':
$extraVars['tabs'] = $this->primaryTabs;
break;
case 'secondary':
$extraVars['tabs'] = $this->secondaryTabs;
break;
if (isset($this->allTabs->{$section})) {
$extraVars['tabs'] = $this->allTabs->{$section};
}
$targetPartial = 'section';
@ -208,14 +212,14 @@ class Form extends WidgetBase
public function renderField($field, $options = [])
{
if (is_string($field)) {
if (!isset($this->fields[$field])) {
if (!isset($this->allFields[$field])) {
throw new ApplicationException(Lang::get(
'backend::lang.form.missing_definition',
compact('field')
));
}
$field = $this->fields[$field];
$field = $this->allFields[$field];
}
if (!isset($options['useContainer'])) {
@ -241,8 +245,6 @@ class Form extends WidgetBase
*/
protected function validateModel()
{
$this->model = $this->getConfig('model');
if (!$this->model) {
throw new ApplicationException(Lang::get(
'backend::lang.form.missing_model',
@ -250,7 +252,9 @@ class Form extends WidgetBase
));
}
$this->data = (object) $this->getConfig('data', $this->model);
$this->data = isset($this->data)
? (object) $this->data
: $this->model;
return $this->model;
}
@ -263,9 +267,9 @@ class Form extends WidgetBase
$this->defineFormFields();
$this->applyFiltersFromModel();
$this->vars['sessionKey'] = $this->getSessionKey();
$this->vars['outsideTabs'] = $this->outsideTabs;
$this->vars['primaryTabs'] = $this->primaryTabs;
$this->vars['secondaryTabs'] = $this->secondaryTabs;
$this->vars['outsideTabs'] = $this->allTabs->outside;
$this->vars['primaryTabs'] = $this->allTabs->primary;
$this->vars['secondaryTabs'] = $this->allTabs->secondary;
}
/**
@ -282,7 +286,7 @@ class Form extends WidgetBase
$this->model->fill($data);
$this->data = (object) array_merge((array) $this->data, (array) $data);
foreach ($this->fields as $field) {
foreach ($this->allFields as $field) {
$field->value = $this->getFieldValue($field);
}
@ -316,8 +320,8 @@ class Form extends WidgetBase
/*
* Extensibility
*/
$this->fireEvent('form.refreshFields', [$this->fields]);
Event::fire('backend.form.refreshFields', [$this, $this->fields]);
$this->fireEvent('form.refreshFields', [$this->allFields]);
Event::fire('backend.form.refreshFields', [$this, $this->allFields]);
/*
* If an array of fields is supplied, update specified fields individually.
@ -325,11 +329,11 @@ class Form extends WidgetBase
if (($updateFields = post('fields')) && is_array($updateFields)) {
foreach ($updateFields as $field) {
if (!isset($this->fields[$field])) {
if (!isset($this->allFields[$field])) {
continue;
}
$fieldObject = $this->fields[$field];
$fieldObject = $this->allFields[$field];
$result['#' . $fieldObject->getId('group')] = $this->makePartial('field', ['field' => $fieldObject]);
}
}
@ -373,51 +377,51 @@ class Form extends WidgetBase
/*
* Outside fields
*/
if (!isset($this->config->fields) || !is_array($this->config->fields)) {
$this->config->fields = [];
if (!isset($this->fields) || !is_array($this->fields)) {
$this->fields = [];
}
$this->outsideTabs = new FormTabs(FormTabs::SECTION_OUTSIDE, $this->config);
$this->addFields($this->config->fields);
$this->allTabs->outside = new FormTabs(FormTabs::SECTION_OUTSIDE, $this->config);
$this->addFields($this->fields);
/*
* Primary Tabs + Fields
*/
if (!isset($this->config->tabs['fields']) || !is_array($this->config->tabs['fields'])) {
$this->config->tabs['fields'] = [];
if (!isset($this->tabs['fields']) || !is_array($this->tabs['fields'])) {
$this->tabs['fields'] = [];
}
$this->primaryTabs = new FormTabs(FormTabs::SECTION_PRIMARY, $this->config->tabs);
$this->addFields($this->config->tabs['fields'], FormTabs::SECTION_PRIMARY);
$this->allTabs->primary = new FormTabs(FormTabs::SECTION_PRIMARY, $this->tabs);
$this->addFields($this->tabs['fields'], FormTabs::SECTION_PRIMARY);
/*
* Secondary Tabs + Fields
*/
if (!isset($this->config->secondaryTabs['fields']) || !is_array($this->config->secondaryTabs['fields'])) {
$this->config->secondaryTabs['fields'] = [];
if (!isset($this->secondaryTabs['fields']) || !is_array($this->secondaryTabs['fields'])) {
$this->secondaryTabs['fields'] = [];
}
$this->secondaryTabs = new FormTabs(FormTabs::SECTION_SECONDARY, $this->config->secondaryTabs);
$this->addFields($this->config->secondaryTabs['fields'], FormTabs::SECTION_SECONDARY);
$this->allTabs->secondary = new FormTabs(FormTabs::SECTION_SECONDARY, $this->secondaryTabs);
$this->addFields($this->secondaryTabs['fields'], FormTabs::SECTION_SECONDARY);
/*
* Extensibility
*/
$this->fireEvent('form.extendFields', [$this->fields]);
Event::fire('backend.form.extendFields', [$this, $this->fields]);
$this->fireEvent('form.extendFields', [$this->allFields]);
Event::fire('backend.form.extendFields', [$this, $this->allFields]);
/*
* Convert automatic spanned fields
*/
foreach ($this->outsideTabs->getTabs() as $fields) {
foreach ($this->allTabs->outside->getTabs() as $fields) {
$this->processAutoSpan($fields);
}
foreach ($this->primaryTabs->getTabs() as $fields) {
foreach ($this->allTabs->primary->getTabs() as $fields) {
$this->processAutoSpan($fields);
}
foreach ($this->secondaryTabs->getTabs() as $fields) {
foreach ($this->allTabs->secondary->getTabs() as $fields) {
$this->processAutoSpan($fields);
}
@ -425,25 +429,25 @@ class Form extends WidgetBase
* At least one tab section should stretch
*/
if (
$this->secondaryTabs->stretch === null
&& $this->primaryTabs->stretch === null
&& $this->outsideTabs->stretch === null
$this->allTabs->secondary->stretch === null
&& $this->allTabs->primary->stretch === null
&& $this->allTabs->outside->stretch === null
) {
if ($this->secondaryTabs->hasFields()) {
$this->secondaryTabs->stretch = true;
if ($this->allTabs->secondary->hasFields()) {
$this->allTabs->secondary->stretch = true;
}
elseif ($this->primaryTabs->hasFields()) {
$this->primaryTabs->stretch = true;
elseif ($this->allTabs->primary->hasFields()) {
$this->allTabs->primary->stretch = true;
}
else {
$this->outsideTabs->stretch = true;
$this->allTabs->outside->stretch = true;
}
}
/*
* Bind all form widgets to controller
*/
foreach ($this->fields as $field) {
foreach ($this->allFields as $field) {
if ($field->type != 'widget') {
continue;
}
@ -496,17 +500,17 @@ class Form extends WidgetBase
}
}
$this->fields[$name] = $fieldObj;
$this->allFields[$name] = $fieldObj;
switch (strtolower($addToArea)) {
case FormTabs::SECTION_PRIMARY:
$this->primaryTabs->addField($name, $fieldObj, $fieldTab);
$this->allTabs->primary->addField($name, $fieldObj, $fieldTab);
break;
case FormTabs::SECTION_SECONDARY:
$this->secondaryTabs->addField($name, $fieldObj, $fieldTab);
$this->allTabs->secondary->addField($name, $fieldObj, $fieldTab);
break;
default:
$this->outsideTabs->addField($name, $fieldObj, $fieldTab);
$this->allTabs->outside->addField($name, $fieldObj, $fieldTab);
break;
}
}
@ -528,21 +532,21 @@ class Form extends WidgetBase
*/
public function removeField($name)
{
if (!isset($this->fields[$name])) {
if (!isset($this->allFields[$name])) {
return false;
}
/*
* Remove from tabs
*/
$this->primaryTabs->removeField($name);
$this->secondaryTabs->removeField($name);
$this->outsideTabs->removeField($name);
$this->allTabs->primary->removeField($name);
$this->allTabs->secondary->removeField($name);
$this->allTabs->outside->removeField($name);
/*
* Remove from main collection
*/
unset($this->fields[$name]);
unset($this->allFields[$name]);
return true;
}
@ -714,7 +718,7 @@ class Form extends WidgetBase
*/
public function getFields()
{
return $this->fields;
return $this->allFields;
}
/**
@ -724,7 +728,7 @@ class Form extends WidgetBase
*/
public function getField($field)
{
return $this->fields[$field];
return $this->allFields[$field];
}
/**
@ -747,14 +751,14 @@ class Form extends WidgetBase
public function getFieldValue($field)
{
if (is_string($field)) {
if (!isset($this->fields[$field])) {
if (!isset($this->allFields[$field])) {
throw new ApplicationException(Lang::get(
'backend::lang.form.missing_definition',
compact('field')
));
}
$field = $this->fields[$field];
$field = $this->allFields[$field];
}
$defaultValue = (!$this->model->exists && $field->defaults !== '')
@ -795,7 +799,7 @@ class Form extends WidgetBase
/*
* Number fields should be converted to integers
*/
foreach ($this->fields as $field) {
foreach ($this->allFields as $field) {
if ($field->type != 'number') {
continue;
}
@ -827,7 +831,7 @@ class Form extends WidgetBase
* Handle fields that differ by fieldName and valueFrom
*/
$remappedFields = [];
foreach ($this->fields as $field) {
foreach ($this->allFields as $field) {
if ($field->fieldName == $field->valueFrom) {
continue;
}
@ -863,7 +867,7 @@ class Form extends WidgetBase
protected function applyFiltersFromModel()
{
if (method_exists($this->model, 'filterFields')) {
$this->model->filterFields((object) $this->fields, $this->getContext());
$this->model->filterFields((object) $this->allFields, $this->getContext());
}
}
@ -939,7 +943,7 @@ class Form extends WidgetBase
*/
public function getContext()
{
return $this->activeContext;
return $this->context;
}
/**