diff --git a/src/FormElement/RadioElement.php b/src/FormElement/RadioElement.php
index c02ad772..dd3a3963 100644
--- a/src/FormElement/RadioElement.php
+++ b/src/FormElement/RadioElement.php
@@ -36,7 +36,10 @@ public function setOptions(array $options): self
$this->options = [];
foreach ($options as $value => $label) {
$option = (new RadioOption($value, $label))
- ->setDisabled(in_array($value, $this->disabledOptions, true));
+ ->setDisabled(
+ in_array($value, $this->disabledOptions, ! is_int($value))
+ || ($value === '' && in_array(null, $this->disabledOptions))
+ );
$this->options[$value] = $option;
}
@@ -74,9 +77,10 @@ public function getOption($value): RadioOption
public function setDisabledOptions(array $disabledOptions): self
{
if (! empty($this->options)) {
- foreach ($this->options as $option) {
+ foreach ($this->options as $value => $option) {
$option->setDisabled(
- in_array($option->getValue(), $disabledOptions, true)
+ in_array($value, $disabledOptions, ! is_int($value))
+ || ($value === '' && in_array(null, $disabledOptions))
);
}
@@ -111,12 +115,7 @@ protected function assemble()
->merge($option->getAttributes())
->registerAttributeCallback('checked',
function () use ($option) {
- $optionValue = $option->getValue();
-
- if ($optionValue === '') {
- $optionValue = null;
- }
- return $this->getValue() === $optionValue;
+ return $this->getValue() === $option->getValue();
}
)
->registerAttributeCallback('disabled',
@@ -126,7 +125,7 @@ function () use ($option) {
);
$labelAttributes = (new Attributes(['class' => RadioOption::LABEL_CLASS]))
- ->add('class', $option->getlabelCssClass());
+ ->add('class', $option->getLabelCssClass());
$label = new HtmlElement(
'label',
diff --git a/src/FormElement/RadioOption.php b/src/FormElement/RadioOption.php
index e2cd75d1..bb723724 100644
--- a/src/FormElement/RadioOption.php
+++ b/src/FormElement/RadioOption.php
@@ -27,11 +27,13 @@ class RadioOption
/**
* RadioOption constructor.
*
- * @param string|int $value
+ * @param string|int|null $value
* @param string $label
*/
public function __construct($value, string $label)
{
+ $value = $value === '' ? null : $value;
+
$this->value = $value;
$this->label = $label;
}
@@ -73,7 +75,7 @@ public function getValue()
/**
* Add css class to the option label
*
- * @param string|array|Attribute $labelCssClass
+ * @param string|string[] $labelCssClass
*
* @return $this
*/
diff --git a/tests/FormElement/RadioElementTest.php b/tests/FormElement/RadioElementTest.php
index 808eda49..a5800199 100644
--- a/tests/FormElement/RadioElementTest.php
+++ b/tests/FormElement/RadioElementTest.php
@@ -280,5 +280,131 @@ public function testNullAndTheEmptyStringAreEquallyHandled()
HTML;
$this->assertHtml($html, $radio2);
+
+ $radio->setDisabledOptions([null, 'foo']);
+ $radio2->setDisabledOptions(['', 'foo']);
+
+ $html = <<<'HTML'
+
+HTML;
+
+ $this->assertHtml($html, $radio);
+
+ $html = <<<'HTML'
+
+HTML;
+
+ $this->assertHtml($html, $radio2);
+ }
+
+ public function testSetOptionsResetsOptions()
+ {
+ $radio = new RadioElement('radio');
+ $radio->setOptions(['foo' => 'Foo', 'bar' => 'Bar']);
+
+ $this->assertInstanceOf(RadioOption::class, $radio->getOption('foo'));
+ $this->assertInstanceOf(RadioOption::class, $radio->getOption('bar'));
+
+ $radio->setOptions(['car' => 'Car', 'train' => 'Train']);
+
+ $this->expectExceptionMessage('There is no such option "foo"');
+ $radio->getOption('foo');
+
+ $this->expectExceptionMessage('There is no such option "bar"');
+ $radio->getOption('bar');
+
+ $this->assertInstanceOf(RadioOption::class, $radio->getOption('car'));
+ $this->assertInstanceOf(RadioOption::class, $radio->getOption('train'));
+ }
+
+ public function testOrderOfOptionsAndDisabledOptionsDoesNotMatter()
+ {
+ $radio = new RadioElement('test', [
+ 'label' => 'Test',
+ 'options' => [
+ 'foo' => 'Foo',
+ 'bar' => 'Bar'
+ ],
+ 'disabledOptions' => ['foo', 'bar']
+ ]);
+
+ $html = <<<'HTML'
+
+
+HTML;
+ $this->assertHtml($html, $radio);
+
+ $radio = new RadioElement('test', [
+ 'disabledOptions' => ['foo', 'bar'],
+ 'label' => 'Test',
+ 'options' => [
+ 'foo' => 'Foo',
+ 'bar' => 'Bar'
+ ]
+ ]);
+
+ $this->assertHtml($html, $radio);
+ }
+
+ public function testGetOptionReturnsPreviouslySetOption()
+ {
+ $radio = new RadioElement('radio');
+ $radio->setOptions(['' => 'Empty String', 'foo' => 'Foo', 'bar' => 'Bar']);
+
+ $this->assertNull($radio->getOption('')->getValue());
+ $this->assertSame('Empty String', $radio->getOption('')->getLabel());
+
+ $this->assertSame('foo', $radio->getOption('foo')->getValue());
+ $this->assertSame('Foo', $radio->getOption('foo')->getLabel());
+
+ $radio->setOptions(['' => 'Please Choose', 'car' => 'Car', 'train' => 'Train']);
+
+ $this->assertNull($radio->getOption('')->getValue());
+ $this->assertSame('Please Choose', $radio->getOption('')->getLabel());
+
+ $this->assertSame('car', $radio->getOption('car')->getValue());
+ $this->assertSame('Car', $radio->getOption('car')->getLabel());
+ }
+
+ public function testNullAndTheEmptyStringAreAlsoEquallyHandledWhileDisablingOptions()
+ {
+ $radio = new RadioElement('radio');
+ $radio->setOptions([null => 'Foo', 'bar' => 'Bar']);
+ $radio->setDisabledOptions([null]);
+
+ $this->assertTrue($radio->getOption(null)->isDisabled());
+
+ $radio = new RadioElement('radio');
+ $radio->setOptions(['' => 'Foo', 'bar' => 'Bar']);
+ $radio->setDisabledOptions(['']);
+
+ $this->assertTrue($radio->getOption('')->isDisabled());
+
+ $radio = new RadioElement('radio');
+ $radio->setOptions([null => 'Foo', 'bar' => 'Bar']);
+ $radio->setDisabledOptions(['']);
+
+ $this->assertTrue($radio->getOption(null)->isDisabled());
+ $radio = new RadioElement('radio');
+ $radio->setOptions(['' => 'Foo', 'bar' => 'Bar']);
+ $radio->setDisabledOptions([null]);
+
+ $this->assertTrue($radio->getOption('')->isDisabled());
+ }
+
+ public function testGetOptionGetValueAndElementGetValueHandleNullAndTheEmptyStringEqually()
+ {
+ $radio = new RadioElement('radio');
+ $radio->setOptions(['' => 'Foo']);
+ $radio->setValue('');
+
+ $this->assertNull($radio->getValue());
+ $this->assertNull($radio->getOption('')->getValue());
+
+ $radio = new RadioElement('radio');
+ $radio->setOptions([null => 'Foo']);
+
+ $this->assertNull($radio->getValue());
+ $this->assertNull($radio->getOption(null)->getValue());
}
}