Skip to content

Commit

Permalink
Fix merging of widgets config in FormHelper constructor.
Browse files Browse the repository at this point in the history
Relying on InstanceTrait::config() to merge the config caused problems as we
want the config array of each widget to be overwritten instead of being merged.

Also keeping the 'widgets' and 'registry' key in config served no purpose as
changing them at runtime wouldn't do anything since widget registry instance is
already created by through helper's constructor.

Fixes #5067
  • Loading branch information
ADmad committed Nov 3, 2014
1 parent 5d2d928 commit 17fec53
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 19 deletions.
51 changes: 32 additions & 19 deletions src/View/Helper/FormHelper.php
Expand Up @@ -74,20 +74,6 @@ class FormHelper extends Helper {
'date' => 'date', 'float' => 'number', 'integer' => 'number',
'decimal' => 'number', 'binary' => 'file', 'uuid' => 'string'
],
'widgets' => [
'button' => ['Cake\View\Widget\ButtonWidget'],
'checkbox' => ['Cake\View\Widget\CheckboxWidget'],
'file' => ['Cake\View\Widget\FileWidget'],
'label' => ['Cake\View\Widget\LabelWidget'],
'nestingLabel' => ['Cake\View\Widget\NestingLabelWidget'],
'multicheckbox' => ['Cake\View\Widget\MultiCheckboxWidget', 'nestingLabel'],
'radio' => ['Cake\View\Widget\RadioWidget', 'nestingLabel'],
'select' => ['Cake\View\Widget\SelectBoxWidget'],
'textarea' => ['Cake\View\Widget\TextareaWidget'],
'datetime' => ['Cake\View\Widget\DateTimeWidget', 'select'],
'_default' => ['Cake\View\Widget\BasicWidget'],
],
'registry' => null,
'templates' => [
'button' => '<button{{attrs}}>{{text}}</button>',
'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
Expand Down Expand Up @@ -121,6 +107,25 @@ class FormHelper extends Helper {
]
];

/**
* Default widgets
*
* @var array
*/
protected $_defaultWigets = [
'button' => ['Cake\View\Widget\ButtonWidget'],
'checkbox' => ['Cake\View\Widget\CheckboxWidget'],
'file' => ['Cake\View\Widget\FileWidget'],
'label' => ['Cake\View\Widget\LabelWidget'],
'nestingLabel' => ['Cake\View\Widget\NestingLabelWidget'],
'multicheckbox' => ['Cake\View\Widget\MultiCheckboxWidget', 'nestingLabel'],
'radio' => ['Cake\View\Widget\RadioWidget', 'nestingLabel'],
'select' => ['Cake\View\Widget\SelectBoxWidget'],
'textarea' => ['Cake\View\Widget\TextareaWidget'],
'datetime' => ['Cake\View\Widget\DateTimeWidget', 'select'],
'_default' => ['Cake\View\Widget\BasicWidget'],
];

/**
* List of fields created, used with secure forms.
*
Expand Down Expand Up @@ -190,17 +195,25 @@ class FormHelper extends Helper {
* @param array $config Configuration settings for the helper.
*/
public function __construct(View $View, array $config = []) {
parent::__construct($View, $config);
$config = $this->_config;
$registry = null;
$widgets = $this->_defaultWigets;
if (isset($config['registry'])) {
$registry = $config['registry'];
unset($config['registry']);
}
if (isset($config['widgets'])) {
$widgets = $config['widgets'] + $widgets;
unset($config['widgets']);
}

$this->widgetRegistry($config['registry'], $config['widgets']);
$this->config(['widgets' => null, 'registry' => null]);
parent::__construct($View, $config);

$this->widgetRegistry($registry, $widgets);
$this->_addDefaultContextProviders();
}

/**
* Set the input registry the helper will use.
* Set the wiget registry the helper will use.
*
* @param \Cake\View\Widget\WidgetRegistry $instance The registry instance to set.
* @param array $widgets An array of widgets
Expand Down
40 changes: 40 additions & 0 deletions tests/TestCase/View/Helper/FormHelperTest.php
Expand Up @@ -203,6 +203,46 @@ public function testConstructTemplatesFile() {
$this->assertContains('<input', $result);
}

/**
* Test that when specifying custom widgets the config array for that widget
* is overwritten instead of merged.
*
* @return void
*/
public function testConstructWithWigets() {
$expected = [
'button' => ['Cake\View\Widget\ButtonWidget'],
'checkbox' => ['Cake\View\Widget\CheckboxWidget'],
'file' => ['Cake\View\Widget\FileWidget'],
'label' => ['Cake\View\Widget\LabelWidget'],
'nestingLabel' => ['Cake\View\Widget\NestingLabelWidget'],
'multicheckbox' => ['Cake\View\Widget\MultiCheckboxWidget', 'nestingLabel'],
'radio' => ['Cake\View\Widget\RadioWidget', 'nestingLabel'],
'select' => ['Cake\View\Widget\SelectBoxWidget'],
'textarea' => ['Cake\View\Widget\TextareaWidget'],
'datetime' => ['MyPlugin\View\Widget\DateTimeWidget', 'select'],
'_default' => ['Cake\View\Widget\BasicWidget']
];

$helper = $this->getMock(
'Cake\View\Helper\FormHelper',
['widgetRegistry'],
[],
'',
false
);
$helper->expects($this->once())
->method('widgetRegistry')
->with(null, $expected);

$config = [
'widgets' => [
'datetime' => ['MyPlugin\View\Widget\DateTimeWidget', 'select']
]
];
$helper->__construct($this->View, $config);
}

/**
* Test registering a new widget class and rendering it.
*
Expand Down

0 comments on commit 17fec53

Please sign in to comment.