Skip to content

Commit f370164

Browse files
committed
Issue #260 Fix nested fields with numeric field names
1 parent 97b80fb commit f370164

File tree

3 files changed

+41
-18
lines changed

3 files changed

+41
-18
lines changed

src/XfdfFile.php

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,45 @@ public function __construct($data, $suffix = null, $prefix = null, $directory =
9999
}
100100

101101
/**
102-
* Parses an array of key/value data that may contain keys in dot notation.
102+
* Parses an array of key/value data into a nested array structure.
103+
*
104+
* The data may use keys in dot notation (#55). Values can also be arrays in
105+
* case of multi value fields (#148). To make both distinguishable in the
106+
* result array keys that represent field names are prefixed with `_`. This
107+
* also allows for numeric field names (#260).
103108
*
104109
* For example an array like this:
105110
*
106111
* ```
107112
* [
108113
* 'a' => 'value a',
109-
* 'b.a' => 'value b.a',
110-
* 'b.b' => 'value b.b',
114+
* 'b.x' => 'value b.x',
115+
* 'b.y' => 'value b.y',
116+
*
117+
* 'c.0' => 'val c.0',
118+
* 'c.1' => 'val c.1',
119+
*
120+
* 'd' => ['m1', 'm2'],
111121
* ]
112122
* ```
113123
*
114124
* Will become:
115125
*
116126
* ```
117127
* [
118-
* 'a' => 'value a',
119-
* 'b' => [
120-
* 'a' => 'value b.a',
121-
* 'b' => 'value b.a',
128+
* '_a' => 'value a',
129+
* '_b' => [
130+
* '_x' => 'value b.x',
131+
* '_y' => 'value b.y',
132+
* ],
133+
* '_c' => [
134+
* '_0' => 'value c.0',
135+
* '_1' => 'value c.1',
136+
* ],
137+
* '_d' => [
138+
* // notice the missing underscore in the keys
139+
* 0 => 'm1',
140+
* 1 => 'm2',
122141
* ],
123142
* ]
124143
*
@@ -136,19 +155,19 @@ protected function parseData($data, $encoding)
136155
$key = mb_convert_encoding($key, 'UTF-8', $encoding);
137156
$value = mb_convert_encoding($value, 'UTF-8', $encoding);
138157
}
139-
$keyParts = explode('.', $key);
140-
$lastPart = array_pop($keyParts);
141-
if (count($keyParts) === 0) {
142-
$result[$lastPart] = $value;
158+
if (strpos($key, '.') === false) {
159+
$result['_' . $key] = $value;
143160
} else {
144161
$target = &$result;
162+
$keyParts = explode('.', $key);
163+
$lastPart = array_pop($keyParts);
145164
foreach ($keyParts as $part) {
146-
if (!isset($target[$part])) {
147-
$target[$part] = array();
165+
if (!isset($target['_' . $part])) {
166+
$target['_' . $part] = array();
148167
}
149-
$target = &$target[$part];
168+
$target = &$target['_' . $part];
150169
}
151-
$target[$lastPart] = $value;
170+
$target['_' . $lastPart] = $value;
152171
}
153172
}
154173
return $result;
@@ -173,13 +192,13 @@ protected function writeXml($fields)
173192
* Write the fields to the given filepointer
174193
*
175194
* @param int $fp
176-
* @param mixed[] $fields an array of field values. A value can also be
177-
* another array in which case a nested field is written.
195+
* @param mixed[] $fields an array of field values as returned by
196+
* `parseData()`.
178197
*/
179198
protected function writeFields($fp, $fields)
180199
{
181200
foreach ($fields as $key => $value) {
182-
$key = $this->xmlEncode($key);
201+
$key = $this->xmlEncode(substr($key,1));
183202
fwrite($fp, "<field name=\"$key\">\n");
184203
if (!is_array($value)) {
185204
$value = array($value);

tests/XfdfFileTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public function testXfdfFileCreation()
1717
'radio 1' => 2,
1818
'address.street' => 'some street',
1919
"umlauts-in-value" => 'öäüÖÄÜ',
20+
'some.other.0' => 'val0',
2021
'some.other.value' => 'val1',
2122
'some.other.value2' => 'val2',
2223
'öäüÖÄÜ' => "umlauts in key",

tests/files/XfdfFileTest.xfdf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
</field>
3030
<field name="some">
3131
<field name="other">
32+
<field name="0">
33+
<value>val0</value>
34+
</field>
3235
<field name="value">
3336
<value>val1</value>
3437
</field>

0 commit comments

Comments
 (0)