Skip to content

Commit a4f155e

Browse files
authored
Merge pull request #228 from mikehaertl/refactor-xfdffile
Refactor XfdfFile
2 parents 2fec45c + 1566eb2 commit a4f155e

File tree

1 file changed

+81
-28
lines changed

1 file changed

+81
-28
lines changed

src/XfdfFile.php

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,43 +44,84 @@ public function __construct($data, $suffix = null, $prefix = null, $directory =
4444
if ($directory === null) {
4545
$directory = self::getTempDir();
4646
}
47-
$suffix = '.xfdf';
48-
$prefix = 'php_pdftk_xfdf_';
47+
if ($suffix === null) {
48+
$suffix = '.xfdf';
49+
}
50+
if ($prefix === null) {
51+
$prefix = 'php_pdftk_xfdf_';
52+
}
4953

50-
$this->_fileName = tempnam($directory, $prefix);
51-
$newName = $this->_fileName . $suffix;
52-
rename($this->_fileName, $newName);
53-
$this->_fileName = $newName;
54+
$tempfile = tempnam($directory, $prefix);
55+
$this->_fileName = $tempfile . $suffix;
56+
rename($tempfile, $this->_fileName);
57+
58+
$fields = $this->parseData($data, $encoding);
59+
$this->writeXml($fields);
60+
}
5461

55-
$fields = array();
62+
/**
63+
* Parses an array of key/value data that may contain keys in dot notation.
64+
*
65+
* For example an array like this:
66+
*
67+
* ```
68+
* [
69+
* 'a' => 'value a',
70+
* 'b.a' => 'value b.a',
71+
* 'b.b' => 'value b.b',
72+
* ]
73+
* ```
74+
*
75+
* Will become:
76+
*
77+
* ```
78+
* [
79+
* 'a' => 'value a',
80+
* 'b' => [
81+
* 'a' => 'value b.a',
82+
* 'b' => 'value b.a',
83+
* ],
84+
* ]
85+
*
86+
*
87+
* @param mixed $data the data to parse
88+
* @param string the encoding of the data
89+
* @return array the result array in UTF-8 encoding with dot keys converted
90+
* to nested arrays
91+
*/
92+
protected function parseData($data, $encoding)
93+
{
94+
$result = array();
5695
foreach ($data as $key => $value) {
57-
// Always convert to UTF-8
5896
if ($encoding !== 'UTF-8' && function_exists('mb_convert_encoding')) {
59-
$value = mb_convert_encoding($value, 'UTF-8', $encoding);
6097
$key = mb_convert_encoding($key, 'UTF-8', $encoding);
98+
$value = mb_convert_encoding($value, 'UTF-8', $encoding);
6199
}
62-
63-
//Sanitize input for use in XML
64-
$sanitizedKey = defined('ENT_XML1') ? htmlspecialchars($key, ENT_XML1, 'UTF-8') : htmlspecialchars($key);
65-
$sanitizedValue = defined('ENT_XML1') ? htmlspecialchars($value, ENT_XML1, 'UTF-8') : htmlspecialchars($value);
66-
67-
// Key can be in dot notation like 'Address.name'
68-
$keys = explode('.', $sanitizedKey);
69-
$final = array_pop($keys);
70-
if (count($keys) === 0) {
71-
$fields[$final] = $sanitizedValue;
100+
$keyParts = explode('.', $key);
101+
$lastPart = array_pop($keyParts);
102+
if (count($keyParts) === 0) {
103+
$result[$lastPart] = $value;
72104
} else {
73-
$target = & $fields;
74-
foreach ($keys as $part) {
105+
$target = &$result;
106+
foreach ($keyParts as $part) {
75107
if (!isset($target[$part])) {
76108
$target[$part] = array();
77109
}
78-
$target = & $target[$part];
110+
$target = &$target[$part];
79111
}
80-
$target[$final] = $sanitizedValue;
112+
$target[$lastPart] = $value;
81113
}
82114
}
115+
return $result;
116+
}
83117

118+
/**
119+
* Write the given fields to an XML file
120+
*
121+
* @param array $fields the fields in a nested array structure
122+
*/
123+
protected function writeXml($fields)
124+
{
84125
// Use fwrite, since file_put_contents() messes around with character encoding
85126
$fp = fopen($this->_fileName, 'w');
86127
fwrite($fp, self::XFDF_HEADER);
@@ -94,19 +135,31 @@ public function __construct($data, $suffix = null, $prefix = null, $directory =
94135
*
95136
* @param int $fp
96137
* @param mixed[] $fields an array of field values. A value can also be
97-
* another array
98-
* in which case a nested field is written.
138+
* another array in which case a nested field is written.
99139
*/
100140
protected function writeFields($fp, $fields)
101141
{
102142
foreach ($fields as $key => $value) {
143+
$key = $this->xmlEncode($key);
144+
fwrite($fp, "<field name=\"$key\">\n");
103145
if (is_array($value)) {
104-
fwrite($fp, "<field name=\"$key\">\n");
105146
$this->writeFields($fp, $value);
106-
fwrite($fp, "</field>\n");
107147
} else {
108-
fwrite($fp, "<field name=\"$key\">\n<value>$value</value>\n</field>\n");
148+
$value = $this->xmlEncode($value);
149+
fwrite($fp, "<value>$value</value>\n");
109150
}
151+
fwrite($fp, "</field>\n");
110152
}
111153
}
154+
155+
/**
156+
* @param string $value the value to encode
157+
* @return string the value correctly encoded for use in a XML document
158+
*/
159+
protected function xmlEncode($value)
160+
{
161+
return defined('ENT_XML1') ?
162+
htmlspecialchars($value, ENT_XML1, 'UTF-8') :
163+
htmlspecialchars($value);
164+
}
112165
}

0 commit comments

Comments
 (0)