diff --git a/forms/Form.php b/forms/Form.php index 403195fe5..cb9d62785 100644 --- a/forms/Form.php +++ b/forms/Form.php @@ -1418,6 +1418,7 @@ class Form extends RequestHandler { if(is_object($data)) $this->record = $data; // dont include fields without data + /** @var FormField[] $dataFields */ $dataFields = $this->Fields()->dataFields(); if($dataFields) foreach($dataFields as $field) { $name = $field->getName(); @@ -1450,15 +1451,31 @@ class Form extends RequestHandler { $val = $data[$name]; } // If field is in array-notation we need to access nested data - else if(strpos($name,'[')) { - // First encode data using PHP's method of converting nested arrays to form data - $flatData = urldecode(http_build_query($data)); - // Then pull the value out from that flattened string - preg_match('/' . addcslashes($name,'[]') . '=([^&]*)/', $flatData, $matches); + else if(preg_match_all('/(.*)\[(.*)\]/U', $name, $matches)) { + //discard first match which is just the whole string + array_shift($matches); - if (isset($matches[1])) { - $exists = true; - $val = $matches[1]; + $keys = array_pop($matches); + $name = array_shift($matches); + $name = array_shift($name); + + if (array_key_exists($name, $data)) { + $tmpData = &$data[$name]; + // drill down into the data array looking for the corresponding value + foreach ($keys as $arrayKey) { + if ($arrayKey !== '') { + $tmpData = &$tmpData[$arrayKey]; + } else { + //empty square brackets means new array + if (is_array($tmpData)) { + $tmpData = array_shift($tmpData); + } + } + } + if ($tmpData) { + $val = $tmpData; + $exists = true; + } } } } diff --git a/tests/forms/FormTest.php b/tests/forms/FormTest.php index 3ec2a9490..910bbc0ce 100644 --- a/tests/forms/FormTest.php +++ b/tests/forms/FormTest.php @@ -58,10 +58,10 @@ class FormTest extends FunctionalTest { $form->loadDataFrom($requestData); $fields = $form->Fields(); - $this->assertEquals($fields->fieldByName('key1')->Value(), 'val1'); - $this->assertEquals($fields->fieldByName('namespace[key2]')->Value(), 'val2'); - $this->assertEquals($fields->fieldByName('namespace[key3][key4]')->Value(), 'val4'); - $this->assertEquals($fields->fieldByName('othernamespace[key5][key6][key7]')->Value(), 'val7'); + $this->assertEquals('val1', $fields->fieldByName('key1')->Value()); + $this->assertEquals('val2', $fields->fieldByName('namespace[key2]')->Value()); + $this->assertEquals('val4', $fields->fieldByName('namespace[key3][key4]')->Value()); + $this->assertEquals('val7', $fields->fieldByName('othernamespace[key5][key6][key7]')->Value()); } public function testSubmitReadonlyFields() {