Browse Source

Fix merging of widgets config in FormHelper constructor.

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
ADmad 11 years ago
parent
commit
17fec53f9a
2 changed files with 72 additions and 19 deletions
  1. 32 19
      src/View/Helper/FormHelper.php
  2. 40 0
      tests/TestCase/View/Helper/FormHelperTest.php

+ 32 - 19
src/View/Helper/FormHelper.php

@@ -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}}>',
@@ -122,6 +108,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.
  *
  * @var array
@@ -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

+ 40 - 0
tests/TestCase/View/Helper/FormHelperTest.php

@@ -204,6 +204,46 @@ class FormHelperTest extends TestCase {
 	}
 
 /**
+ * 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.
  *
  * @return void