@@ -44,43 +44,84 @@ public function __construct($data, $suffix = null, $prefix = null, $directory =
44
44
if ($ directory === null ) {
45
45
$ directory = self ::getTempDir ();
46
46
}
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
+ }
49
53
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
+ }
54
61
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 ();
56
95
foreach ($ data as $ key => $ value ) {
57
- // Always convert to UTF-8
58
96
if ($ encoding !== 'UTF-8 ' && function_exists ('mb_convert_encoding ' )) {
59
- $ value = mb_convert_encoding ($ value , 'UTF-8 ' , $ encoding );
60
97
$ key = mb_convert_encoding ($ key , 'UTF-8 ' , $ encoding );
98
+ $ value = mb_convert_encoding ($ value , 'UTF-8 ' , $ encoding );
61
99
}
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 ;
72
104
} else {
73
- $ target = & $ fields ;
74
- foreach ($ keys as $ part ) {
105
+ $ target = &$ result ;
106
+ foreach ($ keyParts as $ part ) {
75
107
if (!isset ($ target [$ part ])) {
76
108
$ target [$ part ] = array ();
77
109
}
78
- $ target = & $ target [$ part ];
110
+ $ target = &$ target [$ part ];
79
111
}
80
- $ target [$ final ] = $ sanitizedValue ;
112
+ $ target [$ lastPart ] = $ value ;
81
113
}
82
114
}
115
+ return $ result ;
116
+ }
83
117
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
+ {
84
125
// Use fwrite, since file_put_contents() messes around with character encoding
85
126
$ fp = fopen ($ this ->_fileName , 'w ' );
86
127
fwrite ($ fp , self ::XFDF_HEADER );
@@ -94,19 +135,31 @@ public function __construct($data, $suffix = null, $prefix = null, $directory =
94
135
*
95
136
* @param int $fp
96
137
* @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.
99
139
*/
100
140
protected function writeFields ($ fp , $ fields )
101
141
{
102
142
foreach ($ fields as $ key => $ value ) {
143
+ $ key = $ this ->xmlEncode ($ key );
144
+ fwrite ($ fp , "<field name= \"$ key \"> \n" );
103
145
if (is_array ($ value )) {
104
- fwrite ($ fp , "<field name= \"$ key \"> \n" );
105
146
$ this ->writeFields ($ fp , $ value );
106
- fwrite ($ fp , "</field> \n" );
107
147
} 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" );
109
150
}
151
+ fwrite ($ fp , "</field> \n" );
110
152
}
111
153
}
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
+ }
112
165
}
0 commit comments