diff --git a/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md b/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md
index 7a4bf0c9f..64fae0889 100644
--- a/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md
+++ b/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md
@@ -14,7 +14,7 @@ can be rendered out using custom templates using `setTemplate`.
$field = new TextField(..);
$field->setTemplate('MyCustomTextField');
-Both `MyCustomTemplate.ss` and `MyCustomTextField.ss` should be located in **mysite/templates/Includes/**
+Both `MyCustomTemplate.ss` and `MyCustomTextField.ss` should be located in **mysite/templates/forms/** or the same directory as the core.
It's recommended to copy the contents of the template you're going to replace and use that as a start. For instance, if
@@ -66,4 +66,4 @@ well as the available syntax, see the [Templates](../templates) documentation.
## API Documentation
* [api:Form]
-* [api:FormField]
\ No newline at end of file
+* [api:FormField]
diff --git a/forms/Form.php b/forms/Form.php
index 9d4385fba..eee8f1b86 100644
--- a/forms/Form.php
+++ b/forms/Form.php
@@ -1404,6 +1404,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();
@@ -1436,15 +1437,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() {