diff --git a/core/lib/Drupal/Core/Form/FormStateDecoratorBase.php b/core/lib/Drupal/Core/Form/FormStateDecoratorBase.php index 13f0042..9361b87 100644 --- a/core/lib/Drupal/Core/Form/FormStateDecoratorBase.php +++ b/core/lib/Drupal/Core/Form/FormStateDecoratorBase.php @@ -469,55 +469,6 @@ public function &getValues() { /** * {@inheritdoc} */ - public function &getValue($key, $default = NULL) { - return $this->decoratedFormState->getValue($key, $default); - } - - /** - * {@inheritdoc} - */ - public function setValues(array $values) { - return $this->decoratedFormState->setValues($values); - } - - /** - * {@inheritdoc} - */ - public function setValue($key, $value) { - return $this->decoratedFormState->setValue($key, $value); - } - - /** - * {@inheritdoc} - */ - public function unsetValue($key) { - return $this->decoratedFormState->unsetValue($key); - } - - /** - * {@inheritdoc} - */ - public function hasValue($key) { - return $this->decoratedFormState->hasValue($key); - } - - /** - * {@inheritdoc} - */ - public function isValueEmpty($key) { - return $this->decoratedFormState->isValueEmpty($key); - } - - /** - * {@inheritdoc} - */ - public function setValueForElement(array $element, $value) { - return $this->decoratedFormState->getValues($element, $value); - } - - /** - * {@inheritdoc} - */ public function setResponse(Response $response) { return $this->decoratedFormState->setResponse($response); } @@ -554,7 +505,7 @@ public function getRedirect() { * {@inheritdoc} */ public static function hasAnyErrors() { - return FormStateManager::hasAnyErrors(); + return FormState::hasAnyErrors(); } /** @@ -638,7 +589,7 @@ public function getCleanValueKeys() { * {@inheritdoc} */ public function setCleanValueKeys(array $cleanValueKeys) { - return $this->decoratedFormState->cleanValues($cleanValueKeys); + return $this->decoratedFormState->setCleanValueKeys($cleanValueKeys); } /** diff --git a/core/lib/Drupal/Core/Form/SubFormState.php b/core/lib/Drupal/Core/Form/SubFormState.php index a27ad87..dbdb7b9 100644 --- a/core/lib/Drupal/Core/Form/SubFormState.php +++ b/core/lib/Drupal/Core/Form/SubFormState.php @@ -8,11 +8,12 @@ namespace Drupal\Core\Form; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Render\Element; /** * Stores information about the state of a subform. */ -class SubFormState extends FormStateDecoratorBase implements FormStateInterface { +class SubFormState extends FormStateDecoratorBase { use FormStateValuesTrait; @@ -55,9 +56,17 @@ public function __construct(FormStateInterface $parent_form_state, array $array_ * The element to create the sub form state for. * * @return static + * + * @throws \InvalidArgumentException + * Thrown when the form element does not wrap other form elements, or if it + * does not have the necessary Form API properties assigned. */ public static function createForFormElement(FormStateInterface $parent_form_state, array $element) { // Make sure the element contains the required properties. + $children = Element::children($element); + if (empty($children)) { + throw new \InvalidArgumentException('nope'); + } $required_keys = ['#array_parents', '#parents']; foreach ($required_keys as $required_key) { if (!array_key_exists($required_key, $element) || !is_array($element[$required_key])) { diff --git a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php index 3b5ab7a..4fca585 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php @@ -427,6 +427,7 @@ public function testGetFormStateForElement() { $element = [ '#parents' => ['foo'], '#array_parents' => ['foo'], + 'bar' => [], ]; $sub_form_state = $form_state->getFormStateForElement($element); diff --git a/core/tests/Drupal/Tests/Core/Form/SubFormStateTest.php b/core/tests/Drupal/Tests/Core/Form/SubFormStateTest.php index e782cdd..55c060a 100644 --- a/core/tests/Drupal/Tests/Core/Form/SubFormStateTest.php +++ b/core/tests/Drupal/Tests/Core/Form/SubFormStateTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\Core\Form; +use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; use Drupal\Tests\UnitTestCase; @@ -30,6 +31,24 @@ class SubFormStateTest extends UnitTestCase { 'name' => 'Dodger', ], ]; + protected $element = [ + 'foo' => [ + '#parents' => ['foo'], + '#array_parents' => ['foo'], + ], + 'dog' => [ + '#parents' => ['dog'], + '#array_parents' => ['dog'], + 'breed' => [ + '#parents' => ['dog', 'breed'], + '#array_parents' => ['dog', 'breed'], + ], + 'name' => [ + '#parents' => ['dog', 'name'], + '#array_parents' => ['dog', 'name'], + ], + ], + ]; /** * @covers ::createForFormElement @@ -39,6 +58,7 @@ public function testCreateForFormElement() { $element = [ '#parents' => ['foo'], '#array_parents' => ['foo'], + 'bar' => [], ]; $sub_form_state = $form_state->getFormStateForElement($element); @@ -54,7 +74,9 @@ public function testCreateForFormElement() { */ public function testCreateForFormElementMissingArrayParents() { $form_state = new FormState(); - $element = []; + $element = [ + 'bar' => [], + ]; $form_state->getFormStateForElement($element); } @@ -69,6 +91,7 @@ public function testCreateForFormElementMissingParents() { $form_state = new FormState(); $element = [ '#array_parents' => ['foo'], + 'bar' => [], ]; $form_state->getFormStateForElement($element); @@ -82,11 +105,8 @@ public function testCreateForFormElementMissingParents() { public function testGetValues($parents, $expected) { $form_state = new FormState(); $form_state->setValues($this->initialValues); - $element = [ - '#parents' => $parents, - '#array_parents' => $parents, - ]; + $element = NestedArray::getValue($this->element, $parents); $sub_form_state = $form_state->getFormStateForElement($element); $sub_values = $sub_form_state->getValues(); $this->assertSame($expected, $sub_values); @@ -94,26 +114,34 @@ public function testGetValues($parents, $expected) { public function providerTestGetValues() { $data = []; - $data['exist1'] = [ + $data['exist'] = [ ['dog'], $this->initialValues['dog'], ]; - $data['exist2'] = [ + return $data; + } + + /** + * @covers ::getValues + * + * @dataProvider providerTestGetValuesBroken + * + * @expectedException \InvalidArgumentException + */ + public function testGetValuesBroken($parents, $expected) { + $this->testGetValues($parents, $expected); + } + + public function providerTestGetValuesBroken() { + $data = []; + $data['exist'] = [ ['foo'], $this->initialValues['foo'], ]; - $data['not_exist'] = [ - ['cat'], - [], - ]; $data['nested'] = [ ['dog', 'name'], 'Dodger', ]; - $data['empty_parents'] = [ - [], - $this->initialValues, - ]; return $data; } @@ -125,11 +153,8 @@ public function providerTestGetValues() { public function testGetValue($parents, $key, $expected, $default = NULL) { $form_state = new FormState(); $form_state->setValues($this->initialValues); - $element = [ - '#parents' => $parents, - '#array_parents' => $parents, - ]; + $element = NestedArray::getValue($this->element, $parents); $sub_form_state = $form_state->getFormStateForElement($element); $sub_values = $sub_form_state->getValue($key, $default); $this->assertSame($expected, $sub_values); @@ -142,32 +167,27 @@ public function providerTestGetValue() { 'name', 'Dodger', ]; - $data['not_exist'] = [ - ['cat'], - 'cat', - NULL, - ]; + return $data; + } + + /** + * @covers ::getValue + * + * @dataProvider providerTestGetValueBroken + * + * @expectedException \InvalidArgumentException + */ + public function testGetValueBroken($parents, $key, $expected, $default = NULL) { + $this->testGetValue($parents, $key, $expected, $default); + } + + public function providerTestGetValueBroken() { + $data = []; $data['nested'] = [ ['dog', 'name'], NULL, 'Dodger', ]; - $data['not_exist_with_default'] = [ - ['cat'], - 'cat', - 'Steak', - 'Steak', - ]; - $data['empty_parents_null_key'] = [ - [], - NULL, - $this->initialValues, - ]; - $data['empty_parents'] = [ - [], - 'dog', - $this->initialValues['dog'], - ]; return $data; } @@ -179,11 +199,8 @@ public function providerTestGetValue() { public function testSetValues($parents, $new_values, $expected) { $form_state = new FormState(); $form_state->setValues($this->initialValues); - $element = [ - '#parents' => $parents, - '#array_parents' => $parents, - ]; + $element = NestedArray::getValue($this->element, $parents); $sub_form_state = $form_state->getFormStateForElement($element); $sub_form_state->setValues($new_values); $this->assertSame($expected, $form_state->getValues()); @@ -191,7 +208,7 @@ public function testSetValues($parents, $new_values, $expected) { public function providerTestSetValues() { $data = []; - $data['exist1'] = [ + $data['exist'] = [ ['dog'], [], [ @@ -199,7 +216,23 @@ public function providerTestSetValues() { 'dog' => [], ], ]; - $data['exist2'] = [ + return $data; + } + + /** + * @covers ::setValues + * + * @dataProvider providerTestSetValuesBroken + * + * @expectedException \InvalidArgumentException + */ + public function testSetValuesBroken($parents, $new_values, $expected) { + $this->testSetValues($parents, $new_values, $expected); + } + + public function providerTestSetValuesBroken() { + $data = []; + $data['exist'] = [ ['foo'], [], [ @@ -207,11 +240,6 @@ public function providerTestSetValues() { 'dog' => $this->initialValues['dog'], ], ]; - $data['not_exist'] = [ - ['cat'], - [], - $this->initialValues, - ]; return $data; }