Completed
Push — php51 ( 195310...f25510 )
by Gaetano
10:37 queued 36s
created
lib/xmlrpc.inc 2 patches
Indentation   +3828 added lines, -3828 removed lines patch added patch discarded remove patch
@@ -34,98 +34,98 @@  discard block
 block discarded – undo
34 34
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35 35
 // OF THE POSSIBILITY OF SUCH DAMAGE.
36 36
 
37
-	if(!function_exists('xml_parser_create'))
38
-	{
39
-		// For PHP 4 onward, XML functionality is always compiled-in on windows:
40
-		// no more need to dl-open it. It might have been compiled out on *nix...
41
-		if(strtoupper(substr(PHP_OS, 0, 3) != 'WIN'))
42
-		{
43
-			dl('xml.so');
44
-		}
45
-	}
46
-
47
-	// G. Giunta 2005/01/29: declare global these variables,
48
-	// so that xmlrpc.inc will work even if included from within a function
49
-	// Milosch: 2005/08/07 - explicitly request these via $GLOBALS where used.
50
-	$GLOBALS['xmlrpcI4']='i4';
51
-	$GLOBALS['xmlrpcInt']='int';
52
-	$GLOBALS['xmlrpcBoolean']='boolean';
53
-	$GLOBALS['xmlrpcDouble']='double';
54
-	$GLOBALS['xmlrpcString']='string';
55
-	$GLOBALS['xmlrpcDateTime']='dateTime.iso8601';
56
-	$GLOBALS['xmlrpcBase64']='base64';
57
-	$GLOBALS['xmlrpcArray']='array';
58
-	$GLOBALS['xmlrpcStruct']='struct';
59
-	$GLOBALS['xmlrpcValue']='undefined';
60
-
61
-	$GLOBALS['xmlrpcTypes']=array(
62
-		$GLOBALS['xmlrpcI4']       => 1,
63
-		$GLOBALS['xmlrpcInt']      => 1,
64
-		$GLOBALS['xmlrpcBoolean']  => 1,
65
-		$GLOBALS['xmlrpcString']   => 1,
66
-		$GLOBALS['xmlrpcDouble']   => 1,
67
-		$GLOBALS['xmlrpcDateTime'] => 1,
68
-		$GLOBALS['xmlrpcBase64']   => 1,
69
-		$GLOBALS['xmlrpcArray']    => 2,
70
-		$GLOBALS['xmlrpcStruct']   => 3
71
-	);
72
-
73
-	$GLOBALS['xmlrpc_valid_parents'] = array(
74
-		'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
75
-		'BOOLEAN' => array('VALUE'),
76
-		'I4' => array('VALUE'),
77
-		'INT' => array('VALUE'),
78
-		'STRING' => array('VALUE'),
79
-		'DOUBLE' => array('VALUE'),
80
-		'DATETIME.ISO8601' => array('VALUE'),
81
-		'BASE64' => array('VALUE'),
82
-		'MEMBER' => array('STRUCT'),
83
-		'NAME' => array('MEMBER'),
84
-		'DATA' => array('ARRAY'),
85
-		'ARRAY' => array('VALUE'),
86
-		'STRUCT' => array('VALUE'),
87
-		'PARAM' => array('PARAMS'),
88
-		'METHODNAME' => array('METHODCALL'),
89
-		'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
90
-		'FAULT' => array('METHODRESPONSE'),
91
-		'NIL' => array('VALUE'), // only used when extension activated
92
-		'EX:NIL' => array('VALUE') // only used when extension activated
93
-	);
94
-
95
-	// define extra types for supporting NULL (useful for json or <NIL/>)
96
-	$GLOBALS['xmlrpcNull']='null';
97
-	$GLOBALS['xmlrpcTypes']['null']=1;
98
-
99
-	// Not in use anymore since 2.0. Shall we remove it?
100
-	/// @deprecated
101
-	$GLOBALS['xmlEntities']=array(
102
-		'amp'  => '&',
103
-		'quot' => '"',
104
-		'lt'   => '<',
105
-		'gt'   => '>',
106
-		'apos' => "'"
107
-	);
108
-
109
-	// tables used for transcoding different charsets into us-ascii xml
110
-
111
-	$GLOBALS['xml_iso88591_Entities']=array();
112
-	$GLOBALS['xml_iso88591_Entities']['in'] = array();
113
-	$GLOBALS['xml_iso88591_Entities']['out'] = array();
114
-	for ($i = 0; $i < 32; $i++)
115
-	{
116
-		$GLOBALS['xml_iso88591_Entities']['in'][] = chr($i);
117
-		$GLOBALS['xml_iso88591_Entities']['out'][] = '&#'.$i.';';
118
-	}
119
-	for ($i = 160; $i < 256; $i++)
120
-	{
121
-		$GLOBALS['xml_iso88591_Entities']['in'][] = chr($i);
122
-		$GLOBALS['xml_iso88591_Entities']['out'][] = '&#'.$i.';';
123
-	}
124
-
125
-	/// @todo add to iso table the characters from cp_1252 range, i.e. 128 to 159?
126
-	/// These will NOT be present in true ISO-8859-1, but will save the unwary
127
-	/// windows user from sending junk (though no luck when reciving them...)
128
-  /*
37
+    if(!function_exists('xml_parser_create'))
38
+    {
39
+        // For PHP 4 onward, XML functionality is always compiled-in on windows:
40
+        // no more need to dl-open it. It might have been compiled out on *nix...
41
+        if(strtoupper(substr(PHP_OS, 0, 3) != 'WIN'))
42
+        {
43
+            dl('xml.so');
44
+        }
45
+    }
46
+
47
+    // G. Giunta 2005/01/29: declare global these variables,
48
+    // so that xmlrpc.inc will work even if included from within a function
49
+    // Milosch: 2005/08/07 - explicitly request these via $GLOBALS where used.
50
+    $GLOBALS['xmlrpcI4']='i4';
51
+    $GLOBALS['xmlrpcInt']='int';
52
+    $GLOBALS['xmlrpcBoolean']='boolean';
53
+    $GLOBALS['xmlrpcDouble']='double';
54
+    $GLOBALS['xmlrpcString']='string';
55
+    $GLOBALS['xmlrpcDateTime']='dateTime.iso8601';
56
+    $GLOBALS['xmlrpcBase64']='base64';
57
+    $GLOBALS['xmlrpcArray']='array';
58
+    $GLOBALS['xmlrpcStruct']='struct';
59
+    $GLOBALS['xmlrpcValue']='undefined';
60
+
61
+    $GLOBALS['xmlrpcTypes']=array(
62
+        $GLOBALS['xmlrpcI4']       => 1,
63
+        $GLOBALS['xmlrpcInt']      => 1,
64
+        $GLOBALS['xmlrpcBoolean']  => 1,
65
+        $GLOBALS['xmlrpcString']   => 1,
66
+        $GLOBALS['xmlrpcDouble']   => 1,
67
+        $GLOBALS['xmlrpcDateTime'] => 1,
68
+        $GLOBALS['xmlrpcBase64']   => 1,
69
+        $GLOBALS['xmlrpcArray']    => 2,
70
+        $GLOBALS['xmlrpcStruct']   => 3
71
+    );
72
+
73
+    $GLOBALS['xmlrpc_valid_parents'] = array(
74
+        'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
75
+        'BOOLEAN' => array('VALUE'),
76
+        'I4' => array('VALUE'),
77
+        'INT' => array('VALUE'),
78
+        'STRING' => array('VALUE'),
79
+        'DOUBLE' => array('VALUE'),
80
+        'DATETIME.ISO8601' => array('VALUE'),
81
+        'BASE64' => array('VALUE'),
82
+        'MEMBER' => array('STRUCT'),
83
+        'NAME' => array('MEMBER'),
84
+        'DATA' => array('ARRAY'),
85
+        'ARRAY' => array('VALUE'),
86
+        'STRUCT' => array('VALUE'),
87
+        'PARAM' => array('PARAMS'),
88
+        'METHODNAME' => array('METHODCALL'),
89
+        'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
90
+        'FAULT' => array('METHODRESPONSE'),
91
+        'NIL' => array('VALUE'), // only used when extension activated
92
+        'EX:NIL' => array('VALUE') // only used when extension activated
93
+    );
94
+
95
+    // define extra types for supporting NULL (useful for json or <NIL/>)
96
+    $GLOBALS['xmlrpcNull']='null';
97
+    $GLOBALS['xmlrpcTypes']['null']=1;
98
+
99
+    // Not in use anymore since 2.0. Shall we remove it?
100
+    /// @deprecated
101
+    $GLOBALS['xmlEntities']=array(
102
+        'amp'  => '&',
103
+        'quot' => '"',
104
+        'lt'   => '<',
105
+        'gt'   => '>',
106
+        'apos' => "'"
107
+    );
108
+
109
+    // tables used for transcoding different charsets into us-ascii xml
110
+
111
+    $GLOBALS['xml_iso88591_Entities']=array();
112
+    $GLOBALS['xml_iso88591_Entities']['in'] = array();
113
+    $GLOBALS['xml_iso88591_Entities']['out'] = array();
114
+    for ($i = 0; $i < 32; $i++)
115
+    {
116
+        $GLOBALS['xml_iso88591_Entities']['in'][] = chr($i);
117
+        $GLOBALS['xml_iso88591_Entities']['out'][] = '&#'.$i.';';
118
+    }
119
+    for ($i = 160; $i < 256; $i++)
120
+    {
121
+        $GLOBALS['xml_iso88591_Entities']['in'][] = chr($i);
122
+        $GLOBALS['xml_iso88591_Entities']['out'][] = '&#'.$i.';';
123
+    }
124
+
125
+    /// @todo add to iso table the characters from cp_1252 range, i.e. 128 to 159?
126
+    /// These will NOT be present in true ISO-8859-1, but will save the unwary
127
+    /// windows user from sending junk (though no luck when reciving them...)
128
+    /*
129 129
 	$GLOBALS['xml_cp1252_Entities']=array();
130 130
 	for ($i = 128; $i < 160; $i++)
131 131
 	{
@@ -143,222 +143,222 @@  discard block
 block discarded – undo
143 143
 	);
144 144
   */
145 145
 
146
-	$GLOBALS['xmlrpcerr'] = array(
147
-	'unknown_method'=>1,
148
-	'invalid_return'=>2,
149
-	'incorrect_params'=>3,
150
-	'introspect_unknown'=>4,
151
-	'http_error'=>5,
152
-	'no_data'=>6,
153
-	'no_ssl'=>7,
154
-	'curl_fail'=>8,
155
-	'invalid_request'=>15,
156
-	'no_curl'=>16,
157
-	'server_error'=>17,
158
-	'multicall_error'=>18,
159
-	'multicall_notstruct'=>9,
160
-	'multicall_nomethod'=>10,
161
-	'multicall_notstring'=>11,
162
-	'multicall_recursion'=>12,
163
-	'multicall_noparams'=>13,
164
-	'multicall_notarray'=>14,
165
-
166
-	'cannot_decompress'=>103,
167
-	'decompress_fail'=>104,
168
-	'dechunk_fail'=>105,
169
-	'server_cannot_decompress'=>106,
170
-	'server_decompress_fail'=>107
171
-	);
172
-
173
-	$GLOBALS['xmlrpcstr'] = array(
174
-	'unknown_method'=>'Unknown method',
175
-	'invalid_return'=>'Invalid return payload: enable debugging to examine incoming payload',
176
-	'incorrect_params'=>'Incorrect parameters passed to method',
177
-	'introspect_unknown'=>"Can't introspect: method unknown",
178
-	'http_error'=>"Didn't receive 200 OK from remote server.",
179
-	'no_data'=>'No data received from server.',
180
-	'no_ssl'=>'No SSL support compiled in.',
181
-	'curl_fail'=>'CURL error',
182
-	'invalid_request'=>'Invalid request payload',
183
-	'no_curl'=>'No CURL support compiled in.',
184
-	'server_error'=>'Internal server error',
185
-	'multicall_error'=>'Received from server invalid multicall response',
186
-	'multicall_notstruct'=>'system.multicall expected struct',
187
-	'multicall_nomethod'=>'missing methodName',
188
-	'multicall_notstring'=>'methodName is not a string',
189
-	'multicall_recursion'=>'recursive system.multicall forbidden',
190
-	'multicall_noparams'=>'missing params',
191
-	'multicall_notarray'=>'params is not an array',
192
-
193
-	'cannot_decompress'=>'Received from server compressed HTTP and cannot decompress',
194
-	'decompress_fail'=>'Received from server invalid compressed HTTP',
195
-	'dechunk_fail'=>'Received from server invalid chunked HTTP',
196
-	'server_cannot_decompress'=>'Received from client compressed HTTP request and cannot decompress',
197
-	'server_decompress_fail'=>'Received from client invalid compressed HTTP request'
198
-	);
199
-
200
-	// The charset encoding used by the server for received messages and
201
-	// by the client for received responses when received charset cannot be determined
202
-	// or is not supported
203
-	$GLOBALS['xmlrpc_defencoding']='UTF-8';
204
-
205
-	// The encoding used internally by PHP.
206
-	// String values received as xml will be converted to this, and php strings will be converted to xml
207
-	// as if having been coded with this
208
-	$GLOBALS['xmlrpc_internalencoding']='ISO-8859-1';
209
-
210
-	$GLOBALS['xmlrpcName']='XML-RPC for PHP';
211
-	$GLOBALS['xmlrpcVersion']='3.1.1';
212
-
213
-	// let user errors start at 800
214
-	$GLOBALS['xmlrpcerruser']=800;
215
-	// let XML parse errors start at 100
216
-	$GLOBALS['xmlrpcerrxml']=100;
217
-
218
-	// formulate backslashes for escaping regexp
219
-	// Not in use anymore since 2.0. Shall we remove it?
220
-	/// @deprecated
221
-	$GLOBALS['xmlrpc_backslash']=chr(92).chr(92);
222
-
223
-	// set to TRUE to enable correct decoding of <NIL/> and <EX:NIL/> values
224
-	$GLOBALS['xmlrpc_null_extension']=false;
225
-
226
-	// set to TRUE to enable encoding of php NULL values to <EX:NIL/> instead of <NIL/>
227
-	$GLOBALS['xmlrpc_null_apache_encoding']=false;
228
-	$GLOBALS['xmlrpc_null_apache_encoding_ns']='http://ws.apache.org/xmlrpc/namespaces/extensions';
229
-
230
-	// used to store state during parsing
231
-	// quick explanation of components:
232
-	//   ac - used to accumulate values
233
-	//   isf - used to indicate a parsing fault (2) or xmlrpcresp fault (1)
234
-	//   isf_reason - used for storing xmlrpcresp fault string
235
-	//   lv - used to indicate "looking for a value": implements
236
-	//        the logic to allow values with no types to be strings
237
-	//   params - used to store parameters in method calls
238
-	//   method - used to store method name
239
-	//   stack - array with genealogy of xml elements names:
240
-	//           used to validate nesting of xmlrpc elements
241
-	$GLOBALS['_xh']=null;
242
-
243
-	/**
244
-	* Convert a string to the correct XML representation in a target charset
245
-	* To help correct communication of non-ascii chars inside strings, regardless
246
-	* of the charset used when sending requests, parsing them, sending responses
247
-	* and parsing responses, an option is to convert all non-ascii chars present in the message
248
-	* into their equivalent 'charset entity'. Charset entities enumerated this way
249
-	* are independent of the charset encoding used to transmit them, and all XML
250
-	* parsers are bound to understand them.
251
-	* Note that in the std case we are not sending a charset encoding mime type
252
-	* along with http headers, so we are bound by RFC 3023 to emit strict us-ascii.
253
-	*
254
-	* @todo do a bit of basic benchmarking (strtr vs. str_replace)
255
-	* @todo	make usage of iconv() or recode_string() or mb_string() where available
256
-	*/
257
-	function xmlrpc_encode_entitites($data, $src_encoding='', $dest_encoding='')
258
-	{
259
-		if ($src_encoding == '')
260
-		{
261
-			// lame, but we know no better...
262
-			$src_encoding = $GLOBALS['xmlrpc_internalencoding'];
263
-		}
264
-
265
-		switch(strtoupper($src_encoding.'_'.$dest_encoding))
266
-		{
267
-			case 'ISO-8859-1_':
268
-			case 'ISO-8859-1_US-ASCII':
269
-				$escaped_data = str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $data);
270
-				$escaped_data = str_replace($GLOBALS['xml_iso88591_Entities']['in'], $GLOBALS['xml_iso88591_Entities']['out'], $escaped_data);
271
-				break;
272
-			case 'ISO-8859-1_UTF-8':
273
-				$escaped_data = str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $data);
274
-				$escaped_data = utf8_encode($escaped_data);
275
-				break;
276
-			case 'ISO-8859-1_ISO-8859-1':
277
-			case 'US-ASCII_US-ASCII':
278
-			case 'US-ASCII_UTF-8':
279
-			case 'US-ASCII_':
280
-			case 'US-ASCII_ISO-8859-1':
281
-			case 'UTF-8_UTF-8':
282
-			//case 'CP1252_CP1252':
283
-				$escaped_data = str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $data);
284
-				break;
285
-			case 'UTF-8_':
286
-			case 'UTF-8_US-ASCII':
287
-			case 'UTF-8_ISO-8859-1':
288
-	// NB: this will choke on invalid UTF-8, going most likely beyond EOF
289
-	$escaped_data = '';
290
-	// be kind to users creating string xmlrpcvals out of different php types
291
-	$data = (string) $data;
292
-	$ns = strlen ($data);
293
-	for ($nn = 0; $nn < $ns; $nn++)
294
-	{
295
-		$ch = $data[$nn];
296
-		$ii = ord($ch);
297
-		//1 7 0bbbbbbb (127)
298
-		if ($ii < 128)
299
-		{
300
-			/// @todo shall we replace this with a (supposedly) faster str_replace?
301
-			switch($ii){
302
-				case 34:
303
-					$escaped_data .= '&quot;';
304
-					break;
305
-				case 38:
306
-					$escaped_data .= '&amp;';
307
-					break;
308
-				case 39:
309
-					$escaped_data .= '&apos;';
310
-					break;
311
-				case 60:
312
-					$escaped_data .= '&lt;';
313
-					break;
314
-				case 62:
315
-					$escaped_data .= '&gt;';
316
-					break;
317
-				default:
318
-					$escaped_data .= $ch;
319
-			} // switch
320
-		}
321
-		//2 11 110bbbbb 10bbbbbb (2047)
322
-		else if ($ii>>5 == 6)
323
-		{
324
-			$b1 = ($ii & 31);
325
-			$ii = ord($data[$nn+1]);
326
-			$b2 = ($ii & 63);
327
-			$ii = ($b1 * 64) + $b2;
328
-			$ent = sprintf ('&#%d;', $ii);
329
-			$escaped_data .= $ent;
330
-			$nn += 1;
331
-		}
332
-		//3 16 1110bbbb 10bbbbbb 10bbbbbb
333
-		else if ($ii>>4 == 14)
334
-		{
335
-			$b1 = ($ii & 15);
336
-			$ii = ord($data[$nn+1]);
337
-			$b2 = ($ii & 63);
338
-			$ii = ord($data[$nn+2]);
339
-			$b3 = ($ii & 63);
340
-			$ii = ((($b1 * 64) + $b2) * 64) + $b3;
341
-			$ent = sprintf ('&#%d;', $ii);
342
-			$escaped_data .= $ent;
343
-			$nn += 2;
344
-		}
345
-		//4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
346
-		else if ($ii>>3 == 30)
347
-		{
348
-			$b1 = ($ii & 7);
349
-			$ii = ord($data[$nn+1]);
350
-			$b2 = ($ii & 63);
351
-			$ii = ord($data[$nn+2]);
352
-			$b3 = ($ii & 63);
353
-			$ii = ord($data[$nn+3]);
354
-			$b4 = ($ii & 63);
355
-			$ii = ((((($b1 * 64) + $b2) * 64) + $b3) * 64) + $b4;
356
-			$ent = sprintf ('&#%d;', $ii);
357
-			$escaped_data .= $ent;
358
-			$nn += 3;
359
-		}
360
-	}
361
-				break;
146
+    $GLOBALS['xmlrpcerr'] = array(
147
+    'unknown_method'=>1,
148
+    'invalid_return'=>2,
149
+    'incorrect_params'=>3,
150
+    'introspect_unknown'=>4,
151
+    'http_error'=>5,
152
+    'no_data'=>6,
153
+    'no_ssl'=>7,
154
+    'curl_fail'=>8,
155
+    'invalid_request'=>15,
156
+    'no_curl'=>16,
157
+    'server_error'=>17,
158
+    'multicall_error'=>18,
159
+    'multicall_notstruct'=>9,
160
+    'multicall_nomethod'=>10,
161
+    'multicall_notstring'=>11,
162
+    'multicall_recursion'=>12,
163
+    'multicall_noparams'=>13,
164
+    'multicall_notarray'=>14,
165
+
166
+    'cannot_decompress'=>103,
167
+    'decompress_fail'=>104,
168
+    'dechunk_fail'=>105,
169
+    'server_cannot_decompress'=>106,
170
+    'server_decompress_fail'=>107
171
+    );
172
+
173
+    $GLOBALS['xmlrpcstr'] = array(
174
+    'unknown_method'=>'Unknown method',
175
+    'invalid_return'=>'Invalid return payload: enable debugging to examine incoming payload',
176
+    'incorrect_params'=>'Incorrect parameters passed to method',
177
+    'introspect_unknown'=>"Can't introspect: method unknown",
178
+    'http_error'=>"Didn't receive 200 OK from remote server.",
179
+    'no_data'=>'No data received from server.',
180
+    'no_ssl'=>'No SSL support compiled in.',
181
+    'curl_fail'=>'CURL error',
182
+    'invalid_request'=>'Invalid request payload',
183
+    'no_curl'=>'No CURL support compiled in.',
184
+    'server_error'=>'Internal server error',
185
+    'multicall_error'=>'Received from server invalid multicall response',
186
+    'multicall_notstruct'=>'system.multicall expected struct',
187
+    'multicall_nomethod'=>'missing methodName',
188
+    'multicall_notstring'=>'methodName is not a string',
189
+    'multicall_recursion'=>'recursive system.multicall forbidden',
190
+    'multicall_noparams'=>'missing params',
191
+    'multicall_notarray'=>'params is not an array',
192
+
193
+    'cannot_decompress'=>'Received from server compressed HTTP and cannot decompress',
194
+    'decompress_fail'=>'Received from server invalid compressed HTTP',
195
+    'dechunk_fail'=>'Received from server invalid chunked HTTP',
196
+    'server_cannot_decompress'=>'Received from client compressed HTTP request and cannot decompress',
197
+    'server_decompress_fail'=>'Received from client invalid compressed HTTP request'
198
+    );
199
+
200
+    // The charset encoding used by the server for received messages and
201
+    // by the client for received responses when received charset cannot be determined
202
+    // or is not supported
203
+    $GLOBALS['xmlrpc_defencoding']='UTF-8';
204
+
205
+    // The encoding used internally by PHP.
206
+    // String values received as xml will be converted to this, and php strings will be converted to xml
207
+    // as if having been coded with this
208
+    $GLOBALS['xmlrpc_internalencoding']='ISO-8859-1';
209
+
210
+    $GLOBALS['xmlrpcName']='XML-RPC for PHP';
211
+    $GLOBALS['xmlrpcVersion']='3.1.1';
212
+
213
+    // let user errors start at 800
214
+    $GLOBALS['xmlrpcerruser']=800;
215
+    // let XML parse errors start at 100
216
+    $GLOBALS['xmlrpcerrxml']=100;
217
+
218
+    // formulate backslashes for escaping regexp
219
+    // Not in use anymore since 2.0. Shall we remove it?
220
+    /// @deprecated
221
+    $GLOBALS['xmlrpc_backslash']=chr(92).chr(92);
222
+
223
+    // set to TRUE to enable correct decoding of <NIL/> and <EX:NIL/> values
224
+    $GLOBALS['xmlrpc_null_extension']=false;
225
+
226
+    // set to TRUE to enable encoding of php NULL values to <EX:NIL/> instead of <NIL/>
227
+    $GLOBALS['xmlrpc_null_apache_encoding']=false;
228
+    $GLOBALS['xmlrpc_null_apache_encoding_ns']='http://ws.apache.org/xmlrpc/namespaces/extensions';
229
+
230
+    // used to store state during parsing
231
+    // quick explanation of components:
232
+    //   ac - used to accumulate values
233
+    //   isf - used to indicate a parsing fault (2) or xmlrpcresp fault (1)
234
+    //   isf_reason - used for storing xmlrpcresp fault string
235
+    //   lv - used to indicate "looking for a value": implements
236
+    //        the logic to allow values with no types to be strings
237
+    //   params - used to store parameters in method calls
238
+    //   method - used to store method name
239
+    //   stack - array with genealogy of xml elements names:
240
+    //           used to validate nesting of xmlrpc elements
241
+    $GLOBALS['_xh']=null;
242
+
243
+    /**
244
+     * Convert a string to the correct XML representation in a target charset
245
+     * To help correct communication of non-ascii chars inside strings, regardless
246
+     * of the charset used when sending requests, parsing them, sending responses
247
+     * and parsing responses, an option is to convert all non-ascii chars present in the message
248
+     * into their equivalent 'charset entity'. Charset entities enumerated this way
249
+     * are independent of the charset encoding used to transmit them, and all XML
250
+     * parsers are bound to understand them.
251
+     * Note that in the std case we are not sending a charset encoding mime type
252
+     * along with http headers, so we are bound by RFC 3023 to emit strict us-ascii.
253
+     *
254
+     * @todo do a bit of basic benchmarking (strtr vs. str_replace)
255
+     * @todo	make usage of iconv() or recode_string() or mb_string() where available
256
+     */
257
+    function xmlrpc_encode_entitites($data, $src_encoding='', $dest_encoding='')
258
+    {
259
+        if ($src_encoding == '')
260
+        {
261
+            // lame, but we know no better...
262
+            $src_encoding = $GLOBALS['xmlrpc_internalencoding'];
263
+        }
264
+
265
+        switch(strtoupper($src_encoding.'_'.$dest_encoding))
266
+        {
267
+            case 'ISO-8859-1_':
268
+            case 'ISO-8859-1_US-ASCII':
269
+                $escaped_data = str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $data);
270
+                $escaped_data = str_replace($GLOBALS['xml_iso88591_Entities']['in'], $GLOBALS['xml_iso88591_Entities']['out'], $escaped_data);
271
+                break;
272
+            case 'ISO-8859-1_UTF-8':
273
+                $escaped_data = str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $data);
274
+                $escaped_data = utf8_encode($escaped_data);
275
+                break;
276
+            case 'ISO-8859-1_ISO-8859-1':
277
+            case 'US-ASCII_US-ASCII':
278
+            case 'US-ASCII_UTF-8':
279
+            case 'US-ASCII_':
280
+            case 'US-ASCII_ISO-8859-1':
281
+            case 'UTF-8_UTF-8':
282
+            //case 'CP1252_CP1252':
283
+                $escaped_data = str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $data);
284
+                break;
285
+            case 'UTF-8_':
286
+            case 'UTF-8_US-ASCII':
287
+            case 'UTF-8_ISO-8859-1':
288
+    // NB: this will choke on invalid UTF-8, going most likely beyond EOF
289
+    $escaped_data = '';
290
+    // be kind to users creating string xmlrpcvals out of different php types
291
+    $data = (string) $data;
292
+    $ns = strlen ($data);
293
+    for ($nn = 0; $nn < $ns; $nn++)
294
+    {
295
+        $ch = $data[$nn];
296
+        $ii = ord($ch);
297
+        //1 7 0bbbbbbb (127)
298
+        if ($ii < 128)
299
+        {
300
+            /// @todo shall we replace this with a (supposedly) faster str_replace?
301
+            switch($ii){
302
+                case 34:
303
+                    $escaped_data .= '&quot;';
304
+                    break;
305
+                case 38:
306
+                    $escaped_data .= '&amp;';
307
+                    break;
308
+                case 39:
309
+                    $escaped_data .= '&apos;';
310
+                    break;
311
+                case 60:
312
+                    $escaped_data .= '&lt;';
313
+                    break;
314
+                case 62:
315
+                    $escaped_data .= '&gt;';
316
+                    break;
317
+                default:
318
+                    $escaped_data .= $ch;
319
+            } // switch
320
+        }
321
+        //2 11 110bbbbb 10bbbbbb (2047)
322
+        else if ($ii>>5 == 6)
323
+        {
324
+            $b1 = ($ii & 31);
325
+            $ii = ord($data[$nn+1]);
326
+            $b2 = ($ii & 63);
327
+            $ii = ($b1 * 64) + $b2;
328
+            $ent = sprintf ('&#%d;', $ii);
329
+            $escaped_data .= $ent;
330
+            $nn += 1;
331
+        }
332
+        //3 16 1110bbbb 10bbbbbb 10bbbbbb
333
+        else if ($ii>>4 == 14)
334
+        {
335
+            $b1 = ($ii & 15);
336
+            $ii = ord($data[$nn+1]);
337
+            $b2 = ($ii & 63);
338
+            $ii = ord($data[$nn+2]);
339
+            $b3 = ($ii & 63);
340
+            $ii = ((($b1 * 64) + $b2) * 64) + $b3;
341
+            $ent = sprintf ('&#%d;', $ii);
342
+            $escaped_data .= $ent;
343
+            $nn += 2;
344
+        }
345
+        //4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
346
+        else if ($ii>>3 == 30)
347
+        {
348
+            $b1 = ($ii & 7);
349
+            $ii = ord($data[$nn+1]);
350
+            $b2 = ($ii & 63);
351
+            $ii = ord($data[$nn+2]);
352
+            $b3 = ($ii & 63);
353
+            $ii = ord($data[$nn+3]);
354
+            $b4 = ($ii & 63);
355
+            $ii = ((((($b1 * 64) + $b2) * 64) + $b3) * 64) + $b4;
356
+            $ent = sprintf ('&#%d;', $ii);
357
+            $escaped_data .= $ent;
358
+            $nn += 3;
359
+        }
360
+    }
361
+                break;
362 362
 /*
363 363
 			case 'CP1252_':
364 364
 			case 'CP1252_US-ASCII':
@@ -378,2457 +378,2457 @@  discard block
 block discarded – undo
378 378
 				$escaped_data = str_replace($GLOBALS['xml_cp1252_Entities']['in'], $GLOBALS['xml_cp1252_Entities']['out'], $escaped_data);
379 379
 				break;
380 380
 */
381
-			default:
382
-				$escaped_data = '';
383
-				error_log("Converting from $src_encoding to $dest_encoding: not supported...");
384
-		}
385
-		return $escaped_data;
386
-	}
387
-
388
-	/// xml parser handler function for opening element tags
389
-	function xmlrpc_se($parser, $name, $attrs, $accept_single_vals=false)
390
-	{
391
-		// if invalid xmlrpc already detected, skip all processing
392
-		if ($GLOBALS['_xh']['isf'] < 2)
393
-		{
394
-			// check for correct element nesting
395
-			// top level element can only be of 2 types
396
-			/// @todo optimization creep: save this check into a bool variable, instead of using count() every time:
397
-			///       there is only a single top level element in xml anyway
398
-			if (count($GLOBALS['_xh']['stack']) == 0)
399
-			{
400
-				if ($name != 'METHODRESPONSE' && $name != 'METHODCALL' && (
401
-					$name != 'VALUE' && !$accept_single_vals))
402
-				{
403
-					$GLOBALS['_xh']['isf'] = 2;
404
-					$GLOBALS['_xh']['isf_reason'] = 'missing top level xmlrpc element';
405
-					return;
406
-				}
407
-				else
408
-				{
409
-					$GLOBALS['_xh']['rt'] = strtolower($name);
410
-					$GLOBALS['_xh']['rt'] = strtolower($name);
411
-				}
412
-			}
413
-			else
414
-			{
415
-				// not top level element: see if parent is OK
416
-				$parent = end($GLOBALS['_xh']['stack']);
417
-				if (!array_key_exists($name, $GLOBALS['xmlrpc_valid_parents']) || !in_array($parent, $GLOBALS['xmlrpc_valid_parents'][$name]))
418
-				{
419
-					$GLOBALS['_xh']['isf'] = 2;
420
-					$GLOBALS['_xh']['isf_reason'] = "xmlrpc element $name cannot be child of $parent";
421
-					return;
422
-				}
423
-			}
424
-
425
-			switch($name)
426
-			{
427
-				// optimize for speed switch cases: most common cases first
428
-				case 'VALUE':
429
-					/// @todo we could check for 2 VALUE elements inside a MEMBER or PARAM element
430
-					$GLOBALS['_xh']['vt']='value'; // indicator: no value found yet
431
-					$GLOBALS['_xh']['ac']='';
432
-					$GLOBALS['_xh']['lv']=1;
433
-					$GLOBALS['_xh']['php_class']=null;
434
-					break;
435
-				case 'I4':
436
-				case 'INT':
437
-				case 'STRING':
438
-				case 'BOOLEAN':
439
-				case 'DOUBLE':
440
-				case 'DATETIME.ISO8601':
441
-				case 'BASE64':
442
-					if ($GLOBALS['_xh']['vt']!='value')
443
-					{
444
-						//two data elements inside a value: an error occurred!
445
-						$GLOBALS['_xh']['isf'] = 2;
446
-						$GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
447
-						return;
448
-					}
449
-					$GLOBALS['_xh']['ac']=''; // reset the accumulator
450
-					break;
451
-				case 'STRUCT':
452
-				case 'ARRAY':
453
-					if ($GLOBALS['_xh']['vt']!='value')
454
-					{
455
-						//two data elements inside a value: an error occurred!
456
-						$GLOBALS['_xh']['isf'] = 2;
457
-						$GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
458
-						return;
459
-					}
460
-					// create an empty array to hold child values, and push it onto appropriate stack
461
-					$cur_val = array();
462
-					$cur_val['values'] = array();
463
-					$cur_val['type'] = $name;
464
-					// check for out-of-band information to rebuild php objs
465
-					// and in case it is found, save it
466
-					if (@isset($attrs['PHP_CLASS']))
467
-					{
468
-						$cur_val['php_class'] = $attrs['PHP_CLASS'];
469
-					}
470
-					$GLOBALS['_xh']['valuestack'][] = $cur_val;
471
-					$GLOBALS['_xh']['vt']='data'; // be prepared for a data element next
472
-					break;
473
-				case 'DATA':
474
-					if ($GLOBALS['_xh']['vt']!='data')
475
-					{
476
-						//two data elements inside a value: an error occurred!
477
-						$GLOBALS['_xh']['isf'] = 2;
478
-						$GLOBALS['_xh']['isf_reason'] = "found two data elements inside an array element";
479
-						return;
480
-					}
481
-				case 'METHODCALL':
482
-				case 'METHODRESPONSE':
483
-				case 'PARAMS':
484
-					// valid elements that add little to processing
485
-					break;
486
-				case 'METHODNAME':
487
-				case 'NAME':
488
-					/// @todo we could check for 2 NAME elements inside a MEMBER element
489
-					$GLOBALS['_xh']['ac']='';
490
-					break;
491
-				case 'FAULT':
492
-					$GLOBALS['_xh']['isf']=1;
493
-					break;
494
-				case 'MEMBER':
495
-					$GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name']=''; // set member name to null, in case we do not find in the xml later on
496
-					//$GLOBALS['_xh']['ac']='';
497
-					// Drop trough intentionally
498
-				case 'PARAM':
499
-					// clear value type, so we can check later if no value has been passed for this param/member
500
-					$GLOBALS['_xh']['vt']=null;
501
-					break;
502
-				case 'NIL':
503
-				case 'EX:NIL':
504
-					if ($GLOBALS['xmlrpc_null_extension'])
505
-					{
506
-						if ($GLOBALS['_xh']['vt']!='value')
507
-						{
508
-							//two data elements inside a value: an error occurred!
509
-							$GLOBALS['_xh']['isf'] = 2;
510
-							$GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
511
-							return;
512
-						}
513
-						$GLOBALS['_xh']['ac']=''; // reset the accumulator
514
-						break;
515
-					}
516
-					// we do not support the <NIL/> extension, so
517
-					// drop through intentionally
518
-				default:
519
-					/// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
520
-					$GLOBALS['_xh']['isf'] = 2;
521
-					$GLOBALS['_xh']['isf_reason'] = "found not-xmlrpc xml element $name";
522
-					break;
523
-			}
524
-
525
-			// Save current element name to stack, to validate nesting
526
-			$GLOBALS['_xh']['stack'][] = $name;
527
-
528
-			/// @todo optimization creep: move this inside the big switch() above
529
-			if($name!='VALUE')
530
-			{
531
-				$GLOBALS['_xh']['lv']=0;
532
-			}
533
-		}
534
-	}
535
-
536
-	/// Used in decoding xml chunks that might represent single xmlrpc values
537
-	function xmlrpc_se_any($parser, $name, $attrs)
538
-	{
539
-		xmlrpc_se($parser, $name, $attrs, true);
540
-	}
541
-
542
-	/// xml parser handler function for close element tags
543
-	function xmlrpc_ee($parser, $name, $rebuild_xmlrpcvals = true)
544
-	{
545
-		if ($GLOBALS['_xh']['isf'] < 2)
546
-		{
547
-			// push this element name from stack
548
-			// NB: if XML validates, correct opening/closing is guaranteed and
549
-			// we do not have to check for $name == $curr_elem.
550
-			// we also checked for proper nesting at start of elements...
551
-			$curr_elem = array_pop($GLOBALS['_xh']['stack']);
552
-
553
-			switch($name)
554
-			{
555
-				case 'VALUE':
556
-					// This if() detects if no scalar was inside <VALUE></VALUE>
557
-					if ($GLOBALS['_xh']['vt']=='value')
558
-					{
559
-						$GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
560
-						$GLOBALS['_xh']['vt']=$GLOBALS['xmlrpcString'];
561
-					}
562
-
563
-					if ($rebuild_xmlrpcvals)
564
-					{
565
-						// build the xmlrpc val out of the data received, and substitute it
566
-						$temp = new xmlrpcval($GLOBALS['_xh']['value'], $GLOBALS['_xh']['vt']);
567
-						// in case we got info about underlying php class, save it
568
-						// in the object we're rebuilding
569
-						if (isset($GLOBALS['_xh']['php_class']))
570
-							$temp->_php_class = $GLOBALS['_xh']['php_class'];
571
-						// check if we are inside an array or struct:
572
-						// if value just built is inside an array, let's move it into array on the stack
573
-						$vscount = count($GLOBALS['_xh']['valuestack']);
574
-						if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type']=='ARRAY')
575
-						{
576
-							$GLOBALS['_xh']['valuestack'][$vscount-1]['values'][] = $temp;
577
-						}
578
-						else
579
-						{
580
-							$GLOBALS['_xh']['value'] = $temp;
581
-						}
582
-					}
583
-					else
584
-					{
585
-						/// @todo this needs to treat correctly php-serialized objects,
586
-						/// since std deserializing is done by php_xmlrpc_decode,
587
-						/// which we will not be calling...
588
-						if (isset($GLOBALS['_xh']['php_class']))
589
-						{
590
-						}
591
-
592
-						// check if we are inside an array or struct:
593
-						// if value just built is inside an array, let's move it into array on the stack
594
-						$vscount = count($GLOBALS['_xh']['valuestack']);
595
-						if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type']=='ARRAY')
596
-						{
597
-							$GLOBALS['_xh']['valuestack'][$vscount-1]['values'][] = $GLOBALS['_xh']['value'];
598
-						}
599
-					}
600
-					break;
601
-				case 'BOOLEAN':
602
-				case 'I4':
603
-				case 'INT':
604
-				case 'STRING':
605
-				case 'DOUBLE':
606
-				case 'DATETIME.ISO8601':
607
-				case 'BASE64':
608
-					$GLOBALS['_xh']['vt']=strtolower($name);
609
-					/// @todo: optimization creep - remove the if/elseif cycle below
610
-					/// since the case() in which we are already did that
611
-					if ($name=='STRING')
612
-					{
613
-						$GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
614
-					}
615
-					elseif ($name=='DATETIME.ISO8601')
616
-					{
617
-						if (!preg_match('/^[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $GLOBALS['_xh']['ac']))
618
-						{
619
-							error_log('XML-RPC: invalid value received in DATETIME: '.$GLOBALS['_xh']['ac']);
620
-						}
621
-						$GLOBALS['_xh']['vt']=$GLOBALS['xmlrpcDateTime'];
622
-						$GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
623
-					}
624
-					elseif ($name=='BASE64')
625
-					{
626
-						/// @todo check for failure of base64 decoding / catch warnings
627
-						$GLOBALS['_xh']['value']=base64_decode($GLOBALS['_xh']['ac']);
628
-					}
629
-					elseif ($name=='BOOLEAN')
630
-					{
631
-						// special case here: we translate boolean 1 or 0 into PHP
632
-						// constants true or false.
633
-						// Strings 'true' and 'false' are accepted, even though the
634
-						// spec never mentions them (see eg. Blogger api docs)
635
-						// NB: this simple checks helps a lot sanitizing input, ie no
636
-						// security problems around here
637
-						if ($GLOBALS['_xh']['ac']=='1' || strcasecmp($GLOBALS['_xh']['ac'], 'true') == 0)
638
-						{
639
-							$GLOBALS['_xh']['value']=true;
640
-						}
641
-						else
642
-						{
643
-							// log if receiveing something strange, even though we set the value to false anyway
644
-							if ($GLOBALS['_xh']['ac']!='0' && strcasecmp($GLOBALS['_xh']['ac'], 'false') != 0)
645
-								error_log('XML-RPC: invalid value received in BOOLEAN: '.$GLOBALS['_xh']['ac']);
646
-							$GLOBALS['_xh']['value']=false;
647
-						}
648
-					}
649
-					elseif ($name=='DOUBLE')
650
-					{
651
-						// we have a DOUBLE
652
-						// we must check that only 0123456789-.<space> are characters here
653
-						// NOTE: regexp could be much stricter than this...
654
-						if (!preg_match('/^[+-eE0123456789 \t.]+$/', $GLOBALS['_xh']['ac']))
655
-						{
656
-							/// @todo: find a better way of throwing an error than this!
657
-							error_log('XML-RPC: non numeric value received in DOUBLE: '.$GLOBALS['_xh']['ac']);
658
-							$GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
659
-						}
660
-						else
661
-						{
662
-							// it's ok, add it on
663
-							$GLOBALS['_xh']['value']=(double)$GLOBALS['_xh']['ac'];
664
-						}
665
-					}
666
-					else
667
-					{
668
-						// we have an I4/INT
669
-						// we must check that only 0123456789-<space> are characters here
670
-						if (!preg_match('/^[+-]?[0123456789 \t]+$/', $GLOBALS['_xh']['ac']))
671
-						{
672
-							/// @todo find a better way of throwing an error than this!
673
-							error_log('XML-RPC: non numeric value received in INT: '.$GLOBALS['_xh']['ac']);
674
-							$GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
675
-						}
676
-						else
677
-						{
678
-							// it's ok, add it on
679
-							$GLOBALS['_xh']['value']=(int)$GLOBALS['_xh']['ac'];
680
-						}
681
-					}
682
-					//$GLOBALS['_xh']['ac']=''; // is this necessary?
683
-					$GLOBALS['_xh']['lv']=3; // indicate we've found a value
684
-					break;
685
-				case 'NAME':
686
-					$GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name'] = $GLOBALS['_xh']['ac'];
687
-					break;
688
-				case 'MEMBER':
689
-					//$GLOBALS['_xh']['ac']=''; // is this necessary?
690
-					// add to array in the stack the last element built,
691
-					// unless no VALUE was found
692
-					if ($GLOBALS['_xh']['vt'])
693
-					{
694
-						$vscount = count($GLOBALS['_xh']['valuestack']);
695
-						$GLOBALS['_xh']['valuestack'][$vscount-1]['values'][$GLOBALS['_xh']['valuestack'][$vscount-1]['name']] = $GLOBALS['_xh']['value'];
696
-					} else
697
-						error_log('XML-RPC: missing VALUE inside STRUCT in received xml');
698
-					break;
699
-				case 'DATA':
700
-					//$GLOBALS['_xh']['ac']=''; // is this necessary?
701
-					$GLOBALS['_xh']['vt']=null; // reset this to check for 2 data elements in a row - even if they're empty
702
-					break;
703
-				case 'STRUCT':
704
-				case 'ARRAY':
705
-					// fetch out of stack array of values, and promote it to current value
706
-					$curr_val = array_pop($GLOBALS['_xh']['valuestack']);
707
-					$GLOBALS['_xh']['value'] = $curr_val['values'];
708
-					$GLOBALS['_xh']['vt']=strtolower($name);
709
-					if (isset($curr_val['php_class']))
710
-					{
711
-						$GLOBALS['_xh']['php_class'] = $curr_val['php_class'];
712
-					}
713
-					break;
714
-				case 'PARAM':
715
-					// add to array of params the current value,
716
-					// unless no VALUE was found
717
-					if ($GLOBALS['_xh']['vt'])
718
-					{
719
-						$GLOBALS['_xh']['params'][]=$GLOBALS['_xh']['value'];
720
-						$GLOBALS['_xh']['pt'][]=$GLOBALS['_xh']['vt'];
721
-					}
722
-					else
723
-						error_log('XML-RPC: missing VALUE inside PARAM in received xml');
724
-					break;
725
-				case 'METHODNAME':
726
-					$GLOBALS['_xh']['method']=preg_replace('/^[\n\r\t ]+/', '', $GLOBALS['_xh']['ac']);
727
-					break;
728
-				case 'NIL':
729
-				case 'EX:NIL':
730
-					if ($GLOBALS['xmlrpc_null_extension'])
731
-					{
732
-						$GLOBALS['_xh']['vt']='null';
733
-						$GLOBALS['_xh']['value']=null;
734
-						$GLOBALS['_xh']['lv']=3;
735
-						break;
736
-					}
737
-					// drop through intentionally if nil extension not enabled
738
-				case 'PARAMS':
739
-				case 'FAULT':
740
-				case 'METHODCALL':
741
-				case 'METHORESPONSE':
742
-					break;
743
-				default:
744
-					// End of INVALID ELEMENT!
745
-					// shall we add an assert here for unreachable code???
746
-					break;
747
-			}
748
-		}
749
-	}
750
-
751
-	/// Used in decoding xmlrpc requests/responses without rebuilding xmlrpc values
752
-	function xmlrpc_ee_fast($parser, $name)
753
-	{
754
-		xmlrpc_ee($parser, $name, false);
755
-	}
756
-
757
-	/// xml parser handler function for character data
758
-	function xmlrpc_cd($parser, $data)
759
-	{
760
-		// skip processing if xml fault already detected
761
-		if ($GLOBALS['_xh']['isf'] < 2)
762
-		{
763
-			// "lookforvalue==3" means that we've found an entire value
764
-			// and should discard any further character data
765
-			if($GLOBALS['_xh']['lv']!=3)
766
-			{
767
-				// G. Giunta 2006-08-23: useless change of 'lv' from 1 to 2
768
-				//if($GLOBALS['_xh']['lv']==1)
769
-				//{
770
-					// if we've found text and we're just in a <value> then
771
-					// say we've found a value
772
-					//$GLOBALS['_xh']['lv']=2;
773
-				//}
774
-				// we always initialize the accumulator before starting parsing, anyway...
775
-				//if(!@isset($GLOBALS['_xh']['ac']))
776
-				//{
777
-				//	$GLOBALS['_xh']['ac'] = '';
778
-				//}
779
-				$GLOBALS['_xh']['ac'].=$data;
780
-			}
781
-		}
782
-	}
783
-
784
-	/// xml parser handler function for 'other stuff', ie. not char data or
785
-	/// element start/end tag. In fact it only gets called on unknown entities...
786
-	function xmlrpc_dh($parser, $data)
787
-	{
788
-		// skip processing if xml fault already detected
789
-		if ($GLOBALS['_xh']['isf'] < 2)
790
-		{
791
-			if(substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
792
-			{
793
-				// G. Giunta 2006-08-25: useless change of 'lv' from 1 to 2
794
-				//if($GLOBALS['_xh']['lv']==1)
795
-				//{
796
-				//	$GLOBALS['_xh']['lv']=2;
797
-				//}
798
-				$GLOBALS['_xh']['ac'].=$data;
799
-			}
800
-		}
801
-		return true;
802
-	}
803
-
804
-	class xmlrpc_client
805
-	{
806
-		var $path;
807
-		var $server;
808
-		var $port=0;
809
-		var $method='http';
810
-		var $errno;
811
-		var $errstr;
812
-		var $debug=0;
813
-		var $username='';
814
-		var $password='';
815
-		var $authtype=1;
816
-		var $cert='';
817
-		var $certpass='';
818
-		var $cacert='';
819
-		var $cacertdir='';
820
-		var $key='';
821
-		var $keypass='';
822
-		var $verifypeer=true;
823
-		var $verifyhost=1;
824
-		var $sslversion=0; // corresponds to CURL_SSLVERSION_DEFAULT
825
-		var $no_multicall=false;
826
-		var $proxy='';
827
-		var $proxyport=0;
828
-		var $proxy_user='';
829
-		var $proxy_pass='';
830
-		var $proxy_authtype=1;
831
-		var $cookies=array();
832
-		var $extracurlopts=array();
833
-
834
-		/**
835
-		* List of http compression methods accepted by the client for responses.
836
-		* NB: PHP supports deflate, gzip compressions out of the box if compiled w. zlib
837
-		*
838
-		* NNB: you can set it to any non-empty array for HTTP11 and HTTPS, since
839
-		* in those cases it will be up to CURL to decide the compression methods
840
-		* it supports. You might check for the presence of 'zlib' in the output of
841
-		* curl_version() to determine wheter compression is supported or not
842
-		*/
843
-		var $accepted_compression = array();
844
-		/**
845
-		* Name of compression scheme to be used for sending requests.
846
-		* Either null, gzip or deflate
847
-		*/
848
-		var $request_compression = '';
849
-		/**
850
-		* CURL handle: used for keep-alive connections (PHP 4.3.8 up, see:
851
-		* http://curl.haxx.se/docs/faq.html#7.3)
852
-		*/
853
-		var $xmlrpc_curl_handle = null;
854
-		/// Whether to use persistent connections for http 1.1 and https
855
-		var $keepalive = false;
856
-		/// Charset encodings that can be decoded without problems by the client
857
-		var $accepted_charset_encodings = array();
858
-		/// Charset encoding to be used in serializing request. NULL = use ASCII
859
-		var $request_charset_encoding = '';
860
-		/**
861
-		* Decides the content of xmlrpcresp objects returned by calls to send()
862
-		* valid strings are 'xmlrpcvals', 'phpvals' or 'xml'
863
-		*/
864
-		var $return_type = 'xmlrpcvals';
865
-		/**
866
-		* Sent to servers in http headers
867
-		*/
868
-		var $user_agent;
869
-
870
-		/**
871
-		* @param string $path either the complete server URL or the PATH part of the xmlrc server URL, e.g. /xmlrpc/server.php
872
-		* @param string $server the server name / ip address
873
-		* @param integer $port the port the server is listening on, defaults to 80 or 443 depending on protocol used
874
-		* @param string $method the http protocol variant: defaults to 'http', 'https' and 'http11' can be used if CURL is installed
875
-		*/
876
-		function __construct($path, $server='', $port='', $method='')
877
-		{
878
-			// allow user to specify all params in $path
879
-			if($server == '' and $port == '' and $method == '')
880
-			{
881
-				$parts = parse_url($path);
882
-				$server = $parts['host'];
883
-				$path = isset($parts['path']) ? $parts['path'] : '';
884
-				if(isset($parts['query']))
885
-				{
886
-					$path .= '?'.$parts['query'];
887
-				}
888
-				if(isset($parts['fragment']))
889
-				{
890
-					$path .= '#'.$parts['fragment'];
891
-				}
892
-				if(isset($parts['port']))
893
-				{
894
-					$port = $parts['port'];
895
-				}
896
-				if(isset($parts['scheme']))
897
-				{
898
-					$method = $parts['scheme'];
899
-				}
900
-				if(isset($parts['user']))
901
-				{
902
-					$this->username = $parts['user'];
903
-				}
904
-				if(isset($parts['pass']))
905
-				{
906
-					$this->password = $parts['pass'];
907
-				}
908
-			}
909
-			if($path == '' || $path[0] != '/')
910
-			{
911
-				$this->path='/'.$path;
912
-			}
913
-			else
914
-			{
915
-				$this->path=$path;
916
-			}
917
-			$this->server=$server;
918
-			if($port != '')
919
-			{
920
-				$this->port=$port;
921
-			}
922
-			if($method != '')
923
-			{
924
-				$this->method=$method;
925
-			}
926
-
927
-			// if ZLIB is enabled, let the client by default accept compressed responses
928
-			if(function_exists('gzinflate') || (
929
-				function_exists('curl_init') && (($info = curl_version()) &&
930
-				((is_string($info) && strpos($info, 'zlib') !== null) || isset($info['libz_version'])))
931
-			))
932
-			{
933
-				$this->accepted_compression = array('gzip', 'deflate');
934
-			}
935
-
936
-			// keepalives: enabled by default
937
-			$this->keepalive = true;
938
-
939
-			// by default the xml parser can support these 3 charset encodings
940
-			$this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
941
-
942
-			// initialize user_agent string
943
-			$this->user_agent = $GLOBALS['xmlrpcName'] . ' ' . $GLOBALS['xmlrpcVersion'];
944
-		}
945
-
946
-		/**
947
-		* @deprecated
948
-		*/
949
-		function xmlrpc_client($path, $server='', $port='', $method='')
950
-		{
951
-			self::__construct($path, $server, $port, $method);
952
-		}
953
-
954
-		/**
955
-		* Enables/disables the echoing to screen of the xmlrpc responses received
956
-		* @param integer $in values 0, 1 and 2 are supported (2 = echo sent msg too, before received response)
957
-		* @access public
958
-		*/
959
-		function setDebug($in)
960
-		{
961
-			$this->debug=$in;
962
-		}
963
-
964
-		/**
965
-		* Add some http BASIC AUTH credentials, used by the client to authenticate
966
-		* @param string $u username
967
-		* @param string $p password
968
-		* @param integer $t auth type. See curl_setopt man page for supported auth types. Defaults to CURLAUTH_BASIC (basic auth)
969
-		* @access public
970
-		*/
971
-		function setCredentials($u, $p, $t=1)
972
-		{
973
-			$this->username=$u;
974
-			$this->password=$p;
975
-			$this->authtype=$t;
976
-		}
977
-
978
-		/**
979
-		* Add a client-side https certificate
980
-		* @param string $cert
981
-		* @param string $certpass
982
-		* @access public
983
-		*/
984
-		function setCertificate($cert, $certpass)
985
-		{
986
-			$this->cert = $cert;
987
-			$this->certpass = $certpass;
988
-		}
989
-
990
-		/**
991
-		* Add a CA certificate to verify server with (see man page about
992
-		* CURLOPT_CAINFO for more details)
993
-		* @param string $cacert certificate file name (or dir holding certificates)
994
-		* @param bool $is_dir set to true to indicate cacert is a dir. defaults to false
995
-		* @access public
996
-		*/
997
-		function setCaCertificate($cacert, $is_dir=false)
998
-		{
999
-			if ($is_dir)
1000
-			{
1001
-				$this->cacertdir = $cacert;
1002
-			}
1003
-			else
1004
-			{
1005
-				$this->cacert = $cacert;
1006
-			}
1007
-		}
1008
-
1009
-		/**
1010
-		* Set attributes for SSL communication: private SSL key
1011
-		* NB: does not work in older php/curl installs
1012
-		* Thanks to Daniel Convissor
1013
-		* @param string $key The name of a file containing a private SSL key
1014
-		* @param string $keypass The secret password needed to use the private SSL key
1015
-		* @access public
1016
-		*/
1017
-		function setKey($key, $keypass)
1018
-		{
1019
-			$this->key = $key;
1020
-			$this->keypass = $keypass;
1021
-		}
1022
-
1023
-		/**
1024
-		* Set attributes for SSL communication: verify server certificate
1025
-		* @param bool $i enable/disable verification of peer certificate
1026
-		* @access public
1027
-		*/
1028
-		function setSSLVerifyPeer($i)
1029
-		{
1030
-			$this->verifypeer = $i;
1031
-		}
1032
-
1033
-		/**
1034
-		* Set attributes for SSL communication: verify match of server cert w. hostname
1035
-		* @param int $i
1036
-		* @access public
1037
-		*/
1038
-		function setSSLVerifyHost($i)
1039
-		{
1040
-			$this->verifyhost = $i;
1041
-		}
1042
-
1043
-		/**
1044
-		* Set attributes for SSL communication: SSL version to use. Best left at 0 (default value ): let cURL decide
1045
-		*
1046
-		* @param int $i
1047
-		*/
1048
-		public function setSSLVersion($i)
1049
-		{
1050
-			$this->sslversion = $i;
1051
-		}
1052
-
1053
-		/**
1054
-		* Set proxy info
1055
-		* @param string $proxyhost
1056
-		* @param string $proxyport Defaults to 8080 for HTTP and 443 for HTTPS
1057
-		* @param string $proxyusername Leave blank if proxy has public access
1058
-		* @param string $proxypassword Leave blank if proxy has public access
1059
-		* @param int $proxyauthtype set to constant CURLAUTH_NTLM to use NTLM auth with proxy
1060
-		* @access public
1061
-		*/
1062
-		function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 1)
1063
-		{
1064
-			$this->proxy = $proxyhost;
1065
-			$this->proxyport = $proxyport;
1066
-			$this->proxy_user = $proxyusername;
1067
-			$this->proxy_pass = $proxypassword;
1068
-			$this->proxy_authtype = $proxyauthtype;
1069
-		}
1070
-
1071
-		/**
1072
-		* Enables/disables reception of compressed xmlrpc responses.
1073
-		* Note that enabling reception of compressed responses merely adds some standard
1074
-		* http headers to xmlrpc requests. It is up to the xmlrpc server to return
1075
-		* compressed responses when receiving such requests.
1076
-		* @param string $compmethod either 'gzip', 'deflate', 'any' or ''
1077
-		* @access public
1078
-		*/
1079
-		function setAcceptedCompression($compmethod)
1080
-		{
1081
-			if ($compmethod == 'any')
1082
-				$this->accepted_compression = array('gzip', 'deflate');
1083
-			else
1084
-				if ($compmethod == false )
1085
-					$this->accepted_compression = array();
1086
-				else
1087
-					$this->accepted_compression = array($compmethod);
1088
-		}
1089
-
1090
-		/**
1091
-		* Enables/disables http compression of xmlrpc request.
1092
-		* Take care when sending compressed requests: servers might not support them
1093
-		* (and automatic fallback to uncompressed requests is not yet implemented)
1094
-		* @param string $compmethod either 'gzip', 'deflate' or ''
1095
-		* @access public
1096
-		*/
1097
-		function setRequestCompression($compmethod)
1098
-		{
1099
-			$this->request_compression = $compmethod;
1100
-		}
1101
-
1102
-		/**
1103
-		* Adds a cookie to list of cookies that will be sent to server.
1104
-		* NB: setting any param but name and value will turn the cookie into a 'version 1' cookie:
1105
-		* do not do it unless you know what you are doing
1106
-		* @param string $name
1107
-		* @param string $value
1108
-		* @param string $path
1109
-		* @param string $domain
1110
-		* @param int $port
1111
-		* @access public
1112
-		*
1113
-		* @todo check correctness of urlencoding cookie value (copied from php way of doing it...)
1114
-		*/
1115
-		function setCookie($name, $value='', $path='', $domain='', $port=null)
1116
-		{
1117
-			$this->cookies[$name]['value'] = urlencode($value);
1118
-			if ($path || $domain || $port)
1119
-			{
1120
-				$this->cookies[$name]['path'] = $path;
1121
-				$this->cookies[$name]['domain'] = $domain;
1122
-				$this->cookies[$name]['port'] = $port;
1123
-				$this->cookies[$name]['version'] = 1;
1124
-			}
1125
-			else
1126
-			{
1127
-				$this->cookies[$name]['version'] = 0;
1128
-			}
1129
-		}
1130
-
1131
-		/**
1132
-		* Directly set cURL options, for extra flexibility
1133
-		* It allows eg. to bind client to a specific IP interface / address
1134
-		* @param array $options
1135
-		*/
1136
-		function SetCurlOptions( $options )
1137
-		{
1138
-			$this->extracurlopts = $options;
1139
-		}
1140
-
1141
-		/**
1142
-		* Set user-agent string that will be used by this client instance
1143
-		* in http headers sent to the server
1144
-		*/
1145
-		function SetUserAgent( $agentstring )
1146
-		{
1147
-			$this->user_agent = $agentstring;
1148
-		}
1149
-
1150
-		/**
1151
-		* Send an xmlrpc request
1152
-		* @param mixed $msg The message object, or an array of messages for using multicall, or the complete xml representation of a request
1153
-		* @param integer $timeout Connection timeout, in seconds, If unspecified, a platform specific timeout will apply
1154
-		* @param string $method if left unspecified, the http protocol chosen during creation of the object will be used
1155
-		* @return xmlrpcresp
1156
-		* @access public
1157
-		*/
1158
-		function& send($msg, $timeout=0, $method='')
1159
-		{
1160
-			// if user deos not specify http protocol, use native method of this client
1161
-			// (i.e. method set during call to constructor)
1162
-			if($method == '')
1163
-			{
1164
-				$method = $this->method;
1165
-			}
1166
-
1167
-			if(is_array($msg))
1168
-			{
1169
-				// $msg is an array of xmlrpcmsg's
1170
-				$r = $this->multicall($msg, $timeout, $method);
1171
-				return $r;
1172
-			}
1173
-			elseif(is_string($msg))
1174
-			{
1175
-				$n = new xmlrpcmsg('');
1176
-				$n->payload = $msg;
1177
-				$msg = $n;
1178
-			}
1179
-
1180
-			// where msg is an xmlrpcmsg
1181
-			$msg->debug=$this->debug;
1182
-
1183
-			if($method == 'https')
1184
-			{
1185
-				$r =& $this->sendPayloadHTTPS(
1186
-					$msg,
1187
-					$this->server,
1188
-					$this->port,
1189
-					$timeout,
1190
-					$this->username,
1191
-					$this->password,
1192
-					$this->authtype,
1193
-					$this->cert,
1194
-					$this->certpass,
1195
-					$this->cacert,
1196
-					$this->cacertdir,
1197
-					$this->proxy,
1198
-					$this->proxyport,
1199
-					$this->proxy_user,
1200
-					$this->proxy_pass,
1201
-					$this->proxy_authtype,
1202
-					$this->keepalive,
1203
-					$this->key,
1204
-					$this->keypass,
1205
-					$this->sslversion
1206
-				);
1207
-			}
1208
-			elseif($method == 'http11')
1209
-			{
1210
-				$r =& $this->sendPayloadCURL(
1211
-					$msg,
1212
-					$this->server,
1213
-					$this->port,
1214
-					$timeout,
1215
-					$this->username,
1216
-					$this->password,
1217
-					$this->authtype,
1218
-					null,
1219
-					null,
1220
-					null,
1221
-					null,
1222
-					$this->proxy,
1223
-					$this->proxyport,
1224
-					$this->proxy_user,
1225
-					$this->proxy_pass,
1226
-					$this->proxy_authtype,
1227
-					'http',
1228
-					$this->keepalive
1229
-				);
1230
-			}
1231
-			else
1232
-			{
1233
-				$r =& $this->sendPayloadHTTP10(
1234
-					$msg,
1235
-					$this->server,
1236
-					$this->port,
1237
-					$timeout,
1238
-					$this->username,
1239
-					$this->password,
1240
-					$this->authtype,
1241
-					$this->proxy,
1242
-					$this->proxyport,
1243
-					$this->proxy_user,
1244
-					$this->proxy_pass,
1245
-					$this->proxy_authtype
1246
-				);
1247
-			}
1248
-
1249
-			return $r;
1250
-		}
1251
-
1252
-		/**
1253
-		* @access private
1254
-		*/
1255
-		function &sendPayloadHTTP10($msg, $server, $port, $timeout=0,
1256
-			$username='', $password='', $authtype=1, $proxyhost='',
1257
-			$proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1)
1258
-		{
1259
-			if($port==0)
1260
-			{
1261
-				$port=80;
1262
-			}
1263
-
1264
-			// Only create the payload if it was not created previously
1265
-			if(empty($msg->payload))
1266
-			{
1267
-				$msg->createPayload($this->request_charset_encoding);
1268
-			}
1269
-
1270
-			$payload = $msg->payload;
1271
-			// Deflate request body and set appropriate request headers
1272
-			if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1273
-			{
1274
-				if($this->request_compression == 'gzip')
1275
-				{
1276
-					$a = @gzencode($payload);
1277
-					if($a)
1278
-					{
1279
-						$payload = $a;
1280
-						$encoding_hdr = "Content-Encoding: gzip\r\n";
1281
-					}
1282
-				}
1283
-				else
1284
-				{
1285
-					$a = @gzcompress($payload);
1286
-					if($a)
1287
-					{
1288
-						$payload = $a;
1289
-						$encoding_hdr = "Content-Encoding: deflate\r\n";
1290
-					}
1291
-				}
1292
-			}
1293
-			else
1294
-			{
1295
-				$encoding_hdr = '';
1296
-			}
1297
-
1298
-			// thanks to Grant Rauscher <[email protected]> for this
1299
-			$credentials='';
1300
-			if($username!='')
1301
-			{
1302
-				$credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n";
1303
-				if ($authtype != 1)
1304
-				{
1305
-					error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported with HTTP 1.0');
1306
-				}
1307
-			}
1308
-
1309
-			$accepted_encoding = '';
1310
-			if(is_array($this->accepted_compression) && count($this->accepted_compression))
1311
-			{
1312
-				$accepted_encoding = 'Accept-Encoding: ' . implode(', ', $this->accepted_compression) . "\r\n";
1313
-			}
1314
-
1315
-			$proxy_credentials = '';
1316
-			if($proxyhost)
1317
-			{
1318
-				if($proxyport == 0)
1319
-				{
1320
-					$proxyport = 8080;
1321
-				}
1322
-				$connectserver = $proxyhost;
1323
-				$connectport = $proxyport;
1324
-				$uri = 'http://'.$server.':'.$port.$this->path;
1325
-				if($proxyusername != '')
1326
-				{
1327
-					if ($proxyauthtype != 1)
1328
-					{
1329
-						error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported with HTTP 1.0');
1330
-					}
1331
-					$proxy_credentials = 'Proxy-Authorization: Basic ' . base64_encode($proxyusername.':'.$proxypassword) . "\r\n";
1332
-				}
1333
-			}
1334
-			else
1335
-			{
1336
-				$connectserver = $server;
1337
-				$connectport = $port;
1338
-				$uri = $this->path;
1339
-			}
1340
-
1341
-			// Cookie generation, as per rfc2965 (version 1 cookies) or
1342
-			// netscape's rules (version 0 cookies)
1343
-			$cookieheader='';
1344
-			if (count($this->cookies))
1345
-			{
1346
-				$version = '';
1347
-				foreach ($this->cookies as $name => $cookie)
1348
-				{
1349
-					if ($cookie['version'])
1350
-					{
1351
-						$version = ' $Version="' . $cookie['version'] . '";';
1352
-						$cookieheader .= ' ' . $name . '="' . $cookie['value'] . '";';
1353
-						if ($cookie['path'])
1354
-							$cookieheader .= ' $Path="' . $cookie['path'] . '";';
1355
-						if ($cookie['domain'])
1356
-							$cookieheader .= ' $Domain="' . $cookie['domain'] . '";';
1357
-						if ($cookie['port'])
1358
-							$cookieheader .= ' $Port="' . $cookie['port'] . '";';
1359
-					}
1360
-					else
1361
-					{
1362
-						$cookieheader .= ' ' . $name . '=' . $cookie['value'] . ";";
1363
-					}
1364
-				}
1365
-				$cookieheader = 'Cookie:' . $version . substr($cookieheader, 0, -1) . "\r\n";
1366
-			}
1367
-
1368
-			// omit port if 80
1369
-			$port = ($port == 80) ? '' : (':' . $port);
1370
-
1371
-			$op= 'POST ' . $uri. " HTTP/1.0\r\n" .
1372
-				'User-Agent: ' . $this->user_agent . "\r\n" .
1373
-				'Host: '. $server . $port . "\r\n" .
1374
-				$credentials .
1375
-				$proxy_credentials .
1376
-				$accepted_encoding .
1377
-				$encoding_hdr .
1378
-				'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings) . "\r\n" .
1379
-				$cookieheader .
1380
-				'Content-Type: ' . $msg->content_type . "\r\nContent-Length: " .
1381
-				strlen($payload) . "\r\n\r\n" .
1382
-				$payload;
1383
-
1384
-			if($this->debug > 1)
1385
-			{
1386
-				print "<PRE>\n---SENDING---\n" . htmlentities($op) . "\n---END---\n</PRE>";
1387
-				// let the client see this now in case http times out...
1388
-				flush();
1389
-			}
1390
-
1391
-			if($timeout>0)
1392
-			{
1393
-				$fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr, $timeout);
1394
-			}
1395
-			else
1396
-			{
1397
-				$fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr);
1398
-			}
1399
-			if($fp)
1400
-			{
1401
-				if($timeout>0 && function_exists('stream_set_timeout'))
1402
-				{
1403
-					stream_set_timeout($fp, $timeout);
1404
-				}
1405
-			}
1406
-			else
1407
-			{
1408
-				$this->errstr='Connect error: '.$this->errstr;
1409
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr . ' (' . $this->errno . ')');
1410
-				return $r;
1411
-			}
1412
-
1413
-			if(!fputs($fp, $op, strlen($op)))
1414
-			{
1415
-				fclose($fp);
1416
-				$this->errstr='Write error';
1417
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr);
1418
-				return $r;
1419
-			}
1420
-			else
1421
-			{
1422
-				// reset errno and errstr on successful socket connection
1423
-				$this->errstr = '';
1424
-			}
1425
-			// G. Giunta 2005/10/24: close socket before parsing.
1426
-			// should yield slightly better execution times, and make easier recursive calls (e.g. to follow http redirects)
1427
-			$ipd='';
1428
-			do
1429
-			{
1430
-				// shall we check for $data === FALSE?
1431
-				// as per the manual, it signals an error
1432
-				$ipd.=fread($fp, 32768);
1433
-			} while(!feof($fp));
1434
-			fclose($fp);
1435
-			$r =& $msg->parseResponse($ipd, false, $this->return_type);
1436
-			return $r;
1437
-
1438
-		}
1439
-
1440
-		/**
1441
-		* @access private
1442
-		*/
1443
-		function &sendPayloadHTTPS($msg, $server, $port, $timeout=0, $username='',
1444
-			$password='', $authtype=1, $cert='',$certpass='', $cacert='', $cacertdir='',
1445
-			$proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1,
1446
-			$keepalive=false, $key='', $keypass='', $sslVersion = 0)
1447
-		{
1448
-			$r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username,
1449
-				$password, $authtype, $cert, $certpass, $cacert, $cacertdir, $proxyhost, $proxyport,
1450
-				$proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass, $sslVersion);
1451
-			return $r;
1452
-		}
1453
-
1454
-		/**
1455
-		* Contributed by Justin Miller <[email protected]>
1456
-		* Requires curl to be built into PHP
1457
-		* NB: CURL versions before 7.11.10 cannot use proxy to talk to https servers!
1458
-		* @access private
1459
-		*/
1460
-		function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='',
1461
-			$password='', $authtype=1, $cert='', $certpass='', $cacert='', $cacertdir='',
1462
-			$proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $method='https',
1463
-			$keepalive=false, $key='', $keypass='', $sslVersion = 0)
1464
-		{
1465
-			if(!function_exists('curl_init'))
1466
-			{
1467
-				$this->errstr='CURL unavailable on this install';
1468
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_curl'], $GLOBALS['xmlrpcstr']['no_curl']);
1469
-				return $r;
1470
-			}
1471
-			if($method == 'https')
1472
-			{
1473
-				if(($info = curl_version()) &&
1474
-					((is_string($info) && strpos($info, 'OpenSSL') === null) || (is_array($info) && !isset($info['ssl_version']))))
1475
-				{
1476
-					$this->errstr='SSL unavailable on this install';
1477
-					$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_ssl'], $GLOBALS['xmlrpcstr']['no_ssl']);
1478
-					return $r;
1479
-				}
1480
-			}
1481
-
1482
-			if($port == 0)
1483
-			{
1484
-				if($method == 'http')
1485
-				{
1486
-					$port = 80;
1487
-				}
1488
-				else
1489
-				{
1490
-					$port = 443;
1491
-				}
1492
-			}
1493
-
1494
-			// Only create the payload if it was not created previously
1495
-			if(empty($msg->payload))
1496
-			{
1497
-				$msg->createPayload($this->request_charset_encoding);
1498
-			}
1499
-
1500
-			// Deflate request body and set appropriate request headers
1501
-			$payload = $msg->payload;
1502
-			if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1503
-			{
1504
-				if($this->request_compression == 'gzip')
1505
-				{
1506
-					$a = @gzencode($payload);
1507
-					if($a)
1508
-					{
1509
-						$payload = $a;
1510
-						$encoding_hdr = 'Content-Encoding: gzip';
1511
-					}
1512
-				}
1513
-				else
1514
-				{
1515
-					$a = @gzcompress($payload);
1516
-					if($a)
1517
-					{
1518
-						$payload = $a;
1519
-						$encoding_hdr = 'Content-Encoding: deflate';
1520
-					}
1521
-				}
1522
-			}
1523
-			else
1524
-			{
1525
-				$encoding_hdr = '';
1526
-			}
1527
-
1528
-			if($this->debug > 1)
1529
-			{
1530
-				print "<PRE>\n---SENDING---\n" . htmlentities($payload) . "\n---END---\n</PRE>";
1531
-				// let the client see this now in case http times out...
1532
-				flush();
1533
-			}
1534
-
1535
-			if(!$keepalive || !$this->xmlrpc_curl_handle)
1536
-			{
1537
-				$curl = curl_init($method . '://' . $server . ':' . $port . $this->path);
1538
-				if($keepalive)
1539
-				{
1540
-					$this->xmlrpc_curl_handle = $curl;
1541
-				}
1542
-			}
1543
-			else
1544
-			{
1545
-				$curl = $this->xmlrpc_curl_handle;
1546
-			}
1547
-
1548
-			// results into variable
1549
-			curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
1550
-
1551
-			if($this->debug)
1552
-			{
1553
-				curl_setopt($curl, CURLOPT_VERBOSE, 1);
1554
-			}
1555
-			curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
1556
-			// required for XMLRPC: post the data
1557
-			curl_setopt($curl, CURLOPT_POST, 1);
1558
-			// the data
1559
-			curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
1560
-
1561
-			// return the header too
1562
-			curl_setopt($curl, CURLOPT_HEADER, 1);
1563
-
1564
-			// NB: if we set an empty string, CURL will add http header indicating
1565
-			// ALL methods it is supporting. This is possibly a better option than
1566
-			// letting the user tell what curl can / cannot do...
1567
-			if(is_array($this->accepted_compression) && count($this->accepted_compression))
1568
-			{
1569
-				//curl_setopt($curl, CURLOPT_ENCODING, implode(',', $this->accepted_compression));
1570
-				// empty string means 'any supported by CURL' (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1571
-				if (count($this->accepted_compression) == 1)
1572
-				{
1573
-					curl_setopt($curl, CURLOPT_ENCODING, $this->accepted_compression[0]);
1574
-				}
1575
-				else
1576
-					curl_setopt($curl, CURLOPT_ENCODING, '');
1577
-			}
1578
-			// extra headers
1579
-			$headers = array('Content-Type: ' . $msg->content_type , 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings));
1580
-			// if no keepalive is wanted, let the server know it in advance
1581
-			if(!$keepalive)
1582
-			{
1583
-				$headers[] = 'Connection: close';
1584
-			}
1585
-			// request compression header
1586
-			if($encoding_hdr)
1587
-			{
1588
-				$headers[] = $encoding_hdr;
1589
-			}
1590
-
1591
-			curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1592
-			// timeout is borked
1593
-			if($timeout)
1594
-			{
1595
-				curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1);
1596
-			}
1597
-
1598
-			if($username && $password)
1599
-			{
1600
-				curl_setopt($curl, CURLOPT_USERPWD, $username.':'.$password);
1601
-				if (defined('CURLOPT_HTTPAUTH'))
1602
-				{
1603
-					curl_setopt($curl, CURLOPT_HTTPAUTH, $authtype);
1604
-				}
1605
-				else if ($authtype != 1)
1606
-				{
1607
-					error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported by the current PHP/curl install');
1608
-				}
1609
-			}
1610
-
1611
-			if($method == 'https')
1612
-			{
1613
-				// set cert file
1614
-				if($cert)
1615
-				{
1616
-					curl_setopt($curl, CURLOPT_SSLCERT, $cert);
1617
-				}
1618
-				// set cert password
1619
-				if($certpass)
1620
-				{
1621
-					curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $certpass);
1622
-				}
1623
-				// whether to verify remote host's cert
1624
-				curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer);
1625
-				// set ca certificates file/dir
1626
-				if($cacert)
1627
-				{
1628
-					curl_setopt($curl, CURLOPT_CAINFO, $cacert);
1629
-				}
1630
-				if($cacertdir)
1631
-				{
1632
-					curl_setopt($curl, CURLOPT_CAPATH, $cacertdir);
1633
-				}
1634
-				// set key file (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1635
-				if($key)
1636
-				{
1637
-					curl_setopt($curl, CURLOPT_SSLKEY, $key);
1638
-				}
1639
-				// set key password (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1640
-				if($keypass)
1641
-				{
1642
-					curl_setopt($curl, CURLOPT_SSLKEYPASSWD, $keypass);
1643
-				}
1644
-
1645
-				// Upgrade transparently to more stringent check for versions of php which do not support otherwise.
1646
-				// Doing it in constructor would be cleaner; doing it here saves us a couple of function calls
1647
-				if($this->verifyhost == 1 && $info = curl_version() && version_compare($info['version'], '7.28.1') >= 0)
1648
-				{
1649
-					$this->verifyhost = 2;
1650
-				}
1651
-				// whether to verify cert's common name (CN); 0 for no, 1 to verify that it exists, and 2 to verify that it matches the hostname used
1652
-				curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost);
1653
-				// allow usage of different SSL versions
1654
-				curl_setopt($curl, CURLOPT_SSLVERSION, $sslVersion);
1655
-			}
1656
-
1657
-			// proxy info
1658
-			if($proxyhost)
1659
-			{
1660
-				if($proxyport == 0)
1661
-				{
1662
-					$proxyport = 8080; // NB: even for HTTPS, local connection is on port 8080
1663
-				}
1664
-				curl_setopt($curl, CURLOPT_PROXY, $proxyhost.':'.$proxyport);
1665
-				//curl_setopt($curl, CURLOPT_PROXYPORT,$proxyport);
1666
-				if($proxyusername)
1667
-				{
1668
-					curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyusername.':'.$proxypassword);
1669
-					if (defined('CURLOPT_PROXYAUTH'))
1670
-					{
1671
-						curl_setopt($curl, CURLOPT_PROXYAUTH, $proxyauthtype);
1672
-					}
1673
-					else if ($proxyauthtype != 1)
1674
-					{
1675
-						error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported by the current PHP/curl install');
1676
-					}
1677
-				}
1678
-			}
1679
-
1680
-			// NB: should we build cookie http headers by hand rather than let CURL do it?
1681
-			// the following code does not honour 'expires', 'path' and 'domain' cookie attributes
1682
-			// set to client obj the the user...
1683
-			if (count($this->cookies))
1684
-			{
1685
-				$cookieheader = '';
1686
-				foreach ($this->cookies as $name => $cookie)
1687
-				{
1688
-					$cookieheader .= $name . '=' . $cookie['value'] . '; ';
1689
-				}
1690
-				curl_setopt($curl, CURLOPT_COOKIE, substr($cookieheader, 0, -2));
1691
-			}
1692
-
1693
-			foreach ($this->extracurlopts as $opt => $val)
1694
-			{
1695
-				curl_setopt($curl, $opt, $val);
1696
-			}
1697
-
1698
-			$result = curl_exec($curl);
1699
-
1700
-			if ($this->debug > 1)
1701
-			{
1702
-				print "<PRE>\n---CURL INFO---\n";
1703
-				foreach(curl_getinfo($curl) as $name => $val)
1704
-				{
1705
-					if (is_array($val))
1706
-					{
1707
-						$val = implode("\n", $val);
1708
-					}
1709
-					print $name . ': ' . htmlentities($val) . "\n";
1710
-				}
1711
-
1712
-				print "---END---\n</PRE>";
1713
-			}
1714
-
1715
-			if(!$result) /// @todo we should use a better check here - what if we get back '' or '0'?
1716
-			{
1717
-				$this->errstr='no response';
1718
-				$resp=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['curl_fail'], $GLOBALS['xmlrpcstr']['curl_fail']. ': '. curl_error($curl));
1719
-				curl_close($curl);
1720
-				if($keepalive)
1721
-				{
1722
-					$this->xmlrpc_curl_handle = null;
1723
-				}
1724
-			}
1725
-			else
1726
-			{
1727
-				if(!$keepalive)
1728
-				{
1729
-					curl_close($curl);
1730
-				}
1731
-				$resp =& $msg->parseResponse($result, true, $this->return_type);
1732
-				// if we got back a 302, we can not reuse the curl handle for later calls
1733
-				if($resp->faultCode() == $GLOBALS['xmlrpcerr']['http_error'] && $keepalive)
1734
-				{
1735
-					curl_close($curl);
1736
-					$this->xmlrpc_curl_handle = null;
1737
-				}
1738
-			}
1739
-			return $resp;
1740
-		}
1741
-
1742
-		/**
1743
-		* Send an array of request messages and return an array of responses.
1744
-		* Unless $this->no_multicall has been set to true, it will try first
1745
-		* to use one single xmlrpc call to server method system.multicall, and
1746
-		* revert to sending many successive calls in case of failure.
1747
-		* This failure is also stored in $this->no_multicall for subsequent calls.
1748
-		* Unfortunately, there is no server error code universally used to denote
1749
-		* the fact that multicall is unsupported, so there is no way to reliably
1750
-		* distinguish between that and a temporary failure.
1751
-		* If you are sure that server supports multicall and do not want to
1752
-		* fallback to using many single calls, set the fourth parameter to FALSE.
1753
-		*
1754
-		* NB: trying to shoehorn extra functionality into existing syntax has resulted
1755
-		* in pretty much convoluted code...
1756
-		*
1757
-		* @param array $msgs an array of xmlrpcmsg objects
1758
-		* @param integer $timeout connection timeout (in seconds)
1759
-		* @param string $method the http protocol variant to be used
1760
-		* @param boolean fallback When true, upon receiving an error during multicall, multiple single calls will be attempted
1761
-		* @return array
1762
-		* @access public
1763
-		*/
1764
-		function multicall($msgs, $timeout=0, $method='', $fallback=true)
1765
-		{
1766
-			if ($method == '')
1767
-			{
1768
-				$method = $this->method;
1769
-			}
1770
-			if(!$this->no_multicall)
1771
-			{
1772
-				$results = $this->_try_multicall($msgs, $timeout, $method);
1773
-				if(is_array($results))
1774
-				{
1775
-					// System.multicall succeeded
1776
-					return $results;
1777
-				}
1778
-				else
1779
-				{
1780
-					// either system.multicall is unsupported by server,
1781
-					// or call failed for some other reason.
1782
-					if ($fallback)
1783
-					{
1784
-						// Don't try it next time...
1785
-						$this->no_multicall = true;
1786
-					}
1787
-					else
1788
-					{
1789
-						if (is_a($results, 'xmlrpcresp'))
1790
-						{
1791
-							$result = $results;
1792
-						}
1793
-						else
1794
-						{
1795
-							$result = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['multicall_error'], $GLOBALS['xmlrpcstr']['multicall_error']);
1796
-						}
1797
-					}
1798
-				}
1799
-			}
1800
-			else
1801
-			{
1802
-				// override fallback, in case careless user tries to do two
1803
-				// opposite things at the same time
1804
-				$fallback = true;
1805
-			}
1806
-
1807
-			$results = array();
1808
-			if ($fallback)
1809
-			{
1810
-				// system.multicall is (probably) unsupported by server:
1811
-				// emulate multicall via multiple requests
1812
-				foreach($msgs as $msg)
1813
-				{
1814
-					$results[] =& $this->send($msg, $timeout, $method);
1815
-				}
1816
-			}
1817
-			else
1818
-			{
1819
-				// user does NOT want to fallback on many single calls:
1820
-				// since we should always return an array of responses,
1821
-				// return an array with the same error repeated n times
1822
-				foreach($msgs as $msg)
1823
-				{
1824
-					$results[] = $result;
1825
-				}
1826
-			}
1827
-			return $results;
1828
-		}
1829
-
1830
-		/**
1831
-		* Attempt to boxcar $msgs via system.multicall.
1832
-		* Returns either an array of xmlrpcreponses, an xmlrpc error response
1833
-		* or false (when received response does not respect valid multicall syntax)
1834
-		* @access private
1835
-		*/
1836
-		function _try_multicall($msgs, $timeout, $method)
1837
-		{
1838
-			// Construct multicall message
1839
-			$calls = array();
1840
-			foreach($msgs as $msg)
1841
-			{
1842
-				$call['methodName'] = new xmlrpcval($msg->method(),'string');
1843
-				$numParams = $msg->getNumParams();
1844
-				$params = array();
1845
-				for($i = 0; $i < $numParams; $i++)
1846
-				{
1847
-					$params[$i] = $msg->getParam($i);
1848
-				}
1849
-				$call['params'] = new xmlrpcval($params, 'array');
1850
-				$calls[] = new xmlrpcval($call, 'struct');
1851
-			}
1852
-			$multicall = new xmlrpcmsg('system.multicall');
1853
-			$multicall->addParam(new xmlrpcval($calls, 'array'));
1854
-
1855
-			// Attempt RPC call
1856
-			$result =& $this->send($multicall, $timeout, $method);
1857
-
1858
-			if($result->faultCode() != 0)
1859
-			{
1860
-				// call to system.multicall failed
1861
-				return $result;
1862
-			}
1863
-
1864
-			// Unpack responses.
1865
-			$rets = $result->value();
1866
-
1867
-			if ($this->return_type == 'xml')
1868
-			{
1869
-					return $rets;
1870
-			}
1871
-			else if ($this->return_type == 'phpvals')
1872
-			{
1873
-				///@todo test this code branch...
1874
-				$rets = $result->value();
1875
-				if(!is_array($rets))
1876
-				{
1877
-					return false;		// bad return type from system.multicall
1878
-				}
1879
-				$numRets = count($rets);
1880
-				if($numRets != count($msgs))
1881
-				{
1882
-					return false;		// wrong number of return values.
1883
-				}
1884
-
1885
-				$response = array();
1886
-				for($i = 0; $i < $numRets; $i++)
1887
-				{
1888
-					$val = $rets[$i];
1889
-					if (!is_array($val)) {
1890
-						return false;
1891
-					}
1892
-					switch(count($val))
1893
-					{
1894
-						case 1:
1895
-							if(!isset($val[0]))
1896
-							{
1897
-								return false;		// Bad value
1898
-							}
1899
-							// Normal return value
1900
-							$response[$i] = new xmlrpcresp($val[0], 0, '', 'phpvals');
1901
-							break;
1902
-						case 2:
1903
-							///	@todo remove usage of @: it is apparently quite slow
1904
-							$code = @$val['faultCode'];
1905
-							if(!is_int($code))
1906
-							{
1907
-								return false;
1908
-							}
1909
-							$str = @$val['faultString'];
1910
-							if(!is_string($str))
1911
-							{
1912
-								return false;
1913
-							}
1914
-							$response[$i] = new xmlrpcresp(0, $code, $str);
1915
-							break;
1916
-						default:
1917
-							return false;
1918
-					}
1919
-				}
1920
-				return $response;
1921
-			}
1922
-			else // return type == 'xmlrpcvals'
1923
-			{
1924
-				$rets = $result->value();
1925
-				if($rets->kindOf() != 'array')
1926
-				{
1927
-					return false;		// bad return type from system.multicall
1928
-				}
1929
-				$numRets = $rets->arraysize();
1930
-				if($numRets != count($msgs))
1931
-				{
1932
-					return false;		// wrong number of return values.
1933
-				}
1934
-
1935
-				$response = array();
1936
-				for($i = 0; $i < $numRets; $i++)
1937
-				{
1938
-					$val = $rets->arraymem($i);
1939
-					switch($val->kindOf())
1940
-					{
1941
-						case 'array':
1942
-							if($val->arraysize() != 1)
1943
-							{
1944
-								return false;		// Bad value
1945
-							}
1946
-							// Normal return value
1947
-							$response[$i] = new xmlrpcresp($val->arraymem(0));
1948
-							break;
1949
-						case 'struct':
1950
-							$code = $val->structmem('faultCode');
1951
-							if($code->kindOf() != 'scalar' || $code->scalartyp() != 'int')
1952
-							{
1953
-								return false;
1954
-							}
1955
-							$str = $val->structmem('faultString');
1956
-							if($str->kindOf() != 'scalar' || $str->scalartyp() != 'string')
1957
-							{
1958
-								return false;
1959
-							}
1960
-							$response[$i] = new xmlrpcresp(0, $code->scalarval(), $str->scalarval());
1961
-							break;
1962
-						default:
1963
-							return false;
1964
-					}
1965
-				}
1966
-				return $response;
1967
-			}
1968
-		}
1969
-	} // end class xmlrpc_client
1970
-
1971
-	class xmlrpcresp
1972
-	{
1973
-		var $val = 0;
1974
-		var $valtyp;
1975
-		var $errno = 0;
1976
-		var $errstr = '';
1977
-		var $payload;
1978
-		var $hdrs = array();
1979
-		var $_cookies = array();
1980
-		var $content_type = 'text/xml';
1981
-		var $raw_data = '';
1982
-
1983
-		/**
1984
-		* @param mixed $val either an xmlrpcval obj, a php value or the xml serialization of an xmlrpcval (a string)
1985
-		* @param integer $fcode set it to anything but 0 to create an error response
1986
-		* @param string $fstr the error string, in case of an error response
1987
-		* @param string $valtyp either 'xmlrpcvals', 'phpvals' or 'xml'
1988
-		*
1989
-		* @todo add check that $val / $fcode / $fstr is of correct type???
1990
-		* NB: as of now we do not do it, since it might be either an xmlrpcval or a plain
1991
-		* php val, or a complete xml chunk, depending on usage of xmlrpc_client::send() inside which creator is called...
1992
-		*/
1993
-		function __construct($val, $fcode = 0, $fstr = '', $valtyp='')
1994
-		{
1995
-			if($fcode != 0)
1996
-			{
1997
-				// error response
1998
-				$this->errno = $fcode;
1999
-				$this->errstr = $fstr;
2000
-				//$this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later.
2001
-			}
2002
-			else
2003
-			{
2004
-				// successful response
2005
-				$this->val = $val;
2006
-				if ($valtyp == '')
2007
-				{
2008
-					// user did not declare type of response value: try to guess it
2009
-					if (is_object($this->val) && is_a($this->val, 'xmlrpcval'))
2010
-					{
2011
-						$this->valtyp = 'xmlrpcvals';
2012
-					}
2013
-					else if (is_string($this->val))
2014
-					{
2015
-						$this->valtyp = 'xml';
2016
-
2017
-					}
2018
-					else
2019
-					{
2020
-						$this->valtyp = 'phpvals';
2021
-					}
2022
-				}
2023
-				else
2024
-				{
2025
-					// user declares type of resp value: believe him
2026
-					$this->valtyp = $valtyp;
2027
-				}
2028
-			}
2029
-		}
2030
-
2031
-		/**
2032
-		* @deprecated
2033
-		*/
2034
-		function xmlrpcresp($val, $fcode = 0, $fstr = '', $valtyp='')
2035
-		{
2036
-			self::__construct($val, $fcode, $fstr, $valtyp);
2037
-		}
2038
-
2039
-		/**
2040
-		* Returns the error code of the response.
2041
-		* @return integer the error code of this response (0 for not-error responses)
2042
-		* @access public
2043
-		*/
2044
-		function faultCode()
2045
-		{
2046
-			return $this->errno;
2047
-		}
2048
-
2049
-		/**
2050
-		* Returns the error code of the response.
2051
-		* @return string the error string of this response ('' for not-error responses)
2052
-		* @access public
2053
-		*/
2054
-		function faultString()
2055
-		{
2056
-			return $this->errstr;
2057
-		}
2058
-
2059
-		/**
2060
-		* Returns the value received by the server.
2061
-		* @return mixed the xmlrpcval object returned by the server. Might be an xml string or php value if the response has been created by specially configured xmlrpc_client objects
2062
-		* @access public
2063
-		*/
2064
-		function value()
2065
-		{
2066
-			return $this->val;
2067
-		}
2068
-
2069
-		/**
2070
-		* Returns an array with the cookies received from the server.
2071
-		* Array has the form: $cookiename => array ('value' => $val, $attr1 => $val1, $attr2 = $val2, ...)
2072
-		* with attributes being e.g. 'expires', 'path', domain'.
2073
-		* NB: cookies sent as 'expired' by the server (i.e. with an expiry date in the past)
2074
-		* are still present in the array. It is up to the user-defined code to decide
2075
-		* how to use the received cookies, and whether they have to be sent back with the next
2076
-		* request to the server (using xmlrpc_client::setCookie) or not
2077
-		* @return array array of cookies received from the server
2078
-		* @access public
2079
-		*/
2080
-		function cookies()
2081
-		{
2082
-			return $this->_cookies;
2083
-		}
2084
-
2085
-		/**
2086
-		* Returns xml representation of the response. XML prologue not included
2087
-		* @param string $charset_encoding the charset to be used for serialization. if null, US-ASCII is assumed
2088
-		* @return string the xml representation of the response
2089
-		* @access public
2090
-		*/
2091
-		function serialize($charset_encoding='')
2092
-		{
2093
-			if ($charset_encoding != '')
2094
-				$this->content_type = 'text/xml; charset=' . $charset_encoding;
2095
-			else
2096
-				$this->content_type = 'text/xml';
2097
-			if ($GLOBALS['xmlrpc_null_apache_encoding'])
2098
-			{
2099
-				$result = "<methodResponse xmlns:ex=\"".$GLOBALS['xmlrpc_null_apache_encoding_ns']."\">\n";
2100
-			}
2101
-			else
2102
-			{
2103
-			$result = "<methodResponse>\n";
2104
-			}
2105
-			if($this->errno)
2106
-			{
2107
-				// G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients
2108
-				// by xml-encoding non ascii chars
2109
-				$result .= "<fault>\n" .
381
+            default:
382
+                $escaped_data = '';
383
+                error_log("Converting from $src_encoding to $dest_encoding: not supported...");
384
+        }
385
+        return $escaped_data;
386
+    }
387
+
388
+    /// xml parser handler function for opening element tags
389
+    function xmlrpc_se($parser, $name, $attrs, $accept_single_vals=false)
390
+    {
391
+        // if invalid xmlrpc already detected, skip all processing
392
+        if ($GLOBALS['_xh']['isf'] < 2)
393
+        {
394
+            // check for correct element nesting
395
+            // top level element can only be of 2 types
396
+            /// @todo optimization creep: save this check into a bool variable, instead of using count() every time:
397
+            ///       there is only a single top level element in xml anyway
398
+            if (count($GLOBALS['_xh']['stack']) == 0)
399
+            {
400
+                if ($name != 'METHODRESPONSE' && $name != 'METHODCALL' && (
401
+                    $name != 'VALUE' && !$accept_single_vals))
402
+                {
403
+                    $GLOBALS['_xh']['isf'] = 2;
404
+                    $GLOBALS['_xh']['isf_reason'] = 'missing top level xmlrpc element';
405
+                    return;
406
+                }
407
+                else
408
+                {
409
+                    $GLOBALS['_xh']['rt'] = strtolower($name);
410
+                    $GLOBALS['_xh']['rt'] = strtolower($name);
411
+                }
412
+            }
413
+            else
414
+            {
415
+                // not top level element: see if parent is OK
416
+                $parent = end($GLOBALS['_xh']['stack']);
417
+                if (!array_key_exists($name, $GLOBALS['xmlrpc_valid_parents']) || !in_array($parent, $GLOBALS['xmlrpc_valid_parents'][$name]))
418
+                {
419
+                    $GLOBALS['_xh']['isf'] = 2;
420
+                    $GLOBALS['_xh']['isf_reason'] = "xmlrpc element $name cannot be child of $parent";
421
+                    return;
422
+                }
423
+            }
424
+
425
+            switch($name)
426
+            {
427
+                // optimize for speed switch cases: most common cases first
428
+                case 'VALUE':
429
+                    /// @todo we could check for 2 VALUE elements inside a MEMBER or PARAM element
430
+                    $GLOBALS['_xh']['vt']='value'; // indicator: no value found yet
431
+                    $GLOBALS['_xh']['ac']='';
432
+                    $GLOBALS['_xh']['lv']=1;
433
+                    $GLOBALS['_xh']['php_class']=null;
434
+                    break;
435
+                case 'I4':
436
+                case 'INT':
437
+                case 'STRING':
438
+                case 'BOOLEAN':
439
+                case 'DOUBLE':
440
+                case 'DATETIME.ISO8601':
441
+                case 'BASE64':
442
+                    if ($GLOBALS['_xh']['vt']!='value')
443
+                    {
444
+                        //two data elements inside a value: an error occurred!
445
+                        $GLOBALS['_xh']['isf'] = 2;
446
+                        $GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
447
+                        return;
448
+                    }
449
+                    $GLOBALS['_xh']['ac']=''; // reset the accumulator
450
+                    break;
451
+                case 'STRUCT':
452
+                case 'ARRAY':
453
+                    if ($GLOBALS['_xh']['vt']!='value')
454
+                    {
455
+                        //two data elements inside a value: an error occurred!
456
+                        $GLOBALS['_xh']['isf'] = 2;
457
+                        $GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
458
+                        return;
459
+                    }
460
+                    // create an empty array to hold child values, and push it onto appropriate stack
461
+                    $cur_val = array();
462
+                    $cur_val['values'] = array();
463
+                    $cur_val['type'] = $name;
464
+                    // check for out-of-band information to rebuild php objs
465
+                    // and in case it is found, save it
466
+                    if (@isset($attrs['PHP_CLASS']))
467
+                    {
468
+                        $cur_val['php_class'] = $attrs['PHP_CLASS'];
469
+                    }
470
+                    $GLOBALS['_xh']['valuestack'][] = $cur_val;
471
+                    $GLOBALS['_xh']['vt']='data'; // be prepared for a data element next
472
+                    break;
473
+                case 'DATA':
474
+                    if ($GLOBALS['_xh']['vt']!='data')
475
+                    {
476
+                        //two data elements inside a value: an error occurred!
477
+                        $GLOBALS['_xh']['isf'] = 2;
478
+                        $GLOBALS['_xh']['isf_reason'] = "found two data elements inside an array element";
479
+                        return;
480
+                    }
481
+                case 'METHODCALL':
482
+                case 'METHODRESPONSE':
483
+                case 'PARAMS':
484
+                    // valid elements that add little to processing
485
+                    break;
486
+                case 'METHODNAME':
487
+                case 'NAME':
488
+                    /// @todo we could check for 2 NAME elements inside a MEMBER element
489
+                    $GLOBALS['_xh']['ac']='';
490
+                    break;
491
+                case 'FAULT':
492
+                    $GLOBALS['_xh']['isf']=1;
493
+                    break;
494
+                case 'MEMBER':
495
+                    $GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name']=''; // set member name to null, in case we do not find in the xml later on
496
+                    //$GLOBALS['_xh']['ac']='';
497
+                    // Drop trough intentionally
498
+                case 'PARAM':
499
+                    // clear value type, so we can check later if no value has been passed for this param/member
500
+                    $GLOBALS['_xh']['vt']=null;
501
+                    break;
502
+                case 'NIL':
503
+                case 'EX:NIL':
504
+                    if ($GLOBALS['xmlrpc_null_extension'])
505
+                    {
506
+                        if ($GLOBALS['_xh']['vt']!='value')
507
+                        {
508
+                            //two data elements inside a value: an error occurred!
509
+                            $GLOBALS['_xh']['isf'] = 2;
510
+                            $GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
511
+                            return;
512
+                        }
513
+                        $GLOBALS['_xh']['ac']=''; // reset the accumulator
514
+                        break;
515
+                    }
516
+                    // we do not support the <NIL/> extension, so
517
+                    // drop through intentionally
518
+                default:
519
+                    /// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
520
+                    $GLOBALS['_xh']['isf'] = 2;
521
+                    $GLOBALS['_xh']['isf_reason'] = "found not-xmlrpc xml element $name";
522
+                    break;
523
+            }
524
+
525
+            // Save current element name to stack, to validate nesting
526
+            $GLOBALS['_xh']['stack'][] = $name;
527
+
528
+            /// @todo optimization creep: move this inside the big switch() above
529
+            if($name!='VALUE')
530
+            {
531
+                $GLOBALS['_xh']['lv']=0;
532
+            }
533
+        }
534
+    }
535
+
536
+    /// Used in decoding xml chunks that might represent single xmlrpc values
537
+    function xmlrpc_se_any($parser, $name, $attrs)
538
+    {
539
+        xmlrpc_se($parser, $name, $attrs, true);
540
+    }
541
+
542
+    /// xml parser handler function for close element tags
543
+    function xmlrpc_ee($parser, $name, $rebuild_xmlrpcvals = true)
544
+    {
545
+        if ($GLOBALS['_xh']['isf'] < 2)
546
+        {
547
+            // push this element name from stack
548
+            // NB: if XML validates, correct opening/closing is guaranteed and
549
+            // we do not have to check for $name == $curr_elem.
550
+            // we also checked for proper nesting at start of elements...
551
+            $curr_elem = array_pop($GLOBALS['_xh']['stack']);
552
+
553
+            switch($name)
554
+            {
555
+                case 'VALUE':
556
+                    // This if() detects if no scalar was inside <VALUE></VALUE>
557
+                    if ($GLOBALS['_xh']['vt']=='value')
558
+                    {
559
+                        $GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
560
+                        $GLOBALS['_xh']['vt']=$GLOBALS['xmlrpcString'];
561
+                    }
562
+
563
+                    if ($rebuild_xmlrpcvals)
564
+                    {
565
+                        // build the xmlrpc val out of the data received, and substitute it
566
+                        $temp = new xmlrpcval($GLOBALS['_xh']['value'], $GLOBALS['_xh']['vt']);
567
+                        // in case we got info about underlying php class, save it
568
+                        // in the object we're rebuilding
569
+                        if (isset($GLOBALS['_xh']['php_class']))
570
+                            $temp->_php_class = $GLOBALS['_xh']['php_class'];
571
+                        // check if we are inside an array or struct:
572
+                        // if value just built is inside an array, let's move it into array on the stack
573
+                        $vscount = count($GLOBALS['_xh']['valuestack']);
574
+                        if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type']=='ARRAY')
575
+                        {
576
+                            $GLOBALS['_xh']['valuestack'][$vscount-1]['values'][] = $temp;
577
+                        }
578
+                        else
579
+                        {
580
+                            $GLOBALS['_xh']['value'] = $temp;
581
+                        }
582
+                    }
583
+                    else
584
+                    {
585
+                        /// @todo this needs to treat correctly php-serialized objects,
586
+                        /// since std deserializing is done by php_xmlrpc_decode,
587
+                        /// which we will not be calling...
588
+                        if (isset($GLOBALS['_xh']['php_class']))
589
+                        {
590
+                        }
591
+
592
+                        // check if we are inside an array or struct:
593
+                        // if value just built is inside an array, let's move it into array on the stack
594
+                        $vscount = count($GLOBALS['_xh']['valuestack']);
595
+                        if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type']=='ARRAY')
596
+                        {
597
+                            $GLOBALS['_xh']['valuestack'][$vscount-1]['values'][] = $GLOBALS['_xh']['value'];
598
+                        }
599
+                    }
600
+                    break;
601
+                case 'BOOLEAN':
602
+                case 'I4':
603
+                case 'INT':
604
+                case 'STRING':
605
+                case 'DOUBLE':
606
+                case 'DATETIME.ISO8601':
607
+                case 'BASE64':
608
+                    $GLOBALS['_xh']['vt']=strtolower($name);
609
+                    /// @todo: optimization creep - remove the if/elseif cycle below
610
+                    /// since the case() in which we are already did that
611
+                    if ($name=='STRING')
612
+                    {
613
+                        $GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
614
+                    }
615
+                    elseif ($name=='DATETIME.ISO8601')
616
+                    {
617
+                        if (!preg_match('/^[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $GLOBALS['_xh']['ac']))
618
+                        {
619
+                            error_log('XML-RPC: invalid value received in DATETIME: '.$GLOBALS['_xh']['ac']);
620
+                        }
621
+                        $GLOBALS['_xh']['vt']=$GLOBALS['xmlrpcDateTime'];
622
+                        $GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
623
+                    }
624
+                    elseif ($name=='BASE64')
625
+                    {
626
+                        /// @todo check for failure of base64 decoding / catch warnings
627
+                        $GLOBALS['_xh']['value']=base64_decode($GLOBALS['_xh']['ac']);
628
+                    }
629
+                    elseif ($name=='BOOLEAN')
630
+                    {
631
+                        // special case here: we translate boolean 1 or 0 into PHP
632
+                        // constants true or false.
633
+                        // Strings 'true' and 'false' are accepted, even though the
634
+                        // spec never mentions them (see eg. Blogger api docs)
635
+                        // NB: this simple checks helps a lot sanitizing input, ie no
636
+                        // security problems around here
637
+                        if ($GLOBALS['_xh']['ac']=='1' || strcasecmp($GLOBALS['_xh']['ac'], 'true') == 0)
638
+                        {
639
+                            $GLOBALS['_xh']['value']=true;
640
+                        }
641
+                        else
642
+                        {
643
+                            // log if receiveing something strange, even though we set the value to false anyway
644
+                            if ($GLOBALS['_xh']['ac']!='0' && strcasecmp($GLOBALS['_xh']['ac'], 'false') != 0)
645
+                                error_log('XML-RPC: invalid value received in BOOLEAN: '.$GLOBALS['_xh']['ac']);
646
+                            $GLOBALS['_xh']['value']=false;
647
+                        }
648
+                    }
649
+                    elseif ($name=='DOUBLE')
650
+                    {
651
+                        // we have a DOUBLE
652
+                        // we must check that only 0123456789-.<space> are characters here
653
+                        // NOTE: regexp could be much stricter than this...
654
+                        if (!preg_match('/^[+-eE0123456789 \t.]+$/', $GLOBALS['_xh']['ac']))
655
+                        {
656
+                            /// @todo: find a better way of throwing an error than this!
657
+                            error_log('XML-RPC: non numeric value received in DOUBLE: '.$GLOBALS['_xh']['ac']);
658
+                            $GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
659
+                        }
660
+                        else
661
+                        {
662
+                            // it's ok, add it on
663
+                            $GLOBALS['_xh']['value']=(double)$GLOBALS['_xh']['ac'];
664
+                        }
665
+                    }
666
+                    else
667
+                    {
668
+                        // we have an I4/INT
669
+                        // we must check that only 0123456789-<space> are characters here
670
+                        if (!preg_match('/^[+-]?[0123456789 \t]+$/', $GLOBALS['_xh']['ac']))
671
+                        {
672
+                            /// @todo find a better way of throwing an error than this!
673
+                            error_log('XML-RPC: non numeric value received in INT: '.$GLOBALS['_xh']['ac']);
674
+                            $GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
675
+                        }
676
+                        else
677
+                        {
678
+                            // it's ok, add it on
679
+                            $GLOBALS['_xh']['value']=(int)$GLOBALS['_xh']['ac'];
680
+                        }
681
+                    }
682
+                    //$GLOBALS['_xh']['ac']=''; // is this necessary?
683
+                    $GLOBALS['_xh']['lv']=3; // indicate we've found a value
684
+                    break;
685
+                case 'NAME':
686
+                    $GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name'] = $GLOBALS['_xh']['ac'];
687
+                    break;
688
+                case 'MEMBER':
689
+                    //$GLOBALS['_xh']['ac']=''; // is this necessary?
690
+                    // add to array in the stack the last element built,
691
+                    // unless no VALUE was found
692
+                    if ($GLOBALS['_xh']['vt'])
693
+                    {
694
+                        $vscount = count($GLOBALS['_xh']['valuestack']);
695
+                        $GLOBALS['_xh']['valuestack'][$vscount-1]['values'][$GLOBALS['_xh']['valuestack'][$vscount-1]['name']] = $GLOBALS['_xh']['value'];
696
+                    } else
697
+                        error_log('XML-RPC: missing VALUE inside STRUCT in received xml');
698
+                    break;
699
+                case 'DATA':
700
+                    //$GLOBALS['_xh']['ac']=''; // is this necessary?
701
+                    $GLOBALS['_xh']['vt']=null; // reset this to check for 2 data elements in a row - even if they're empty
702
+                    break;
703
+                case 'STRUCT':
704
+                case 'ARRAY':
705
+                    // fetch out of stack array of values, and promote it to current value
706
+                    $curr_val = array_pop($GLOBALS['_xh']['valuestack']);
707
+                    $GLOBALS['_xh']['value'] = $curr_val['values'];
708
+                    $GLOBALS['_xh']['vt']=strtolower($name);
709
+                    if (isset($curr_val['php_class']))
710
+                    {
711
+                        $GLOBALS['_xh']['php_class'] = $curr_val['php_class'];
712
+                    }
713
+                    break;
714
+                case 'PARAM':
715
+                    // add to array of params the current value,
716
+                    // unless no VALUE was found
717
+                    if ($GLOBALS['_xh']['vt'])
718
+                    {
719
+                        $GLOBALS['_xh']['params'][]=$GLOBALS['_xh']['value'];
720
+                        $GLOBALS['_xh']['pt'][]=$GLOBALS['_xh']['vt'];
721
+                    }
722
+                    else
723
+                        error_log('XML-RPC: missing VALUE inside PARAM in received xml');
724
+                    break;
725
+                case 'METHODNAME':
726
+                    $GLOBALS['_xh']['method']=preg_replace('/^[\n\r\t ]+/', '', $GLOBALS['_xh']['ac']);
727
+                    break;
728
+                case 'NIL':
729
+                case 'EX:NIL':
730
+                    if ($GLOBALS['xmlrpc_null_extension'])
731
+                    {
732
+                        $GLOBALS['_xh']['vt']='null';
733
+                        $GLOBALS['_xh']['value']=null;
734
+                        $GLOBALS['_xh']['lv']=3;
735
+                        break;
736
+                    }
737
+                    // drop through intentionally if nil extension not enabled
738
+                case 'PARAMS':
739
+                case 'FAULT':
740
+                case 'METHODCALL':
741
+                case 'METHORESPONSE':
742
+                    break;
743
+                default:
744
+                    // End of INVALID ELEMENT!
745
+                    // shall we add an assert here for unreachable code???
746
+                    break;
747
+            }
748
+        }
749
+    }
750
+
751
+    /// Used in decoding xmlrpc requests/responses without rebuilding xmlrpc values
752
+    function xmlrpc_ee_fast($parser, $name)
753
+    {
754
+        xmlrpc_ee($parser, $name, false);
755
+    }
756
+
757
+    /// xml parser handler function for character data
758
+    function xmlrpc_cd($parser, $data)
759
+    {
760
+        // skip processing if xml fault already detected
761
+        if ($GLOBALS['_xh']['isf'] < 2)
762
+        {
763
+            // "lookforvalue==3" means that we've found an entire value
764
+            // and should discard any further character data
765
+            if($GLOBALS['_xh']['lv']!=3)
766
+            {
767
+                // G. Giunta 2006-08-23: useless change of 'lv' from 1 to 2
768
+                //if($GLOBALS['_xh']['lv']==1)
769
+                //{
770
+                    // if we've found text and we're just in a <value> then
771
+                    // say we've found a value
772
+                    //$GLOBALS['_xh']['lv']=2;
773
+                //}
774
+                // we always initialize the accumulator before starting parsing, anyway...
775
+                //if(!@isset($GLOBALS['_xh']['ac']))
776
+                //{
777
+                //	$GLOBALS['_xh']['ac'] = '';
778
+                //}
779
+                $GLOBALS['_xh']['ac'].=$data;
780
+            }
781
+        }
782
+    }
783
+
784
+    /// xml parser handler function for 'other stuff', ie. not char data or
785
+    /// element start/end tag. In fact it only gets called on unknown entities...
786
+    function xmlrpc_dh($parser, $data)
787
+    {
788
+        // skip processing if xml fault already detected
789
+        if ($GLOBALS['_xh']['isf'] < 2)
790
+        {
791
+            if(substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
792
+            {
793
+                // G. Giunta 2006-08-25: useless change of 'lv' from 1 to 2
794
+                //if($GLOBALS['_xh']['lv']==1)
795
+                //{
796
+                //	$GLOBALS['_xh']['lv']=2;
797
+                //}
798
+                $GLOBALS['_xh']['ac'].=$data;
799
+            }
800
+        }
801
+        return true;
802
+    }
803
+
804
+    class xmlrpc_client
805
+    {
806
+        var $path;
807
+        var $server;
808
+        var $port=0;
809
+        var $method='http';
810
+        var $errno;
811
+        var $errstr;
812
+        var $debug=0;
813
+        var $username='';
814
+        var $password='';
815
+        var $authtype=1;
816
+        var $cert='';
817
+        var $certpass='';
818
+        var $cacert='';
819
+        var $cacertdir='';
820
+        var $key='';
821
+        var $keypass='';
822
+        var $verifypeer=true;
823
+        var $verifyhost=1;
824
+        var $sslversion=0; // corresponds to CURL_SSLVERSION_DEFAULT
825
+        var $no_multicall=false;
826
+        var $proxy='';
827
+        var $proxyport=0;
828
+        var $proxy_user='';
829
+        var $proxy_pass='';
830
+        var $proxy_authtype=1;
831
+        var $cookies=array();
832
+        var $extracurlopts=array();
833
+
834
+        /**
835
+         * List of http compression methods accepted by the client for responses.
836
+         * NB: PHP supports deflate, gzip compressions out of the box if compiled w. zlib
837
+         *
838
+         * NNB: you can set it to any non-empty array for HTTP11 and HTTPS, since
839
+         * in those cases it will be up to CURL to decide the compression methods
840
+         * it supports. You might check for the presence of 'zlib' in the output of
841
+         * curl_version() to determine wheter compression is supported or not
842
+         */
843
+        var $accepted_compression = array();
844
+        /**
845
+         * Name of compression scheme to be used for sending requests.
846
+         * Either null, gzip or deflate
847
+         */
848
+        var $request_compression = '';
849
+        /**
850
+         * CURL handle: used for keep-alive connections (PHP 4.3.8 up, see:
851
+         * http://curl.haxx.se/docs/faq.html#7.3)
852
+         */
853
+        var $xmlrpc_curl_handle = null;
854
+        /// Whether to use persistent connections for http 1.1 and https
855
+        var $keepalive = false;
856
+        /// Charset encodings that can be decoded without problems by the client
857
+        var $accepted_charset_encodings = array();
858
+        /// Charset encoding to be used in serializing request. NULL = use ASCII
859
+        var $request_charset_encoding = '';
860
+        /**
861
+         * Decides the content of xmlrpcresp objects returned by calls to send()
862
+         * valid strings are 'xmlrpcvals', 'phpvals' or 'xml'
863
+         */
864
+        var $return_type = 'xmlrpcvals';
865
+        /**
866
+         * Sent to servers in http headers
867
+         */
868
+        var $user_agent;
869
+
870
+        /**
871
+         * @param string $path either the complete server URL or the PATH part of the xmlrc server URL, e.g. /xmlrpc/server.php
872
+         * @param string $server the server name / ip address
873
+         * @param integer $port the port the server is listening on, defaults to 80 or 443 depending on protocol used
874
+         * @param string $method the http protocol variant: defaults to 'http', 'https' and 'http11' can be used if CURL is installed
875
+         */
876
+        function __construct($path, $server='', $port='', $method='')
877
+        {
878
+            // allow user to specify all params in $path
879
+            if($server == '' and $port == '' and $method == '')
880
+            {
881
+                $parts = parse_url($path);
882
+                $server = $parts['host'];
883
+                $path = isset($parts['path']) ? $parts['path'] : '';
884
+                if(isset($parts['query']))
885
+                {
886
+                    $path .= '?'.$parts['query'];
887
+                }
888
+                if(isset($parts['fragment']))
889
+                {
890
+                    $path .= '#'.$parts['fragment'];
891
+                }
892
+                if(isset($parts['port']))
893
+                {
894
+                    $port = $parts['port'];
895
+                }
896
+                if(isset($parts['scheme']))
897
+                {
898
+                    $method = $parts['scheme'];
899
+                }
900
+                if(isset($parts['user']))
901
+                {
902
+                    $this->username = $parts['user'];
903
+                }
904
+                if(isset($parts['pass']))
905
+                {
906
+                    $this->password = $parts['pass'];
907
+                }
908
+            }
909
+            if($path == '' || $path[0] != '/')
910
+            {
911
+                $this->path='/'.$path;
912
+            }
913
+            else
914
+            {
915
+                $this->path=$path;
916
+            }
917
+            $this->server=$server;
918
+            if($port != '')
919
+            {
920
+                $this->port=$port;
921
+            }
922
+            if($method != '')
923
+            {
924
+                $this->method=$method;
925
+            }
926
+
927
+            // if ZLIB is enabled, let the client by default accept compressed responses
928
+            if(function_exists('gzinflate') || (
929
+                function_exists('curl_init') && (($info = curl_version()) &&
930
+                ((is_string($info) && strpos($info, 'zlib') !== null) || isset($info['libz_version'])))
931
+            ))
932
+            {
933
+                $this->accepted_compression = array('gzip', 'deflate');
934
+            }
935
+
936
+            // keepalives: enabled by default
937
+            $this->keepalive = true;
938
+
939
+            // by default the xml parser can support these 3 charset encodings
940
+            $this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
941
+
942
+            // initialize user_agent string
943
+            $this->user_agent = $GLOBALS['xmlrpcName'] . ' ' . $GLOBALS['xmlrpcVersion'];
944
+        }
945
+
946
+        /**
947
+         * @deprecated
948
+         */
949
+        function xmlrpc_client($path, $server='', $port='', $method='')
950
+        {
951
+            self::__construct($path, $server, $port, $method);
952
+        }
953
+
954
+        /**
955
+         * Enables/disables the echoing to screen of the xmlrpc responses received
956
+         * @param integer $in values 0, 1 and 2 are supported (2 = echo sent msg too, before received response)
957
+         * @access public
958
+         */
959
+        function setDebug($in)
960
+        {
961
+            $this->debug=$in;
962
+        }
963
+
964
+        /**
965
+         * Add some http BASIC AUTH credentials, used by the client to authenticate
966
+         * @param string $u username
967
+         * @param string $p password
968
+         * @param integer $t auth type. See curl_setopt man page for supported auth types. Defaults to CURLAUTH_BASIC (basic auth)
969
+         * @access public
970
+         */
971
+        function setCredentials($u, $p, $t=1)
972
+        {
973
+            $this->username=$u;
974
+            $this->password=$p;
975
+            $this->authtype=$t;
976
+        }
977
+
978
+        /**
979
+         * Add a client-side https certificate
980
+         * @param string $cert
981
+         * @param string $certpass
982
+         * @access public
983
+         */
984
+        function setCertificate($cert, $certpass)
985
+        {
986
+            $this->cert = $cert;
987
+            $this->certpass = $certpass;
988
+        }
989
+
990
+        /**
991
+         * Add a CA certificate to verify server with (see man page about
992
+         * CURLOPT_CAINFO for more details)
993
+         * @param string $cacert certificate file name (or dir holding certificates)
994
+         * @param bool $is_dir set to true to indicate cacert is a dir. defaults to false
995
+         * @access public
996
+         */
997
+        function setCaCertificate($cacert, $is_dir=false)
998
+        {
999
+            if ($is_dir)
1000
+            {
1001
+                $this->cacertdir = $cacert;
1002
+            }
1003
+            else
1004
+            {
1005
+                $this->cacert = $cacert;
1006
+            }
1007
+        }
1008
+
1009
+        /**
1010
+         * Set attributes for SSL communication: private SSL key
1011
+         * NB: does not work in older php/curl installs
1012
+         * Thanks to Daniel Convissor
1013
+         * @param string $key The name of a file containing a private SSL key
1014
+         * @param string $keypass The secret password needed to use the private SSL key
1015
+         * @access public
1016
+         */
1017
+        function setKey($key, $keypass)
1018
+        {
1019
+            $this->key = $key;
1020
+            $this->keypass = $keypass;
1021
+        }
1022
+
1023
+        /**
1024
+         * Set attributes for SSL communication: verify server certificate
1025
+         * @param bool $i enable/disable verification of peer certificate
1026
+         * @access public
1027
+         */
1028
+        function setSSLVerifyPeer($i)
1029
+        {
1030
+            $this->verifypeer = $i;
1031
+        }
1032
+
1033
+        /**
1034
+         * Set attributes for SSL communication: verify match of server cert w. hostname
1035
+         * @param int $i
1036
+         * @access public
1037
+         */
1038
+        function setSSLVerifyHost($i)
1039
+        {
1040
+            $this->verifyhost = $i;
1041
+        }
1042
+
1043
+        /**
1044
+         * Set attributes for SSL communication: SSL version to use. Best left at 0 (default value ): let cURL decide
1045
+         *
1046
+         * @param int $i
1047
+         */
1048
+        public function setSSLVersion($i)
1049
+        {
1050
+            $this->sslversion = $i;
1051
+        }
1052
+
1053
+        /**
1054
+         * Set proxy info
1055
+         * @param string $proxyhost
1056
+         * @param string $proxyport Defaults to 8080 for HTTP and 443 for HTTPS
1057
+         * @param string $proxyusername Leave blank if proxy has public access
1058
+         * @param string $proxypassword Leave blank if proxy has public access
1059
+         * @param int $proxyauthtype set to constant CURLAUTH_NTLM to use NTLM auth with proxy
1060
+         * @access public
1061
+         */
1062
+        function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 1)
1063
+        {
1064
+            $this->proxy = $proxyhost;
1065
+            $this->proxyport = $proxyport;
1066
+            $this->proxy_user = $proxyusername;
1067
+            $this->proxy_pass = $proxypassword;
1068
+            $this->proxy_authtype = $proxyauthtype;
1069
+        }
1070
+
1071
+        /**
1072
+         * Enables/disables reception of compressed xmlrpc responses.
1073
+         * Note that enabling reception of compressed responses merely adds some standard
1074
+         * http headers to xmlrpc requests. It is up to the xmlrpc server to return
1075
+         * compressed responses when receiving such requests.
1076
+         * @param string $compmethod either 'gzip', 'deflate', 'any' or ''
1077
+         * @access public
1078
+         */
1079
+        function setAcceptedCompression($compmethod)
1080
+        {
1081
+            if ($compmethod == 'any')
1082
+                $this->accepted_compression = array('gzip', 'deflate');
1083
+            else
1084
+                if ($compmethod == false )
1085
+                    $this->accepted_compression = array();
1086
+                else
1087
+                    $this->accepted_compression = array($compmethod);
1088
+        }
1089
+
1090
+        /**
1091
+         * Enables/disables http compression of xmlrpc request.
1092
+         * Take care when sending compressed requests: servers might not support them
1093
+         * (and automatic fallback to uncompressed requests is not yet implemented)
1094
+         * @param string $compmethod either 'gzip', 'deflate' or ''
1095
+         * @access public
1096
+         */
1097
+        function setRequestCompression($compmethod)
1098
+        {
1099
+            $this->request_compression = $compmethod;
1100
+        }
1101
+
1102
+        /**
1103
+         * Adds a cookie to list of cookies that will be sent to server.
1104
+         * NB: setting any param but name and value will turn the cookie into a 'version 1' cookie:
1105
+         * do not do it unless you know what you are doing
1106
+         * @param string $name
1107
+         * @param string $value
1108
+         * @param string $path
1109
+         * @param string $domain
1110
+         * @param int $port
1111
+         * @access public
1112
+         *
1113
+         * @todo check correctness of urlencoding cookie value (copied from php way of doing it...)
1114
+         */
1115
+        function setCookie($name, $value='', $path='', $domain='', $port=null)
1116
+        {
1117
+            $this->cookies[$name]['value'] = urlencode($value);
1118
+            if ($path || $domain || $port)
1119
+            {
1120
+                $this->cookies[$name]['path'] = $path;
1121
+                $this->cookies[$name]['domain'] = $domain;
1122
+                $this->cookies[$name]['port'] = $port;
1123
+                $this->cookies[$name]['version'] = 1;
1124
+            }
1125
+            else
1126
+            {
1127
+                $this->cookies[$name]['version'] = 0;
1128
+            }
1129
+        }
1130
+
1131
+        /**
1132
+         * Directly set cURL options, for extra flexibility
1133
+         * It allows eg. to bind client to a specific IP interface / address
1134
+         * @param array $options
1135
+         */
1136
+        function SetCurlOptions( $options )
1137
+        {
1138
+            $this->extracurlopts = $options;
1139
+        }
1140
+
1141
+        /**
1142
+         * Set user-agent string that will be used by this client instance
1143
+         * in http headers sent to the server
1144
+         */
1145
+        function SetUserAgent( $agentstring )
1146
+        {
1147
+            $this->user_agent = $agentstring;
1148
+        }
1149
+
1150
+        /**
1151
+         * Send an xmlrpc request
1152
+         * @param mixed $msg The message object, or an array of messages for using multicall, or the complete xml representation of a request
1153
+         * @param integer $timeout Connection timeout, in seconds, If unspecified, a platform specific timeout will apply
1154
+         * @param string $method if left unspecified, the http protocol chosen during creation of the object will be used
1155
+         * @return xmlrpcresp
1156
+         * @access public
1157
+         */
1158
+        function& send($msg, $timeout=0, $method='')
1159
+        {
1160
+            // if user deos not specify http protocol, use native method of this client
1161
+            // (i.e. method set during call to constructor)
1162
+            if($method == '')
1163
+            {
1164
+                $method = $this->method;
1165
+            }
1166
+
1167
+            if(is_array($msg))
1168
+            {
1169
+                // $msg is an array of xmlrpcmsg's
1170
+                $r = $this->multicall($msg, $timeout, $method);
1171
+                return $r;
1172
+            }
1173
+            elseif(is_string($msg))
1174
+            {
1175
+                $n = new xmlrpcmsg('');
1176
+                $n->payload = $msg;
1177
+                $msg = $n;
1178
+            }
1179
+
1180
+            // where msg is an xmlrpcmsg
1181
+            $msg->debug=$this->debug;
1182
+
1183
+            if($method == 'https')
1184
+            {
1185
+                $r =& $this->sendPayloadHTTPS(
1186
+                    $msg,
1187
+                    $this->server,
1188
+                    $this->port,
1189
+                    $timeout,
1190
+                    $this->username,
1191
+                    $this->password,
1192
+                    $this->authtype,
1193
+                    $this->cert,
1194
+                    $this->certpass,
1195
+                    $this->cacert,
1196
+                    $this->cacertdir,
1197
+                    $this->proxy,
1198
+                    $this->proxyport,
1199
+                    $this->proxy_user,
1200
+                    $this->proxy_pass,
1201
+                    $this->proxy_authtype,
1202
+                    $this->keepalive,
1203
+                    $this->key,
1204
+                    $this->keypass,
1205
+                    $this->sslversion
1206
+                );
1207
+            }
1208
+            elseif($method == 'http11')
1209
+            {
1210
+                $r =& $this->sendPayloadCURL(
1211
+                    $msg,
1212
+                    $this->server,
1213
+                    $this->port,
1214
+                    $timeout,
1215
+                    $this->username,
1216
+                    $this->password,
1217
+                    $this->authtype,
1218
+                    null,
1219
+                    null,
1220
+                    null,
1221
+                    null,
1222
+                    $this->proxy,
1223
+                    $this->proxyport,
1224
+                    $this->proxy_user,
1225
+                    $this->proxy_pass,
1226
+                    $this->proxy_authtype,
1227
+                    'http',
1228
+                    $this->keepalive
1229
+                );
1230
+            }
1231
+            else
1232
+            {
1233
+                $r =& $this->sendPayloadHTTP10(
1234
+                    $msg,
1235
+                    $this->server,
1236
+                    $this->port,
1237
+                    $timeout,
1238
+                    $this->username,
1239
+                    $this->password,
1240
+                    $this->authtype,
1241
+                    $this->proxy,
1242
+                    $this->proxyport,
1243
+                    $this->proxy_user,
1244
+                    $this->proxy_pass,
1245
+                    $this->proxy_authtype
1246
+                );
1247
+            }
1248
+
1249
+            return $r;
1250
+        }
1251
+
1252
+        /**
1253
+         * @access private
1254
+         */
1255
+        function &sendPayloadHTTP10($msg, $server, $port, $timeout=0,
1256
+            $username='', $password='', $authtype=1, $proxyhost='',
1257
+            $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1)
1258
+        {
1259
+            if($port==0)
1260
+            {
1261
+                $port=80;
1262
+            }
1263
+
1264
+            // Only create the payload if it was not created previously
1265
+            if(empty($msg->payload))
1266
+            {
1267
+                $msg->createPayload($this->request_charset_encoding);
1268
+            }
1269
+
1270
+            $payload = $msg->payload;
1271
+            // Deflate request body and set appropriate request headers
1272
+            if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1273
+            {
1274
+                if($this->request_compression == 'gzip')
1275
+                {
1276
+                    $a = @gzencode($payload);
1277
+                    if($a)
1278
+                    {
1279
+                        $payload = $a;
1280
+                        $encoding_hdr = "Content-Encoding: gzip\r\n";
1281
+                    }
1282
+                }
1283
+                else
1284
+                {
1285
+                    $a = @gzcompress($payload);
1286
+                    if($a)
1287
+                    {
1288
+                        $payload = $a;
1289
+                        $encoding_hdr = "Content-Encoding: deflate\r\n";
1290
+                    }
1291
+                }
1292
+            }
1293
+            else
1294
+            {
1295
+                $encoding_hdr = '';
1296
+            }
1297
+
1298
+            // thanks to Grant Rauscher <[email protected]> for this
1299
+            $credentials='';
1300
+            if($username!='')
1301
+            {
1302
+                $credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n";
1303
+                if ($authtype != 1)
1304
+                {
1305
+                    error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported with HTTP 1.0');
1306
+                }
1307
+            }
1308
+
1309
+            $accepted_encoding = '';
1310
+            if(is_array($this->accepted_compression) && count($this->accepted_compression))
1311
+            {
1312
+                $accepted_encoding = 'Accept-Encoding: ' . implode(', ', $this->accepted_compression) . "\r\n";
1313
+            }
1314
+
1315
+            $proxy_credentials = '';
1316
+            if($proxyhost)
1317
+            {
1318
+                if($proxyport == 0)
1319
+                {
1320
+                    $proxyport = 8080;
1321
+                }
1322
+                $connectserver = $proxyhost;
1323
+                $connectport = $proxyport;
1324
+                $uri = 'http://'.$server.':'.$port.$this->path;
1325
+                if($proxyusername != '')
1326
+                {
1327
+                    if ($proxyauthtype != 1)
1328
+                    {
1329
+                        error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported with HTTP 1.0');
1330
+                    }
1331
+                    $proxy_credentials = 'Proxy-Authorization: Basic ' . base64_encode($proxyusername.':'.$proxypassword) . "\r\n";
1332
+                }
1333
+            }
1334
+            else
1335
+            {
1336
+                $connectserver = $server;
1337
+                $connectport = $port;
1338
+                $uri = $this->path;
1339
+            }
1340
+
1341
+            // Cookie generation, as per rfc2965 (version 1 cookies) or
1342
+            // netscape's rules (version 0 cookies)
1343
+            $cookieheader='';
1344
+            if (count($this->cookies))
1345
+            {
1346
+                $version = '';
1347
+                foreach ($this->cookies as $name => $cookie)
1348
+                {
1349
+                    if ($cookie['version'])
1350
+                    {
1351
+                        $version = ' $Version="' . $cookie['version'] . '";';
1352
+                        $cookieheader .= ' ' . $name . '="' . $cookie['value'] . '";';
1353
+                        if ($cookie['path'])
1354
+                            $cookieheader .= ' $Path="' . $cookie['path'] . '";';
1355
+                        if ($cookie['domain'])
1356
+                            $cookieheader .= ' $Domain="' . $cookie['domain'] . '";';
1357
+                        if ($cookie['port'])
1358
+                            $cookieheader .= ' $Port="' . $cookie['port'] . '";';
1359
+                    }
1360
+                    else
1361
+                    {
1362
+                        $cookieheader .= ' ' . $name . '=' . $cookie['value'] . ";";
1363
+                    }
1364
+                }
1365
+                $cookieheader = 'Cookie:' . $version . substr($cookieheader, 0, -1) . "\r\n";
1366
+            }
1367
+
1368
+            // omit port if 80
1369
+            $port = ($port == 80) ? '' : (':' . $port);
1370
+
1371
+            $op= 'POST ' . $uri. " HTTP/1.0\r\n" .
1372
+                'User-Agent: ' . $this->user_agent . "\r\n" .
1373
+                'Host: '. $server . $port . "\r\n" .
1374
+                $credentials .
1375
+                $proxy_credentials .
1376
+                $accepted_encoding .
1377
+                $encoding_hdr .
1378
+                'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings) . "\r\n" .
1379
+                $cookieheader .
1380
+                'Content-Type: ' . $msg->content_type . "\r\nContent-Length: " .
1381
+                strlen($payload) . "\r\n\r\n" .
1382
+                $payload;
1383
+
1384
+            if($this->debug > 1)
1385
+            {
1386
+                print "<PRE>\n---SENDING---\n" . htmlentities($op) . "\n---END---\n</PRE>";
1387
+                // let the client see this now in case http times out...
1388
+                flush();
1389
+            }
1390
+
1391
+            if($timeout>0)
1392
+            {
1393
+                $fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr, $timeout);
1394
+            }
1395
+            else
1396
+            {
1397
+                $fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr);
1398
+            }
1399
+            if($fp)
1400
+            {
1401
+                if($timeout>0 && function_exists('stream_set_timeout'))
1402
+                {
1403
+                    stream_set_timeout($fp, $timeout);
1404
+                }
1405
+            }
1406
+            else
1407
+            {
1408
+                $this->errstr='Connect error: '.$this->errstr;
1409
+                $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr . ' (' . $this->errno . ')');
1410
+                return $r;
1411
+            }
1412
+
1413
+            if(!fputs($fp, $op, strlen($op)))
1414
+            {
1415
+                fclose($fp);
1416
+                $this->errstr='Write error';
1417
+                $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr);
1418
+                return $r;
1419
+            }
1420
+            else
1421
+            {
1422
+                // reset errno and errstr on successful socket connection
1423
+                $this->errstr = '';
1424
+            }
1425
+            // G. Giunta 2005/10/24: close socket before parsing.
1426
+            // should yield slightly better execution times, and make easier recursive calls (e.g. to follow http redirects)
1427
+            $ipd='';
1428
+            do
1429
+            {
1430
+                // shall we check for $data === FALSE?
1431
+                // as per the manual, it signals an error
1432
+                $ipd.=fread($fp, 32768);
1433
+            } while(!feof($fp));
1434
+            fclose($fp);
1435
+            $r =& $msg->parseResponse($ipd, false, $this->return_type);
1436
+            return $r;
1437
+
1438
+        }
1439
+
1440
+        /**
1441
+         * @access private
1442
+         */
1443
+        function &sendPayloadHTTPS($msg, $server, $port, $timeout=0, $username='',
1444
+            $password='', $authtype=1, $cert='',$certpass='', $cacert='', $cacertdir='',
1445
+            $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1,
1446
+            $keepalive=false, $key='', $keypass='', $sslVersion = 0)
1447
+        {
1448
+            $r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username,
1449
+                $password, $authtype, $cert, $certpass, $cacert, $cacertdir, $proxyhost, $proxyport,
1450
+                $proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass, $sslVersion);
1451
+            return $r;
1452
+        }
1453
+
1454
+        /**
1455
+         * Contributed by Justin Miller <[email protected]>
1456
+         * Requires curl to be built into PHP
1457
+         * NB: CURL versions before 7.11.10 cannot use proxy to talk to https servers!
1458
+         * @access private
1459
+         */
1460
+        function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='',
1461
+            $password='', $authtype=1, $cert='', $certpass='', $cacert='', $cacertdir='',
1462
+            $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $method='https',
1463
+            $keepalive=false, $key='', $keypass='', $sslVersion = 0)
1464
+        {
1465
+            if(!function_exists('curl_init'))
1466
+            {
1467
+                $this->errstr='CURL unavailable on this install';
1468
+                $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_curl'], $GLOBALS['xmlrpcstr']['no_curl']);
1469
+                return $r;
1470
+            }
1471
+            if($method == 'https')
1472
+            {
1473
+                if(($info = curl_version()) &&
1474
+                    ((is_string($info) && strpos($info, 'OpenSSL') === null) || (is_array($info) && !isset($info['ssl_version']))))
1475
+                {
1476
+                    $this->errstr='SSL unavailable on this install';
1477
+                    $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_ssl'], $GLOBALS['xmlrpcstr']['no_ssl']);
1478
+                    return $r;
1479
+                }
1480
+            }
1481
+
1482
+            if($port == 0)
1483
+            {
1484
+                if($method == 'http')
1485
+                {
1486
+                    $port = 80;
1487
+                }
1488
+                else
1489
+                {
1490
+                    $port = 443;
1491
+                }
1492
+            }
1493
+
1494
+            // Only create the payload if it was not created previously
1495
+            if(empty($msg->payload))
1496
+            {
1497
+                $msg->createPayload($this->request_charset_encoding);
1498
+            }
1499
+
1500
+            // Deflate request body and set appropriate request headers
1501
+            $payload = $msg->payload;
1502
+            if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1503
+            {
1504
+                if($this->request_compression == 'gzip')
1505
+                {
1506
+                    $a = @gzencode($payload);
1507
+                    if($a)
1508
+                    {
1509
+                        $payload = $a;
1510
+                        $encoding_hdr = 'Content-Encoding: gzip';
1511
+                    }
1512
+                }
1513
+                else
1514
+                {
1515
+                    $a = @gzcompress($payload);
1516
+                    if($a)
1517
+                    {
1518
+                        $payload = $a;
1519
+                        $encoding_hdr = 'Content-Encoding: deflate';
1520
+                    }
1521
+                }
1522
+            }
1523
+            else
1524
+            {
1525
+                $encoding_hdr = '';
1526
+            }
1527
+
1528
+            if($this->debug > 1)
1529
+            {
1530
+                print "<PRE>\n---SENDING---\n" . htmlentities($payload) . "\n---END---\n</PRE>";
1531
+                // let the client see this now in case http times out...
1532
+                flush();
1533
+            }
1534
+
1535
+            if(!$keepalive || !$this->xmlrpc_curl_handle)
1536
+            {
1537
+                $curl = curl_init($method . '://' . $server . ':' . $port . $this->path);
1538
+                if($keepalive)
1539
+                {
1540
+                    $this->xmlrpc_curl_handle = $curl;
1541
+                }
1542
+            }
1543
+            else
1544
+            {
1545
+                $curl = $this->xmlrpc_curl_handle;
1546
+            }
1547
+
1548
+            // results into variable
1549
+            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
1550
+
1551
+            if($this->debug)
1552
+            {
1553
+                curl_setopt($curl, CURLOPT_VERBOSE, 1);
1554
+            }
1555
+            curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
1556
+            // required for XMLRPC: post the data
1557
+            curl_setopt($curl, CURLOPT_POST, 1);
1558
+            // the data
1559
+            curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
1560
+
1561
+            // return the header too
1562
+            curl_setopt($curl, CURLOPT_HEADER, 1);
1563
+
1564
+            // NB: if we set an empty string, CURL will add http header indicating
1565
+            // ALL methods it is supporting. This is possibly a better option than
1566
+            // letting the user tell what curl can / cannot do...
1567
+            if(is_array($this->accepted_compression) && count($this->accepted_compression))
1568
+            {
1569
+                //curl_setopt($curl, CURLOPT_ENCODING, implode(',', $this->accepted_compression));
1570
+                // empty string means 'any supported by CURL' (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1571
+                if (count($this->accepted_compression) == 1)
1572
+                {
1573
+                    curl_setopt($curl, CURLOPT_ENCODING, $this->accepted_compression[0]);
1574
+                }
1575
+                else
1576
+                    curl_setopt($curl, CURLOPT_ENCODING, '');
1577
+            }
1578
+            // extra headers
1579
+            $headers = array('Content-Type: ' . $msg->content_type , 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings));
1580
+            // if no keepalive is wanted, let the server know it in advance
1581
+            if(!$keepalive)
1582
+            {
1583
+                $headers[] = 'Connection: close';
1584
+            }
1585
+            // request compression header
1586
+            if($encoding_hdr)
1587
+            {
1588
+                $headers[] = $encoding_hdr;
1589
+            }
1590
+
1591
+            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1592
+            // timeout is borked
1593
+            if($timeout)
1594
+            {
1595
+                curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1);
1596
+            }
1597
+
1598
+            if($username && $password)
1599
+            {
1600
+                curl_setopt($curl, CURLOPT_USERPWD, $username.':'.$password);
1601
+                if (defined('CURLOPT_HTTPAUTH'))
1602
+                {
1603
+                    curl_setopt($curl, CURLOPT_HTTPAUTH, $authtype);
1604
+                }
1605
+                else if ($authtype != 1)
1606
+                {
1607
+                    error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported by the current PHP/curl install');
1608
+                }
1609
+            }
1610
+
1611
+            if($method == 'https')
1612
+            {
1613
+                // set cert file
1614
+                if($cert)
1615
+                {
1616
+                    curl_setopt($curl, CURLOPT_SSLCERT, $cert);
1617
+                }
1618
+                // set cert password
1619
+                if($certpass)
1620
+                {
1621
+                    curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $certpass);
1622
+                }
1623
+                // whether to verify remote host's cert
1624
+                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer);
1625
+                // set ca certificates file/dir
1626
+                if($cacert)
1627
+                {
1628
+                    curl_setopt($curl, CURLOPT_CAINFO, $cacert);
1629
+                }
1630
+                if($cacertdir)
1631
+                {
1632
+                    curl_setopt($curl, CURLOPT_CAPATH, $cacertdir);
1633
+                }
1634
+                // set key file (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1635
+                if($key)
1636
+                {
1637
+                    curl_setopt($curl, CURLOPT_SSLKEY, $key);
1638
+                }
1639
+                // set key password (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1640
+                if($keypass)
1641
+                {
1642
+                    curl_setopt($curl, CURLOPT_SSLKEYPASSWD, $keypass);
1643
+                }
1644
+
1645
+                // Upgrade transparently to more stringent check for versions of php which do not support otherwise.
1646
+                // Doing it in constructor would be cleaner; doing it here saves us a couple of function calls
1647
+                if($this->verifyhost == 1 && $info = curl_version() && version_compare($info['version'], '7.28.1') >= 0)
1648
+                {
1649
+                    $this->verifyhost = 2;
1650
+                }
1651
+                // whether to verify cert's common name (CN); 0 for no, 1 to verify that it exists, and 2 to verify that it matches the hostname used
1652
+                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost);
1653
+                // allow usage of different SSL versions
1654
+                curl_setopt($curl, CURLOPT_SSLVERSION, $sslVersion);
1655
+            }
1656
+
1657
+            // proxy info
1658
+            if($proxyhost)
1659
+            {
1660
+                if($proxyport == 0)
1661
+                {
1662
+                    $proxyport = 8080; // NB: even for HTTPS, local connection is on port 8080
1663
+                }
1664
+                curl_setopt($curl, CURLOPT_PROXY, $proxyhost.':'.$proxyport);
1665
+                //curl_setopt($curl, CURLOPT_PROXYPORT,$proxyport);
1666
+                if($proxyusername)
1667
+                {
1668
+                    curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyusername.':'.$proxypassword);
1669
+                    if (defined('CURLOPT_PROXYAUTH'))
1670
+                    {
1671
+                        curl_setopt($curl, CURLOPT_PROXYAUTH, $proxyauthtype);
1672
+                    }
1673
+                    else if ($proxyauthtype != 1)
1674
+                    {
1675
+                        error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported by the current PHP/curl install');
1676
+                    }
1677
+                }
1678
+            }
1679
+
1680
+            // NB: should we build cookie http headers by hand rather than let CURL do it?
1681
+            // the following code does not honour 'expires', 'path' and 'domain' cookie attributes
1682
+            // set to client obj the the user...
1683
+            if (count($this->cookies))
1684
+            {
1685
+                $cookieheader = '';
1686
+                foreach ($this->cookies as $name => $cookie)
1687
+                {
1688
+                    $cookieheader .= $name . '=' . $cookie['value'] . '; ';
1689
+                }
1690
+                curl_setopt($curl, CURLOPT_COOKIE, substr($cookieheader, 0, -2));
1691
+            }
1692
+
1693
+            foreach ($this->extracurlopts as $opt => $val)
1694
+            {
1695
+                curl_setopt($curl, $opt, $val);
1696
+            }
1697
+
1698
+            $result = curl_exec($curl);
1699
+
1700
+            if ($this->debug > 1)
1701
+            {
1702
+                print "<PRE>\n---CURL INFO---\n";
1703
+                foreach(curl_getinfo($curl) as $name => $val)
1704
+                {
1705
+                    if (is_array($val))
1706
+                    {
1707
+                        $val = implode("\n", $val);
1708
+                    }
1709
+                    print $name . ': ' . htmlentities($val) . "\n";
1710
+                }
1711
+
1712
+                print "---END---\n</PRE>";
1713
+            }
1714
+
1715
+            if(!$result) /// @todo we should use a better check here - what if we get back '' or '0'?
1716
+            {
1717
+                $this->errstr='no response';
1718
+                $resp=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['curl_fail'], $GLOBALS['xmlrpcstr']['curl_fail']. ': '. curl_error($curl));
1719
+                curl_close($curl);
1720
+                if($keepalive)
1721
+                {
1722
+                    $this->xmlrpc_curl_handle = null;
1723
+                }
1724
+            }
1725
+            else
1726
+            {
1727
+                if(!$keepalive)
1728
+                {
1729
+                    curl_close($curl);
1730
+                }
1731
+                $resp =& $msg->parseResponse($result, true, $this->return_type);
1732
+                // if we got back a 302, we can not reuse the curl handle for later calls
1733
+                if($resp->faultCode() == $GLOBALS['xmlrpcerr']['http_error'] && $keepalive)
1734
+                {
1735
+                    curl_close($curl);
1736
+                    $this->xmlrpc_curl_handle = null;
1737
+                }
1738
+            }
1739
+            return $resp;
1740
+        }
1741
+
1742
+        /**
1743
+         * Send an array of request messages and return an array of responses.
1744
+         * Unless $this->no_multicall has been set to true, it will try first
1745
+         * to use one single xmlrpc call to server method system.multicall, and
1746
+         * revert to sending many successive calls in case of failure.
1747
+         * This failure is also stored in $this->no_multicall for subsequent calls.
1748
+         * Unfortunately, there is no server error code universally used to denote
1749
+         * the fact that multicall is unsupported, so there is no way to reliably
1750
+         * distinguish between that and a temporary failure.
1751
+         * If you are sure that server supports multicall and do not want to
1752
+         * fallback to using many single calls, set the fourth parameter to FALSE.
1753
+         *
1754
+         * NB: trying to shoehorn extra functionality into existing syntax has resulted
1755
+         * in pretty much convoluted code...
1756
+         *
1757
+         * @param array $msgs an array of xmlrpcmsg objects
1758
+         * @param integer $timeout connection timeout (in seconds)
1759
+         * @param string $method the http protocol variant to be used
1760
+         * @param boolean fallback When true, upon receiving an error during multicall, multiple single calls will be attempted
1761
+         * @return array
1762
+         * @access public
1763
+         */
1764
+        function multicall($msgs, $timeout=0, $method='', $fallback=true)
1765
+        {
1766
+            if ($method == '')
1767
+            {
1768
+                $method = $this->method;
1769
+            }
1770
+            if(!$this->no_multicall)
1771
+            {
1772
+                $results = $this->_try_multicall($msgs, $timeout, $method);
1773
+                if(is_array($results))
1774
+                {
1775
+                    // System.multicall succeeded
1776
+                    return $results;
1777
+                }
1778
+                else
1779
+                {
1780
+                    // either system.multicall is unsupported by server,
1781
+                    // or call failed for some other reason.
1782
+                    if ($fallback)
1783
+                    {
1784
+                        // Don't try it next time...
1785
+                        $this->no_multicall = true;
1786
+                    }
1787
+                    else
1788
+                    {
1789
+                        if (is_a($results, 'xmlrpcresp'))
1790
+                        {
1791
+                            $result = $results;
1792
+                        }
1793
+                        else
1794
+                        {
1795
+                            $result = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['multicall_error'], $GLOBALS['xmlrpcstr']['multicall_error']);
1796
+                        }
1797
+                    }
1798
+                }
1799
+            }
1800
+            else
1801
+            {
1802
+                // override fallback, in case careless user tries to do two
1803
+                // opposite things at the same time
1804
+                $fallback = true;
1805
+            }
1806
+
1807
+            $results = array();
1808
+            if ($fallback)
1809
+            {
1810
+                // system.multicall is (probably) unsupported by server:
1811
+                // emulate multicall via multiple requests
1812
+                foreach($msgs as $msg)
1813
+                {
1814
+                    $results[] =& $this->send($msg, $timeout, $method);
1815
+                }
1816
+            }
1817
+            else
1818
+            {
1819
+                // user does NOT want to fallback on many single calls:
1820
+                // since we should always return an array of responses,
1821
+                // return an array with the same error repeated n times
1822
+                foreach($msgs as $msg)
1823
+                {
1824
+                    $results[] = $result;
1825
+                }
1826
+            }
1827
+            return $results;
1828
+        }
1829
+
1830
+        /**
1831
+         * Attempt to boxcar $msgs via system.multicall.
1832
+         * Returns either an array of xmlrpcreponses, an xmlrpc error response
1833
+         * or false (when received response does not respect valid multicall syntax)
1834
+         * @access private
1835
+         */
1836
+        function _try_multicall($msgs, $timeout, $method)
1837
+        {
1838
+            // Construct multicall message
1839
+            $calls = array();
1840
+            foreach($msgs as $msg)
1841
+            {
1842
+                $call['methodName'] = new xmlrpcval($msg->method(),'string');
1843
+                $numParams = $msg->getNumParams();
1844
+                $params = array();
1845
+                for($i = 0; $i < $numParams; $i++)
1846
+                {
1847
+                    $params[$i] = $msg->getParam($i);
1848
+                }
1849
+                $call['params'] = new xmlrpcval($params, 'array');
1850
+                $calls[] = new xmlrpcval($call, 'struct');
1851
+            }
1852
+            $multicall = new xmlrpcmsg('system.multicall');
1853
+            $multicall->addParam(new xmlrpcval($calls, 'array'));
1854
+
1855
+            // Attempt RPC call
1856
+            $result =& $this->send($multicall, $timeout, $method);
1857
+
1858
+            if($result->faultCode() != 0)
1859
+            {
1860
+                // call to system.multicall failed
1861
+                return $result;
1862
+            }
1863
+
1864
+            // Unpack responses.
1865
+            $rets = $result->value();
1866
+
1867
+            if ($this->return_type == 'xml')
1868
+            {
1869
+                    return $rets;
1870
+            }
1871
+            else if ($this->return_type == 'phpvals')
1872
+            {
1873
+                ///@todo test this code branch...
1874
+                $rets = $result->value();
1875
+                if(!is_array($rets))
1876
+                {
1877
+                    return false;		// bad return type from system.multicall
1878
+                }
1879
+                $numRets = count($rets);
1880
+                if($numRets != count($msgs))
1881
+                {
1882
+                    return false;		// wrong number of return values.
1883
+                }
1884
+
1885
+                $response = array();
1886
+                for($i = 0; $i < $numRets; $i++)
1887
+                {
1888
+                    $val = $rets[$i];
1889
+                    if (!is_array($val)) {
1890
+                        return false;
1891
+                    }
1892
+                    switch(count($val))
1893
+                    {
1894
+                        case 1:
1895
+                            if(!isset($val[0]))
1896
+                            {
1897
+                                return false;		// Bad value
1898
+                            }
1899
+                            // Normal return value
1900
+                            $response[$i] = new xmlrpcresp($val[0], 0, '', 'phpvals');
1901
+                            break;
1902
+                        case 2:
1903
+                            ///	@todo remove usage of @: it is apparently quite slow
1904
+                            $code = @$val['faultCode'];
1905
+                            if(!is_int($code))
1906
+                            {
1907
+                                return false;
1908
+                            }
1909
+                            $str = @$val['faultString'];
1910
+                            if(!is_string($str))
1911
+                            {
1912
+                                return false;
1913
+                            }
1914
+                            $response[$i] = new xmlrpcresp(0, $code, $str);
1915
+                            break;
1916
+                        default:
1917
+                            return false;
1918
+                    }
1919
+                }
1920
+                return $response;
1921
+            }
1922
+            else // return type == 'xmlrpcvals'
1923
+            {
1924
+                $rets = $result->value();
1925
+                if($rets->kindOf() != 'array')
1926
+                {
1927
+                    return false;		// bad return type from system.multicall
1928
+                }
1929
+                $numRets = $rets->arraysize();
1930
+                if($numRets != count($msgs))
1931
+                {
1932
+                    return false;		// wrong number of return values.
1933
+                }
1934
+
1935
+                $response = array();
1936
+                for($i = 0; $i < $numRets; $i++)
1937
+                {
1938
+                    $val = $rets->arraymem($i);
1939
+                    switch($val->kindOf())
1940
+                    {
1941
+                        case 'array':
1942
+                            if($val->arraysize() != 1)
1943
+                            {
1944
+                                return false;		// Bad value
1945
+                            }
1946
+                            // Normal return value
1947
+                            $response[$i] = new xmlrpcresp($val->arraymem(0));
1948
+                            break;
1949
+                        case 'struct':
1950
+                            $code = $val->structmem('faultCode');
1951
+                            if($code->kindOf() != 'scalar' || $code->scalartyp() != 'int')
1952
+                            {
1953
+                                return false;
1954
+                            }
1955
+                            $str = $val->structmem('faultString');
1956
+                            if($str->kindOf() != 'scalar' || $str->scalartyp() != 'string')
1957
+                            {
1958
+                                return false;
1959
+                            }
1960
+                            $response[$i] = new xmlrpcresp(0, $code->scalarval(), $str->scalarval());
1961
+                            break;
1962
+                        default:
1963
+                            return false;
1964
+                    }
1965
+                }
1966
+                return $response;
1967
+            }
1968
+        }
1969
+    } // end class xmlrpc_client
1970
+
1971
+    class xmlrpcresp
1972
+    {
1973
+        var $val = 0;
1974
+        var $valtyp;
1975
+        var $errno = 0;
1976
+        var $errstr = '';
1977
+        var $payload;
1978
+        var $hdrs = array();
1979
+        var $_cookies = array();
1980
+        var $content_type = 'text/xml';
1981
+        var $raw_data = '';
1982
+
1983
+        /**
1984
+         * @param mixed $val either an xmlrpcval obj, a php value or the xml serialization of an xmlrpcval (a string)
1985
+         * @param integer $fcode set it to anything but 0 to create an error response
1986
+         * @param string $fstr the error string, in case of an error response
1987
+         * @param string $valtyp either 'xmlrpcvals', 'phpvals' or 'xml'
1988
+         *
1989
+         * @todo add check that $val / $fcode / $fstr is of correct type???
1990
+         * NB: as of now we do not do it, since it might be either an xmlrpcval or a plain
1991
+         * php val, or a complete xml chunk, depending on usage of xmlrpc_client::send() inside which creator is called...
1992
+         */
1993
+        function __construct($val, $fcode = 0, $fstr = '', $valtyp='')
1994
+        {
1995
+            if($fcode != 0)
1996
+            {
1997
+                // error response
1998
+                $this->errno = $fcode;
1999
+                $this->errstr = $fstr;
2000
+                //$this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later.
2001
+            }
2002
+            else
2003
+            {
2004
+                // successful response
2005
+                $this->val = $val;
2006
+                if ($valtyp == '')
2007
+                {
2008
+                    // user did not declare type of response value: try to guess it
2009
+                    if (is_object($this->val) && is_a($this->val, 'xmlrpcval'))
2010
+                    {
2011
+                        $this->valtyp = 'xmlrpcvals';
2012
+                    }
2013
+                    else if (is_string($this->val))
2014
+                    {
2015
+                        $this->valtyp = 'xml';
2016
+
2017
+                    }
2018
+                    else
2019
+                    {
2020
+                        $this->valtyp = 'phpvals';
2021
+                    }
2022
+                }
2023
+                else
2024
+                {
2025
+                    // user declares type of resp value: believe him
2026
+                    $this->valtyp = $valtyp;
2027
+                }
2028
+            }
2029
+        }
2030
+
2031
+        /**
2032
+         * @deprecated
2033
+         */
2034
+        function xmlrpcresp($val, $fcode = 0, $fstr = '', $valtyp='')
2035
+        {
2036
+            self::__construct($val, $fcode, $fstr, $valtyp);
2037
+        }
2038
+
2039
+        /**
2040
+         * Returns the error code of the response.
2041
+         * @return integer the error code of this response (0 for not-error responses)
2042
+         * @access public
2043
+         */
2044
+        function faultCode()
2045
+        {
2046
+            return $this->errno;
2047
+        }
2048
+
2049
+        /**
2050
+         * Returns the error code of the response.
2051
+         * @return string the error string of this response ('' for not-error responses)
2052
+         * @access public
2053
+         */
2054
+        function faultString()
2055
+        {
2056
+            return $this->errstr;
2057
+        }
2058
+
2059
+        /**
2060
+         * Returns the value received by the server.
2061
+         * @return mixed the xmlrpcval object returned by the server. Might be an xml string or php value if the response has been created by specially configured xmlrpc_client objects
2062
+         * @access public
2063
+         */
2064
+        function value()
2065
+        {
2066
+            return $this->val;
2067
+        }
2068
+
2069
+        /**
2070
+         * Returns an array with the cookies received from the server.
2071
+         * Array has the form: $cookiename => array ('value' => $val, $attr1 => $val1, $attr2 = $val2, ...)
2072
+         * with attributes being e.g. 'expires', 'path', domain'.
2073
+         * NB: cookies sent as 'expired' by the server (i.e. with an expiry date in the past)
2074
+         * are still present in the array. It is up to the user-defined code to decide
2075
+         * how to use the received cookies, and whether they have to be sent back with the next
2076
+         * request to the server (using xmlrpc_client::setCookie) or not
2077
+         * @return array array of cookies received from the server
2078
+         * @access public
2079
+         */
2080
+        function cookies()
2081
+        {
2082
+            return $this->_cookies;
2083
+        }
2084
+
2085
+        /**
2086
+         * Returns xml representation of the response. XML prologue not included
2087
+         * @param string $charset_encoding the charset to be used for serialization. if null, US-ASCII is assumed
2088
+         * @return string the xml representation of the response
2089
+         * @access public
2090
+         */
2091
+        function serialize($charset_encoding='')
2092
+        {
2093
+            if ($charset_encoding != '')
2094
+                $this->content_type = 'text/xml; charset=' . $charset_encoding;
2095
+            else
2096
+                $this->content_type = 'text/xml';
2097
+            if ($GLOBALS['xmlrpc_null_apache_encoding'])
2098
+            {
2099
+                $result = "<methodResponse xmlns:ex=\"".$GLOBALS['xmlrpc_null_apache_encoding_ns']."\">\n";
2100
+            }
2101
+            else
2102
+            {
2103
+            $result = "<methodResponse>\n";
2104
+            }
2105
+            if($this->errno)
2106
+            {
2107
+                // G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients
2108
+                // by xml-encoding non ascii chars
2109
+                $result .= "<fault>\n" .
2110 2110
 "<value>\n<struct><member><name>faultCode</name>\n<value><int>" . $this->errno .
2111 2111
 "</int></value>\n</member>\n<member>\n<name>faultString</name>\n<value><string>" .
2112 2112
 xmlrpc_encode_entitites($this->errstr, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "</string></value>\n</member>\n" .
2113 2113
 "</struct>\n</value>\n</fault>";
2114
-			}
2115
-			else
2116
-			{
2117
-				if(!is_object($this->val) || !is_a($this->val, 'xmlrpcval'))
2118
-				{
2119
-					if (is_string($this->val) && $this->valtyp == 'xml')
2120
-					{
2121
-						$result .= "<params>\n<param>\n" .
2122
-							$this->val .
2123
-							"</param>\n</params>";
2124
-					}
2125
-					else
2126
-					{
2127
-						/// @todo try to build something serializable?
2128
-						die('cannot serialize xmlrpcresp objects whose content is native php values');
2129
-					}
2130
-				}
2131
-				else
2132
-				{
2133
-					$result .= "<params>\n<param>\n" .
2134
-						$this->val->serialize($charset_encoding) .
2135
-						"</param>\n</params>";
2136
-				}
2137
-			}
2138
-			$result .= "\n</methodResponse>";
2139
-			$this->payload = $result;
2140
-			return $result;
2141
-		}
2142
-	}
2143
-
2144
-	class xmlrpcmsg
2145
-	{
2146
-		var $payload;
2147
-		var $methodname;
2148
-		var $params=array();
2149
-		var $debug=0;
2150
-		var $content_type = 'text/xml';
2151
-
2152
-		/**
2153
-		* @param string $meth the name of the method to invoke
2154
-		* @param array $pars array of parameters to be passed to the method (xmlrpcval objects)
2155
-		*/
2156
-		function __construct($meth, $pars=0)
2157
-		{
2158
-			$this->methodname=$meth;
2159
-			if(is_array($pars) && count($pars)>0)
2160
-			{
2161
-				for($i=0; $i<count($pars); $i++)
2162
-				{
2163
-					$this->addParam($pars[$i]);
2164
-				}
2165
-			}
2166
-		}
2167
-
2168
-				/**
2169
-		* @deprecated
2170
-		*/
2171
-		function xmlrpcmsg($meth, $pars=0)
2172
-		{
2173
-			self::__construct($meth, $pars);
2174
-		}
2175
-
2176
-		/**
2177
-		* @access private
2178
-		*/
2179
-		function xml_header($charset_encoding='')
2180
-		{
2181
-			if ($charset_encoding != '')
2182
-			{
2183
-				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\" ?" . ">\n<methodCall>\n";
2184
-			}
2185
-			else
2186
-			{
2187
-				return "<?xml version=\"1.0\"?" . ">\n<methodCall>\n";
2188
-			}
2189
-		}
2190
-
2191
-		/**
2192
-		* @access private
2193
-		*/
2194
-		function xml_footer()
2195
-		{
2196
-			return '</methodCall>';
2197
-		}
2198
-
2199
-		/**
2200
-		* @access private
2201
-		*/
2202
-		function kindOf()
2203
-		{
2204
-			return 'msg';
2205
-		}
2206
-
2207
-		/**
2208
-		* @access private
2209
-		*/
2210
-		function createPayload($charset_encoding='')
2211
-		{
2212
-			if ($charset_encoding != '')
2213
-				$this->content_type = 'text/xml; charset=' . $charset_encoding;
2214
-			else
2215
-				$this->content_type = 'text/xml';
2216
-			$this->payload=$this->xml_header($charset_encoding);
2217
-			$this->payload.='<methodName>' . xmlrpc_encode_entitites($this->methodname, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "</methodName>\n";
2218
-			$this->payload.="<params>\n";
2219
-			for($i=0; $i<count($this->params); $i++)
2220
-			{
2221
-				$p=$this->params[$i];
2222
-				$this->payload.="<param>\n" . $p->serialize($charset_encoding) .
2223
-				"</param>\n";
2224
-			}
2225
-			$this->payload.="</params>\n";
2226
-			$this->payload.=$this->xml_footer();
2227
-		}
2228
-
2229
-		/**
2230
-		* Gets/sets the xmlrpc method to be invoked
2231
-		* @param string $meth the method to be set (leave empty not to set it)
2232
-		* @return string the method that will be invoked
2233
-		* @access public
2234
-		*/
2235
-		function method($meth='')
2236
-		{
2237
-			if($meth!='')
2238
-			{
2239
-				$this->methodname=$meth;
2240
-			}
2241
-			return $this->methodname;
2242
-		}
2243
-
2244
-		/**
2245
-		* Returns xml representation of the message. XML prologue included
2246
-		* @param string $charset_encoding
2247
-		* @return string the xml representation of the message, xml prologue included
2248
-		* @access public
2249
-		*/
2250
-		function serialize($charset_encoding='')
2251
-		{
2252
-			$this->createPayload($charset_encoding);
2253
-			return $this->payload;
2254
-		}
2255
-
2256
-		/**
2257
-		* Add a parameter to the list of parameters to be used upon method invocation
2258
-		* @param xmlrpcval $par
2259
-		* @return boolean false on failure
2260
-		* @access public
2261
-		*/
2262
-		function addParam($par)
2263
-		{
2264
-			// add check: do not add to self params which are not xmlrpcvals
2265
-			if(is_object($par) && is_a($par, 'xmlrpcval'))
2266
-			{
2267
-				$this->params[]=$par;
2268
-				return true;
2269
-			}
2270
-			else
2271
-			{
2272
-				return false;
2273
-			}
2274
-		}
2275
-
2276
-		/**
2277
-		* Returns the nth parameter in the message. The index zero-based.
2278
-		* @param integer $i the index of the parameter to fetch (zero based)
2279
-		* @return xmlrpcval the i-th parameter
2280
-		* @access public
2281
-		*/
2282
-		function getParam($i) { return $this->params[$i]; }
2283
-
2284
-		/**
2285
-		* Returns the number of parameters in the messge.
2286
-		* @return integer the number of parameters currently set
2287
-		* @access public
2288
-		*/
2289
-		function getNumParams() { return count($this->params); }
2290
-
2291
-		/**
2292
-		* Given an open file handle, read all data available and parse it as axmlrpc response.
2293
-		* NB: the file handle is not closed by this function.
2294
-		* NNB: might have trouble in rare cases to work on network streams, as we
2295
-		*      check for a read of 0 bytes instead of feof($fp).
2296
-		*      But since checking for feof(null) returns false, we would risk an
2297
-		*      infinite loop in that case, because we cannot trust the caller
2298
-		*      to give us a valid pointer to an open file...
2299
-		* @access public
2300
-		* @param resource $fp stream pointer
2301
-		* @return xmlrpcresp
2302
-		* @todo add 2nd & 3rd param to be passed to ParseResponse() ???
2303
-		*/
2304
-		function &parseResponseFile($fp)
2305
-		{
2306
-			$ipd='';
2307
-			while($data=fread($fp, 32768))
2308
-			{
2309
-				$ipd.=$data;
2310
-			}
2311
-			//fclose($fp);
2312
-			$r =& $this->parseResponse($ipd);
2313
-			return $r;
2314
-		}
2315
-
2316
-		/**
2317
-		* Parses HTTP headers and separates them from data.
2318
-		* @access private
2319
-		*/
2320
-		function &parseResponseHeaders(&$data, $headers_processed=false)
2321
-		{
2322
-				// Support "web-proxy-tunelling" connections for https through proxies
2323
-				if(preg_match('/^HTTP\/1\.[0-1] 200 Connection established/', $data))
2324
-				{
2325
-					// Look for CR/LF or simple LF as line separator,
2326
-					// (even though it is not valid http)
2327
-					$pos = strpos($data,"\r\n\r\n");
2328
-					if($pos || is_int($pos))
2329
-					{
2330
-						$bd = $pos+4;
2331
-					}
2332
-					else
2333
-					{
2334
-						$pos = strpos($data,"\n\n");
2335
-						if($pos || is_int($pos))
2336
-						{
2337
-							$bd = $pos+2;
2338
-						}
2339
-						else
2340
-						{
2341
-							// No separation between response headers and body: fault?
2342
-							$bd = 0;
2343
-						}
2344
-					}
2345
-					if ($bd)
2346
-					{
2347
-						// this filters out all http headers from proxy.
2348
-						// maybe we could take them into account, too?
2349
-						$data = substr($data, $bd);
2350
-					}
2351
-					else
2352
-					{
2353
-						error_log('XML-RPC: '.__METHOD__.': HTTPS via proxy error, tunnel connection possibly failed');
2354
-						$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (HTTPS via proxy error, tunnel connection possibly failed)');
2355
-						return $r;
2356
-					}
2357
-				}
2358
-
2359
-				// Strip HTTP 1.1 100 Continue header if present
2360
-				while(preg_match('/^HTTP\/1\.1 1[0-9]{2} /', $data))
2361
-				{
2362
-					$pos = strpos($data, 'HTTP', 12);
2363
-					// server sent a Continue header without any (valid) content following...
2364
-					// give the client a chance to know it
2365
-					if(!$pos && !is_int($pos)) // works fine in php 3, 4 and 5
2366
-					{
2367
-						break;
2368
-					}
2369
-					$data = substr($data, $pos);
2370
-				}
2371
-				if(!preg_match('/^HTTP\/[0-9.]+ 200 /', $data))
2372
-				{
2373
-					$errstr= substr($data, 0, strpos($data, "\n")-1);
2374
-					error_log('XML-RPC: '.__METHOD__.': HTTP error, got response: ' .$errstr);
2375
-					$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (' . $errstr . ')');
2376
-					return $r;
2377
-				}
2378
-
2379
-				$GLOBALS['_xh']['headers'] = array();
2380
-				$GLOBALS['_xh']['cookies'] = array();
2381
-
2382
-				// be tolerant to usage of \n instead of \r\n to separate headers and data
2383
-				// (even though it is not valid http)
2384
-				$pos = strpos($data,"\r\n\r\n");
2385
-				if($pos || is_int($pos))
2386
-				{
2387
-					$bd = $pos+4;
2388
-				}
2389
-				else
2390
-				{
2391
-					$pos = strpos($data,"\n\n");
2392
-					if($pos || is_int($pos))
2393
-					{
2394
-						$bd = $pos+2;
2395
-					}
2396
-					else
2397
-					{
2398
-						// No separation between response headers and body: fault?
2399
-						// we could take some action here instead of going on...
2400
-						$bd = 0;
2401
-					}
2402
-				}
2403
-				// be tolerant to line endings, and extra empty lines
2404
-				$ar = preg_split("/\r?\n/", trim(substr($data, 0, $pos)));
2405
-				while(list(,$line) = @each($ar))
2406
-				{
2407
-					// take care of multi-line headers and cookies
2408
-					$arr = explode(':',$line,2);
2409
-					if(count($arr) > 1)
2410
-					{
2411
-						$header_name = strtolower(trim($arr[0]));
2412
-						/// @todo some other headers (the ones that allow a CSV list of values)
2413
-						/// do allow many values to be passed using multiple header lines.
2414
-						/// We should add content to $GLOBALS['_xh']['headers'][$header_name]
2415
-						/// instead of replacing it for those...
2416
-						if ($header_name == 'set-cookie' || $header_name == 'set-cookie2')
2417
-						{
2418
-							if ($header_name == 'set-cookie2')
2419
-							{
2420
-								// version 2 cookies:
2421
-								// there could be many cookies on one line, comma separated
2422
-								$cookies = explode(',', $arr[1]);
2423
-							}
2424
-							else
2425
-							{
2426
-								$cookies = array($arr[1]);
2427
-							}
2428
-							foreach ($cookies as $cookie)
2429
-							{
2430
-								// glue together all received cookies, using a comma to separate them
2431
-								// (same as php does with getallheaders())
2432
-								if (isset($GLOBALS['_xh']['headers'][$header_name]))
2433
-									$GLOBALS['_xh']['headers'][$header_name] .= ', ' . trim($cookie);
2434
-								else
2435
-									$GLOBALS['_xh']['headers'][$header_name] = trim($cookie);
2436
-								// parse cookie attributes, in case user wants to correctly honour them
2437
-								// feature creep: only allow rfc-compliant cookie attributes?
2438
-								// @todo support for server sending multiple time cookie with same name, but using different PATHs
2439
-								$cookie = explode(';', $cookie);
2440
-								foreach ($cookie as $pos => $val)
2441
-								{
2442
-									$val = explode('=', $val, 2);
2443
-									$tag = trim($val[0]);
2444
-									$val = trim(@$val[1]);
2445
-									/// @todo with version 1 cookies, we should strip leading and trailing " chars
2446
-									if ($pos == 0)
2447
-									{
2448
-										$cookiename = $tag;
2449
-										$GLOBALS['_xh']['cookies'][$tag] = array();
2450
-										$GLOBALS['_xh']['cookies'][$cookiename]['value'] = urldecode($val);
2451
-									}
2452
-									else
2453
-									{
2454
-										if ($tag != 'value')
2455
-										{
2456
-											$GLOBALS['_xh']['cookies'][$cookiename][$tag] = $val;
2457
-										}
2458
-									}
2459
-								}
2460
-							}
2461
-						}
2462
-						else
2463
-						{
2464
-							$GLOBALS['_xh']['headers'][$header_name] = trim($arr[1]);
2465
-						}
2466
-					}
2467
-					elseif(isset($header_name))
2468
-					{
2469
-						///	@todo version1 cookies might span multiple lines, thus breaking the parsing above
2470
-						$GLOBALS['_xh']['headers'][$header_name] .= ' ' . trim($line);
2471
-					}
2472
-				}
2473
-
2474
-				$data = substr($data, $bd);
2475
-
2476
-				if($this->debug && count($GLOBALS['_xh']['headers']))
2477
-				{
2478
-					print '<PRE>';
2479
-					foreach($GLOBALS['_xh']['headers'] as $header => $value)
2480
-					{
2481
-						print htmlentities("HEADER: $header: $value\n");
2482
-					}
2483
-					foreach($GLOBALS['_xh']['cookies'] as $header => $value)
2484
-					{
2485
-						print htmlentities("COOKIE: $header={$value['value']}\n");
2486
-					}
2487
-					print "</PRE>\n";
2488
-				}
2489
-
2490
-				// if CURL was used for the call, http headers have been processed,
2491
-				// and dechunking + reinflating have been carried out
2492
-				if(!$headers_processed)
2493
-				{
2494
-					// Decode chunked encoding sent by http 1.1 servers
2495
-					if(isset($GLOBALS['_xh']['headers']['transfer-encoding']) && $GLOBALS['_xh']['headers']['transfer-encoding'] == 'chunked')
2496
-					{
2497
-						if(!$data = decode_chunked($data))
2498
-						{
2499
-							error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to rebuild the chunked data received from server');
2500
-							$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['dechunk_fail'], $GLOBALS['xmlrpcstr']['dechunk_fail']);
2501
-							return $r;
2502
-						}
2503
-					}
2504
-
2505
-					// Decode gzip-compressed stuff
2506
-					// code shamelessly inspired from nusoap library by Dietrich Ayala
2507
-					if(isset($GLOBALS['_xh']['headers']['content-encoding']))
2508
-					{
2509
-						$GLOBALS['_xh']['headers']['content-encoding'] = str_replace('x-', '', $GLOBALS['_xh']['headers']['content-encoding']);
2510
-						if($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' || $GLOBALS['_xh']['headers']['content-encoding'] == 'gzip')
2511
-						{
2512
-							// if decoding works, use it. else assume data wasn't gzencoded
2513
-							if(function_exists('gzinflate'))
2514
-							{
2515
-								if($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data))
2516
-								{
2517
-									$data = $degzdata;
2518
-									if($this->debug)
2519
-									print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n" . htmlentities($data) . "\n---END---</PRE>";
2520
-								}
2521
-								elseif($GLOBALS['_xh']['headers']['content-encoding'] == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
2522
-								{
2523
-									$data = $degzdata;
2524
-									if($this->debug)
2525
-									print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n" . htmlentities($data) . "\n---END---</PRE>";
2526
-								}
2527
-								else
2528
-								{
2529
-									error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to decode the deflated data received from server');
2530
-									$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['decompress_fail'], $GLOBALS['xmlrpcstr']['decompress_fail']);
2531
-									return $r;
2532
-								}
2533
-							}
2534
-							else
2535
-							{
2536
-								error_log('XML-RPC: '.__METHOD__.': the server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');
2537
-								$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['cannot_decompress'], $GLOBALS['xmlrpcstr']['cannot_decompress']);
2538
-								return $r;
2539
-							}
2540
-						}
2541
-					}
2542
-				} // end of 'if needed, de-chunk, re-inflate response'
2543
-
2544
-				// real stupid hack to avoid PHP complaining about returning NULL by ref
2545
-				$r = null;
2546
-				$r =& $r;
2547
-				return $r;
2548
-		}
2549
-
2550
-		/**
2551
-		* Parse the xmlrpc response contained in the string $data and return an xmlrpcresp object.
2552
-		* @param string $data the xmlrpc response, eventually including http headers
2553
-		* @param bool $headers_processed when true prevents parsing HTTP headers for interpretation of content-encoding and consequent decoding
2554
-		* @param string $return_type decides return type, i.e. content of response->value(). Either 'xmlrpcvals', 'xml' or 'phpvals'
2555
-		* @return xmlrpcresp
2556
-		* @access public
2557
-		*/
2558
-		function &parseResponse($data='', $headers_processed=false, $return_type='xmlrpcvals')
2559
-		{
2560
-			if($this->debug)
2561
-			{
2562
-				//by maHo, replaced htmlspecialchars with htmlentities
2563
-				print "<PRE>---GOT---\n" . htmlentities($data) . "\n---END---\n</PRE>";
2564
-			}
2565
-
2566
-			if($data == '')
2567
-			{
2568
-				error_log('XML-RPC: '.__METHOD__.': no response received from server.');
2569
-				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_data'], $GLOBALS['xmlrpcstr']['no_data']);
2570
-				return $r;
2571
-			}
2572
-
2573
-			$GLOBALS['_xh']=array();
2574
-
2575
-			$raw_data = $data;
2576
-			// parse the HTTP headers of the response, if present, and separate them from data
2577
-			if(substr($data, 0, 4) == 'HTTP')
2578
-			{
2579
-				$r =& $this->parseResponseHeaders($data, $headers_processed);
2580
-				if ($r)
2581
-				{
2582
-					// failed processing of HTTP response headers
2583
-					// save into response obj the full payload received, for debugging
2584
-					$r->raw_data = $data;
2585
-					return $r;
2586
-				}
2587
-			}
2588
-			else
2589
-			{
2590
-				$GLOBALS['_xh']['headers'] = array();
2591
-				$GLOBALS['_xh']['cookies'] = array();
2592
-			}
2593
-
2594
-			if($this->debug)
2595
-			{
2596
-				$start = strpos($data, '<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
2597
-				if ($start)
2598
-				{
2599
-					$start += strlen('<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
2600
-					$end = strpos($data, '-->', $start);
2601
-					$comments = substr($data, $start, $end-$start);
2602
-					print "<PRE>---SERVER DEBUG INFO (DECODED) ---\n\t".htmlentities(str_replace("\n", "\n\t", base64_decode($comments)))."\n---END---\n</PRE>";
2603
-				}
2604
-			}
2605
-
2606
-			// be tolerant of extra whitespace in response body
2607
-			$data = trim($data);
2608
-
2609
-			/// @todo return an error msg if $data=='' ?
2610
-
2611
-			// be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts)
2612
-			// idea from Luca Mariano <[email protected]> originally in PEARified version of the lib
2613
-			$pos = strrpos($data, '</methodResponse>');
2614
-			if($pos !== false)
2615
-			{
2616
-				$data = substr($data, 0, $pos+17);
2617
-			}
2618
-
2619
-			// if user wants back raw xml, give it to him
2620
-			if ($return_type == 'xml')
2621
-			{
2622
-				$r = new xmlrpcresp($data, 0, '', 'xml');
2623
-				$r->hdrs = $GLOBALS['_xh']['headers'];
2624
-				$r->_cookies = $GLOBALS['_xh']['cookies'];
2625
-				$r->raw_data = $raw_data;
2626
-				return $r;
2627
-			}
2628
-
2629
-			// try to 'guestimate' the character encoding of the received response
2630
-			$resp_encoding = guess_encoding(@$GLOBALS['_xh']['headers']['content-type'], $data);
2631
-
2632
-			$GLOBALS['_xh']['ac']='';
2633
-			//$GLOBALS['_xh']['qt']=''; //unused...
2634
-			$GLOBALS['_xh']['stack'] = array();
2635
-			$GLOBALS['_xh']['valuestack'] = array();
2636
-			$GLOBALS['_xh']['isf']=0; // 0 = OK, 1 for xmlrpc fault responses, 2 = invalid xmlrpc
2637
-			$GLOBALS['_xh']['isf_reason']='';
2638
-			$GLOBALS['_xh']['rt']=''; // 'methodcall or 'methodresponse'
2639
-
2640
-			// Since parsing will fail if charset is not specified in the xml prologue,
2641
-			// the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
2642
-			// The following code might be better for mb_string enabled installs, but
2643
-			// makes the lib about 200% slower...
2644
-			//if (!is_valid_charset($resp_encoding, array('UTF-8')))
2645
-			if (!in_array($resp_encoding, array('UTF-8', 'US-ASCII')) && !has_encoding($data)) {
2646
-				if ($resp_encoding == 'ISO-8859-1') {
2647
-					$data = utf8_encode($data);
2648
-				} else {
2649
-					if (extension_loaded('mbstring')) {
2650
-						$data = mb_convert_encoding($data, 'UTF-8', $resp_encoding);
2651
-					} else {
2652
-						error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $resp_encoding);
2653
-					}
2654
-				}
2655
-			}
2656
-
2657
-			$parser = xml_parser_create();
2658
-			xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
2659
-			// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
2660
-			// the xml parser to give us back data in the expected charset.
2661
-			// What if internal encoding is not in one of the 3 allowed?
2662
-			// we use the broadest one, ie. utf8
2663
-			// This allows to send data which is native in various charset,
2664
-			// by extending xmlrpc_encode_entitites() and setting xmlrpc_internalencoding
2665
-			if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
2666
-			{
2667
-				xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
2668
-			}
2669
-			else
2670
-			{
2671
-				xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
2672
-			}
2673
-
2674
-			if ($return_type == 'phpvals')
2675
-			{
2676
-				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast');
2677
-			}
2678
-			else
2679
-			{
2680
-				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
2681
-			}
2682
-
2683
-			xml_set_character_data_handler($parser, 'xmlrpc_cd');
2684
-			xml_set_default_handler($parser, 'xmlrpc_dh');
2685
-
2686
-			// first error check: xml not well formed
2687
-			if(!xml_parse($parser, $data, 1))
2688
-			{
2689
-				// thanks to Peter Kocks <[email protected]>
2690
-				if((xml_get_current_line_number($parser)) == 1)
2691
-				{
2692
-					$errstr = 'XML error at line 1, check URL';
2693
-				}
2694
-				else
2695
-				{
2696
-					$errstr = sprintf('XML error: %s at line %d, column %d',
2697
-						xml_error_string(xml_get_error_code($parser)),
2698
-						xml_get_current_line_number($parser), xml_get_current_column_number($parser));
2699
-				}
2700
-				error_log($errstr);
2701
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcstr']['invalid_return'].' ('.$errstr.')');
2702
-				xml_parser_free($parser);
2703
-				if($this->debug)
2704
-				{
2705
-					print $errstr;
2706
-				}
2707
-				$r->hdrs = $GLOBALS['_xh']['headers'];
2708
-				$r->_cookies = $GLOBALS['_xh']['cookies'];
2709
-				$r->raw_data = $raw_data;
2710
-				return $r;
2711
-			}
2712
-			xml_parser_free($parser);
2713
-			// second error check: xml well formed but not xml-rpc compliant
2714
-			if ($GLOBALS['_xh']['isf'] > 1)
2715
-			{
2716
-				if ($this->debug)
2717
-				{
2718
-					/// @todo echo something for user?
2719
-				}
2720
-
2721
-				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2722
-				$GLOBALS['xmlrpcstr']['invalid_return'] . ' ' . $GLOBALS['_xh']['isf_reason']);
2723
-			}
2724
-			// third error check: parsing of the response has somehow gone boink.
2725
-			// NB: shall we omit this check, since we trust the parsing code?
2726
-			elseif ($return_type == 'xmlrpcvals' && !is_object($GLOBALS['_xh']['value']))
2727
-			{
2728
-				// something odd has happened
2729
-				// and it's time to generate a client side error
2730
-				// indicating something odd went on
2731
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2732
-					$GLOBALS['xmlrpcstr']['invalid_return']);
2733
-			}
2734
-			else
2735
-			{
2736
-				if ($this->debug)
2737
-				{
2738
-					print "<PRE>---PARSED---\n";
2739
-					// somehow htmlentities chokes on var_export, and some full html string...
2740
-					//print htmlentitites(var_export($GLOBALS['_xh']['value'], true));
2741
-					print htmlspecialchars(var_export($GLOBALS['_xh']['value'], true));
2742
-					print "\n---END---</PRE>";
2743
-				}
2744
-
2745
-				// note that using =& will raise an error if $GLOBALS['_xh']['st'] does not generate an object.
2746
-				$v =& $GLOBALS['_xh']['value'];
2747
-
2748
-				if($GLOBALS['_xh']['isf'])
2749
-				{
2750
-					/// @todo we should test here if server sent an int and a string,
2751
-					/// and/or coerce them into such...
2752
-					if ($return_type == 'xmlrpcvals')
2753
-					{
2754
-						$errno_v = $v->structmem('faultCode');
2755
-						$errstr_v = $v->structmem('faultString');
2756
-						$errno = $errno_v->scalarval();
2757
-						$errstr = $errstr_v->scalarval();
2758
-					}
2759
-					else
2760
-					{
2761
-						$errno = $v['faultCode'];
2762
-						$errstr = $v['faultString'];
2763
-					}
2764
-
2765
-					if($errno == 0)
2766
-					{
2767
-						// FAULT returned, errno needs to reflect that
2768
-						$errno = -1;
2769
-					}
2770
-
2771
-					$r = new xmlrpcresp(0, $errno, $errstr);
2772
-				}
2773
-				else
2774
-				{
2775
-					$r=new xmlrpcresp($v, 0, '', $return_type);
2776
-				}
2777
-			}
2778
-
2779
-			$r->hdrs = $GLOBALS['_xh']['headers'];
2780
-			$r->_cookies = $GLOBALS['_xh']['cookies'];
2781
-			$r->raw_data = $raw_data;
2782
-			return $r;
2783
-		}
2784
-	}
2785
-
2786
-	class xmlrpcval
2787
-	{
2788
-		var $me=array();
2789
-		var $mytype=0;
2790
-		var $_php_class=null;
2791
-
2792
-		/**
2793
-		* @param mixed $val
2794
-		* @param string $type any valid xmlrpc type name (lowercase). If null, 'string' is assumed
2795
-		*/
2796
-		function __construct($val=-1, $type='')
2797
-		{
2798
-			/// @todo: optimization creep - do not call addXX, do it all inline.
2799
-			/// downside: booleans will not be coerced anymore
2800
-			if($val!==-1 || $type!='')
2801
-			{
2802
-				// optimization creep: inlined all work done by constructor
2803
-				switch($type)
2804
-				{
2805
-					case '':
2806
-						$this->mytype=1;
2807
-						$this->me['string']=$val;
2808
-						break;
2809
-					case 'i4':
2810
-					case 'int':
2811
-					case 'double':
2812
-					case 'string':
2813
-					case 'boolean':
2814
-					case 'dateTime.iso8601':
2815
-					case 'base64':
2816
-					case 'null':
2817
-						$this->mytype=1;
2818
-						$this->me[$type]=$val;
2819
-						break;
2820
-					case 'array':
2821
-						$this->mytype=2;
2822
-						$this->me['array']=$val;
2823
-						break;
2824
-					case 'struct':
2825
-						$this->mytype=3;
2826
-						$this->me['struct']=$val;
2827
-						break;
2828
-					default:
2829
-						error_log("XML-RPC: ".__METHOD__.": not a known type ($type)");
2830
-				}
2831
-				/*if($type=='')
2114
+            }
2115
+            else
2116
+            {
2117
+                if(!is_object($this->val) || !is_a($this->val, 'xmlrpcval'))
2118
+                {
2119
+                    if (is_string($this->val) && $this->valtyp == 'xml')
2120
+                    {
2121
+                        $result .= "<params>\n<param>\n" .
2122
+                            $this->val .
2123
+                            "</param>\n</params>";
2124
+                    }
2125
+                    else
2126
+                    {
2127
+                        /// @todo try to build something serializable?
2128
+                        die('cannot serialize xmlrpcresp objects whose content is native php values');
2129
+                    }
2130
+                }
2131
+                else
2132
+                {
2133
+                    $result .= "<params>\n<param>\n" .
2134
+                        $this->val->serialize($charset_encoding) .
2135
+                        "</param>\n</params>";
2136
+                }
2137
+            }
2138
+            $result .= "\n</methodResponse>";
2139
+            $this->payload = $result;
2140
+            return $result;
2141
+        }
2142
+    }
2143
+
2144
+    class xmlrpcmsg
2145
+    {
2146
+        var $payload;
2147
+        var $methodname;
2148
+        var $params=array();
2149
+        var $debug=0;
2150
+        var $content_type = 'text/xml';
2151
+
2152
+        /**
2153
+         * @param string $meth the name of the method to invoke
2154
+         * @param array $pars array of parameters to be passed to the method (xmlrpcval objects)
2155
+         */
2156
+        function __construct($meth, $pars=0)
2157
+        {
2158
+            $this->methodname=$meth;
2159
+            if(is_array($pars) && count($pars)>0)
2160
+            {
2161
+                for($i=0; $i<count($pars); $i++)
2162
+                {
2163
+                    $this->addParam($pars[$i]);
2164
+                }
2165
+            }
2166
+        }
2167
+
2168
+                /**
2169
+                 * @deprecated
2170
+                 */
2171
+        function xmlrpcmsg($meth, $pars=0)
2172
+        {
2173
+            self::__construct($meth, $pars);
2174
+        }
2175
+
2176
+        /**
2177
+         * @access private
2178
+         */
2179
+        function xml_header($charset_encoding='')
2180
+        {
2181
+            if ($charset_encoding != '')
2182
+            {
2183
+                return "<?xml version=\"1.0\" encoding=\"$charset_encoding\" ?" . ">\n<methodCall>\n";
2184
+            }
2185
+            else
2186
+            {
2187
+                return "<?xml version=\"1.0\"?" . ">\n<methodCall>\n";
2188
+            }
2189
+        }
2190
+
2191
+        /**
2192
+         * @access private
2193
+         */
2194
+        function xml_footer()
2195
+        {
2196
+            return '</methodCall>';
2197
+        }
2198
+
2199
+        /**
2200
+         * @access private
2201
+         */
2202
+        function kindOf()
2203
+        {
2204
+            return 'msg';
2205
+        }
2206
+
2207
+        /**
2208
+         * @access private
2209
+         */
2210
+        function createPayload($charset_encoding='')
2211
+        {
2212
+            if ($charset_encoding != '')
2213
+                $this->content_type = 'text/xml; charset=' . $charset_encoding;
2214
+            else
2215
+                $this->content_type = 'text/xml';
2216
+            $this->payload=$this->xml_header($charset_encoding);
2217
+            $this->payload.='<methodName>' . xmlrpc_encode_entitites($this->methodname, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "</methodName>\n";
2218
+            $this->payload.="<params>\n";
2219
+            for($i=0; $i<count($this->params); $i++)
2220
+            {
2221
+                $p=$this->params[$i];
2222
+                $this->payload.="<param>\n" . $p->serialize($charset_encoding) .
2223
+                "</param>\n";
2224
+            }
2225
+            $this->payload.="</params>\n";
2226
+            $this->payload.=$this->xml_footer();
2227
+        }
2228
+
2229
+        /**
2230
+         * Gets/sets the xmlrpc method to be invoked
2231
+         * @param string $meth the method to be set (leave empty not to set it)
2232
+         * @return string the method that will be invoked
2233
+         * @access public
2234
+         */
2235
+        function method($meth='')
2236
+        {
2237
+            if($meth!='')
2238
+            {
2239
+                $this->methodname=$meth;
2240
+            }
2241
+            return $this->methodname;
2242
+        }
2243
+
2244
+        /**
2245
+         * Returns xml representation of the message. XML prologue included
2246
+         * @param string $charset_encoding
2247
+         * @return string the xml representation of the message, xml prologue included
2248
+         * @access public
2249
+         */
2250
+        function serialize($charset_encoding='')
2251
+        {
2252
+            $this->createPayload($charset_encoding);
2253
+            return $this->payload;
2254
+        }
2255
+
2256
+        /**
2257
+         * Add a parameter to the list of parameters to be used upon method invocation
2258
+         * @param xmlrpcval $par
2259
+         * @return boolean false on failure
2260
+         * @access public
2261
+         */
2262
+        function addParam($par)
2263
+        {
2264
+            // add check: do not add to self params which are not xmlrpcvals
2265
+            if(is_object($par) && is_a($par, 'xmlrpcval'))
2266
+            {
2267
+                $this->params[]=$par;
2268
+                return true;
2269
+            }
2270
+            else
2271
+            {
2272
+                return false;
2273
+            }
2274
+        }
2275
+
2276
+        /**
2277
+         * Returns the nth parameter in the message. The index zero-based.
2278
+         * @param integer $i the index of the parameter to fetch (zero based)
2279
+         * @return xmlrpcval the i-th parameter
2280
+         * @access public
2281
+         */
2282
+        function getParam($i) { return $this->params[$i]; }
2283
+
2284
+        /**
2285
+         * Returns the number of parameters in the messge.
2286
+         * @return integer the number of parameters currently set
2287
+         * @access public
2288
+         */
2289
+        function getNumParams() { return count($this->params); }
2290
+
2291
+        /**
2292
+         * Given an open file handle, read all data available and parse it as axmlrpc response.
2293
+         * NB: the file handle is not closed by this function.
2294
+         * NNB: might have trouble in rare cases to work on network streams, as we
2295
+         *      check for a read of 0 bytes instead of feof($fp).
2296
+         *      But since checking for feof(null) returns false, we would risk an
2297
+         *      infinite loop in that case, because we cannot trust the caller
2298
+         *      to give us a valid pointer to an open file...
2299
+         * @access public
2300
+         * @param resource $fp stream pointer
2301
+         * @return xmlrpcresp
2302
+         * @todo add 2nd & 3rd param to be passed to ParseResponse() ???
2303
+         */
2304
+        function &parseResponseFile($fp)
2305
+        {
2306
+            $ipd='';
2307
+            while($data=fread($fp, 32768))
2308
+            {
2309
+                $ipd.=$data;
2310
+            }
2311
+            //fclose($fp);
2312
+            $r =& $this->parseResponse($ipd);
2313
+            return $r;
2314
+        }
2315
+
2316
+        /**
2317
+         * Parses HTTP headers and separates them from data.
2318
+         * @access private
2319
+         */
2320
+        function &parseResponseHeaders(&$data, $headers_processed=false)
2321
+        {
2322
+                // Support "web-proxy-tunelling" connections for https through proxies
2323
+                if(preg_match('/^HTTP\/1\.[0-1] 200 Connection established/', $data))
2324
+                {
2325
+                    // Look for CR/LF or simple LF as line separator,
2326
+                    // (even though it is not valid http)
2327
+                    $pos = strpos($data,"\r\n\r\n");
2328
+                    if($pos || is_int($pos))
2329
+                    {
2330
+                        $bd = $pos+4;
2331
+                    }
2332
+                    else
2333
+                    {
2334
+                        $pos = strpos($data,"\n\n");
2335
+                        if($pos || is_int($pos))
2336
+                        {
2337
+                            $bd = $pos+2;
2338
+                        }
2339
+                        else
2340
+                        {
2341
+                            // No separation between response headers and body: fault?
2342
+                            $bd = 0;
2343
+                        }
2344
+                    }
2345
+                    if ($bd)
2346
+                    {
2347
+                        // this filters out all http headers from proxy.
2348
+                        // maybe we could take them into account, too?
2349
+                        $data = substr($data, $bd);
2350
+                    }
2351
+                    else
2352
+                    {
2353
+                        error_log('XML-RPC: '.__METHOD__.': HTTPS via proxy error, tunnel connection possibly failed');
2354
+                        $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (HTTPS via proxy error, tunnel connection possibly failed)');
2355
+                        return $r;
2356
+                    }
2357
+                }
2358
+
2359
+                // Strip HTTP 1.1 100 Continue header if present
2360
+                while(preg_match('/^HTTP\/1\.1 1[0-9]{2} /', $data))
2361
+                {
2362
+                    $pos = strpos($data, 'HTTP', 12);
2363
+                    // server sent a Continue header without any (valid) content following...
2364
+                    // give the client a chance to know it
2365
+                    if(!$pos && !is_int($pos)) // works fine in php 3, 4 and 5
2366
+                    {
2367
+                        break;
2368
+                    }
2369
+                    $data = substr($data, $pos);
2370
+                }
2371
+                if(!preg_match('/^HTTP\/[0-9.]+ 200 /', $data))
2372
+                {
2373
+                    $errstr= substr($data, 0, strpos($data, "\n")-1);
2374
+                    error_log('XML-RPC: '.__METHOD__.': HTTP error, got response: ' .$errstr);
2375
+                    $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (' . $errstr . ')');
2376
+                    return $r;
2377
+                }
2378
+
2379
+                $GLOBALS['_xh']['headers'] = array();
2380
+                $GLOBALS['_xh']['cookies'] = array();
2381
+
2382
+                // be tolerant to usage of \n instead of \r\n to separate headers and data
2383
+                // (even though it is not valid http)
2384
+                $pos = strpos($data,"\r\n\r\n");
2385
+                if($pos || is_int($pos))
2386
+                {
2387
+                    $bd = $pos+4;
2388
+                }
2389
+                else
2390
+                {
2391
+                    $pos = strpos($data,"\n\n");
2392
+                    if($pos || is_int($pos))
2393
+                    {
2394
+                        $bd = $pos+2;
2395
+                    }
2396
+                    else
2397
+                    {
2398
+                        // No separation between response headers and body: fault?
2399
+                        // we could take some action here instead of going on...
2400
+                        $bd = 0;
2401
+                    }
2402
+                }
2403
+                // be tolerant to line endings, and extra empty lines
2404
+                $ar = preg_split("/\r?\n/", trim(substr($data, 0, $pos)));
2405
+                while(list(,$line) = @each($ar))
2406
+                {
2407
+                    // take care of multi-line headers and cookies
2408
+                    $arr = explode(':',$line,2);
2409
+                    if(count($arr) > 1)
2410
+                    {
2411
+                        $header_name = strtolower(trim($arr[0]));
2412
+                        /// @todo some other headers (the ones that allow a CSV list of values)
2413
+                        /// do allow many values to be passed using multiple header lines.
2414
+                        /// We should add content to $GLOBALS['_xh']['headers'][$header_name]
2415
+                        /// instead of replacing it for those...
2416
+                        if ($header_name == 'set-cookie' || $header_name == 'set-cookie2')
2417
+                        {
2418
+                            if ($header_name == 'set-cookie2')
2419
+                            {
2420
+                                // version 2 cookies:
2421
+                                // there could be many cookies on one line, comma separated
2422
+                                $cookies = explode(',', $arr[1]);
2423
+                            }
2424
+                            else
2425
+                            {
2426
+                                $cookies = array($arr[1]);
2427
+                            }
2428
+                            foreach ($cookies as $cookie)
2429
+                            {
2430
+                                // glue together all received cookies, using a comma to separate them
2431
+                                // (same as php does with getallheaders())
2432
+                                if (isset($GLOBALS['_xh']['headers'][$header_name]))
2433
+                                    $GLOBALS['_xh']['headers'][$header_name] .= ', ' . trim($cookie);
2434
+                                else
2435
+                                    $GLOBALS['_xh']['headers'][$header_name] = trim($cookie);
2436
+                                // parse cookie attributes, in case user wants to correctly honour them
2437
+                                // feature creep: only allow rfc-compliant cookie attributes?
2438
+                                // @todo support for server sending multiple time cookie with same name, but using different PATHs
2439
+                                $cookie = explode(';', $cookie);
2440
+                                foreach ($cookie as $pos => $val)
2441
+                                {
2442
+                                    $val = explode('=', $val, 2);
2443
+                                    $tag = trim($val[0]);
2444
+                                    $val = trim(@$val[1]);
2445
+                                    /// @todo with version 1 cookies, we should strip leading and trailing " chars
2446
+                                    if ($pos == 0)
2447
+                                    {
2448
+                                        $cookiename = $tag;
2449
+                                        $GLOBALS['_xh']['cookies'][$tag] = array();
2450
+                                        $GLOBALS['_xh']['cookies'][$cookiename]['value'] = urldecode($val);
2451
+                                    }
2452
+                                    else
2453
+                                    {
2454
+                                        if ($tag != 'value')
2455
+                                        {
2456
+                                            $GLOBALS['_xh']['cookies'][$cookiename][$tag] = $val;
2457
+                                        }
2458
+                                    }
2459
+                                }
2460
+                            }
2461
+                        }
2462
+                        else
2463
+                        {
2464
+                            $GLOBALS['_xh']['headers'][$header_name] = trim($arr[1]);
2465
+                        }
2466
+                    }
2467
+                    elseif(isset($header_name))
2468
+                    {
2469
+                        ///	@todo version1 cookies might span multiple lines, thus breaking the parsing above
2470
+                        $GLOBALS['_xh']['headers'][$header_name] .= ' ' . trim($line);
2471
+                    }
2472
+                }
2473
+
2474
+                $data = substr($data, $bd);
2475
+
2476
+                if($this->debug && count($GLOBALS['_xh']['headers']))
2477
+                {
2478
+                    print '<PRE>';
2479
+                    foreach($GLOBALS['_xh']['headers'] as $header => $value)
2480
+                    {
2481
+                        print htmlentities("HEADER: $header: $value\n");
2482
+                    }
2483
+                    foreach($GLOBALS['_xh']['cookies'] as $header => $value)
2484
+                    {
2485
+                        print htmlentities("COOKIE: $header={$value['value']}\n");
2486
+                    }
2487
+                    print "</PRE>\n";
2488
+                }
2489
+
2490
+                // if CURL was used for the call, http headers have been processed,
2491
+                // and dechunking + reinflating have been carried out
2492
+                if(!$headers_processed)
2493
+                {
2494
+                    // Decode chunked encoding sent by http 1.1 servers
2495
+                    if(isset($GLOBALS['_xh']['headers']['transfer-encoding']) && $GLOBALS['_xh']['headers']['transfer-encoding'] == 'chunked')
2496
+                    {
2497
+                        if(!$data = decode_chunked($data))
2498
+                        {
2499
+                            error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to rebuild the chunked data received from server');
2500
+                            $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['dechunk_fail'], $GLOBALS['xmlrpcstr']['dechunk_fail']);
2501
+                            return $r;
2502
+                        }
2503
+                    }
2504
+
2505
+                    // Decode gzip-compressed stuff
2506
+                    // code shamelessly inspired from nusoap library by Dietrich Ayala
2507
+                    if(isset($GLOBALS['_xh']['headers']['content-encoding']))
2508
+                    {
2509
+                        $GLOBALS['_xh']['headers']['content-encoding'] = str_replace('x-', '', $GLOBALS['_xh']['headers']['content-encoding']);
2510
+                        if($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' || $GLOBALS['_xh']['headers']['content-encoding'] == 'gzip')
2511
+                        {
2512
+                            // if decoding works, use it. else assume data wasn't gzencoded
2513
+                            if(function_exists('gzinflate'))
2514
+                            {
2515
+                                if($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data))
2516
+                                {
2517
+                                    $data = $degzdata;
2518
+                                    if($this->debug)
2519
+                                    print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n" . htmlentities($data) . "\n---END---</PRE>";
2520
+                                }
2521
+                                elseif($GLOBALS['_xh']['headers']['content-encoding'] == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
2522
+                                {
2523
+                                    $data = $degzdata;
2524
+                                    if($this->debug)
2525
+                                    print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n" . htmlentities($data) . "\n---END---</PRE>";
2526
+                                }
2527
+                                else
2528
+                                {
2529
+                                    error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to decode the deflated data received from server');
2530
+                                    $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['decompress_fail'], $GLOBALS['xmlrpcstr']['decompress_fail']);
2531
+                                    return $r;
2532
+                                }
2533
+                            }
2534
+                            else
2535
+                            {
2536
+                                error_log('XML-RPC: '.__METHOD__.': the server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');
2537
+                                $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['cannot_decompress'], $GLOBALS['xmlrpcstr']['cannot_decompress']);
2538
+                                return $r;
2539
+                            }
2540
+                        }
2541
+                    }
2542
+                } // end of 'if needed, de-chunk, re-inflate response'
2543
+
2544
+                // real stupid hack to avoid PHP complaining about returning NULL by ref
2545
+                $r = null;
2546
+                $r =& $r;
2547
+                return $r;
2548
+        }
2549
+
2550
+        /**
2551
+         * Parse the xmlrpc response contained in the string $data and return an xmlrpcresp object.
2552
+         * @param string $data the xmlrpc response, eventually including http headers
2553
+         * @param bool $headers_processed when true prevents parsing HTTP headers for interpretation of content-encoding and consequent decoding
2554
+         * @param string $return_type decides return type, i.e. content of response->value(). Either 'xmlrpcvals', 'xml' or 'phpvals'
2555
+         * @return xmlrpcresp
2556
+         * @access public
2557
+         */
2558
+        function &parseResponse($data='', $headers_processed=false, $return_type='xmlrpcvals')
2559
+        {
2560
+            if($this->debug)
2561
+            {
2562
+                //by maHo, replaced htmlspecialchars with htmlentities
2563
+                print "<PRE>---GOT---\n" . htmlentities($data) . "\n---END---\n</PRE>";
2564
+            }
2565
+
2566
+            if($data == '')
2567
+            {
2568
+                error_log('XML-RPC: '.__METHOD__.': no response received from server.');
2569
+                $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_data'], $GLOBALS['xmlrpcstr']['no_data']);
2570
+                return $r;
2571
+            }
2572
+
2573
+            $GLOBALS['_xh']=array();
2574
+
2575
+            $raw_data = $data;
2576
+            // parse the HTTP headers of the response, if present, and separate them from data
2577
+            if(substr($data, 0, 4) == 'HTTP')
2578
+            {
2579
+                $r =& $this->parseResponseHeaders($data, $headers_processed);
2580
+                if ($r)
2581
+                {
2582
+                    // failed processing of HTTP response headers
2583
+                    // save into response obj the full payload received, for debugging
2584
+                    $r->raw_data = $data;
2585
+                    return $r;
2586
+                }
2587
+            }
2588
+            else
2589
+            {
2590
+                $GLOBALS['_xh']['headers'] = array();
2591
+                $GLOBALS['_xh']['cookies'] = array();
2592
+            }
2593
+
2594
+            if($this->debug)
2595
+            {
2596
+                $start = strpos($data, '<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
2597
+                if ($start)
2598
+                {
2599
+                    $start += strlen('<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
2600
+                    $end = strpos($data, '-->', $start);
2601
+                    $comments = substr($data, $start, $end-$start);
2602
+                    print "<PRE>---SERVER DEBUG INFO (DECODED) ---\n\t".htmlentities(str_replace("\n", "\n\t", base64_decode($comments)))."\n---END---\n</PRE>";
2603
+                }
2604
+            }
2605
+
2606
+            // be tolerant of extra whitespace in response body
2607
+            $data = trim($data);
2608
+
2609
+            /// @todo return an error msg if $data=='' ?
2610
+
2611
+            // be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts)
2612
+            // idea from Luca Mariano <[email protected]> originally in PEARified version of the lib
2613
+            $pos = strrpos($data, '</methodResponse>');
2614
+            if($pos !== false)
2615
+            {
2616
+                $data = substr($data, 0, $pos+17);
2617
+            }
2618
+
2619
+            // if user wants back raw xml, give it to him
2620
+            if ($return_type == 'xml')
2621
+            {
2622
+                $r = new xmlrpcresp($data, 0, '', 'xml');
2623
+                $r->hdrs = $GLOBALS['_xh']['headers'];
2624
+                $r->_cookies = $GLOBALS['_xh']['cookies'];
2625
+                $r->raw_data = $raw_data;
2626
+                return $r;
2627
+            }
2628
+
2629
+            // try to 'guestimate' the character encoding of the received response
2630
+            $resp_encoding = guess_encoding(@$GLOBALS['_xh']['headers']['content-type'], $data);
2631
+
2632
+            $GLOBALS['_xh']['ac']='';
2633
+            //$GLOBALS['_xh']['qt']=''; //unused...
2634
+            $GLOBALS['_xh']['stack'] = array();
2635
+            $GLOBALS['_xh']['valuestack'] = array();
2636
+            $GLOBALS['_xh']['isf']=0; // 0 = OK, 1 for xmlrpc fault responses, 2 = invalid xmlrpc
2637
+            $GLOBALS['_xh']['isf_reason']='';
2638
+            $GLOBALS['_xh']['rt']=''; // 'methodcall or 'methodresponse'
2639
+
2640
+            // Since parsing will fail if charset is not specified in the xml prologue,
2641
+            // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
2642
+            // The following code might be better for mb_string enabled installs, but
2643
+            // makes the lib about 200% slower...
2644
+            //if (!is_valid_charset($resp_encoding, array('UTF-8')))
2645
+            if (!in_array($resp_encoding, array('UTF-8', 'US-ASCII')) && !has_encoding($data)) {
2646
+                if ($resp_encoding == 'ISO-8859-1') {
2647
+                    $data = utf8_encode($data);
2648
+                } else {
2649
+                    if (extension_loaded('mbstring')) {
2650
+                        $data = mb_convert_encoding($data, 'UTF-8', $resp_encoding);
2651
+                    } else {
2652
+                        error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $resp_encoding);
2653
+                    }
2654
+                }
2655
+            }
2656
+
2657
+            $parser = xml_parser_create();
2658
+            xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
2659
+            // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
2660
+            // the xml parser to give us back data in the expected charset.
2661
+            // What if internal encoding is not in one of the 3 allowed?
2662
+            // we use the broadest one, ie. utf8
2663
+            // This allows to send data which is native in various charset,
2664
+            // by extending xmlrpc_encode_entitites() and setting xmlrpc_internalencoding
2665
+            if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
2666
+            {
2667
+                xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
2668
+            }
2669
+            else
2670
+            {
2671
+                xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
2672
+            }
2673
+
2674
+            if ($return_type == 'phpvals')
2675
+            {
2676
+                xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast');
2677
+            }
2678
+            else
2679
+            {
2680
+                xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
2681
+            }
2682
+
2683
+            xml_set_character_data_handler($parser, 'xmlrpc_cd');
2684
+            xml_set_default_handler($parser, 'xmlrpc_dh');
2685
+
2686
+            // first error check: xml not well formed
2687
+            if(!xml_parse($parser, $data, 1))
2688
+            {
2689
+                // thanks to Peter Kocks <[email protected]>
2690
+                if((xml_get_current_line_number($parser)) == 1)
2691
+                {
2692
+                    $errstr = 'XML error at line 1, check URL';
2693
+                }
2694
+                else
2695
+                {
2696
+                    $errstr = sprintf('XML error: %s at line %d, column %d',
2697
+                        xml_error_string(xml_get_error_code($parser)),
2698
+                        xml_get_current_line_number($parser), xml_get_current_column_number($parser));
2699
+                }
2700
+                error_log($errstr);
2701
+                $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcstr']['invalid_return'].' ('.$errstr.')');
2702
+                xml_parser_free($parser);
2703
+                if($this->debug)
2704
+                {
2705
+                    print $errstr;
2706
+                }
2707
+                $r->hdrs = $GLOBALS['_xh']['headers'];
2708
+                $r->_cookies = $GLOBALS['_xh']['cookies'];
2709
+                $r->raw_data = $raw_data;
2710
+                return $r;
2711
+            }
2712
+            xml_parser_free($parser);
2713
+            // second error check: xml well formed but not xml-rpc compliant
2714
+            if ($GLOBALS['_xh']['isf'] > 1)
2715
+            {
2716
+                if ($this->debug)
2717
+                {
2718
+                    /// @todo echo something for user?
2719
+                }
2720
+
2721
+                $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2722
+                $GLOBALS['xmlrpcstr']['invalid_return'] . ' ' . $GLOBALS['_xh']['isf_reason']);
2723
+            }
2724
+            // third error check: parsing of the response has somehow gone boink.
2725
+            // NB: shall we omit this check, since we trust the parsing code?
2726
+            elseif ($return_type == 'xmlrpcvals' && !is_object($GLOBALS['_xh']['value']))
2727
+            {
2728
+                // something odd has happened
2729
+                // and it's time to generate a client side error
2730
+                // indicating something odd went on
2731
+                $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2732
+                    $GLOBALS['xmlrpcstr']['invalid_return']);
2733
+            }
2734
+            else
2735
+            {
2736
+                if ($this->debug)
2737
+                {
2738
+                    print "<PRE>---PARSED---\n";
2739
+                    // somehow htmlentities chokes on var_export, and some full html string...
2740
+                    //print htmlentitites(var_export($GLOBALS['_xh']['value'], true));
2741
+                    print htmlspecialchars(var_export($GLOBALS['_xh']['value'], true));
2742
+                    print "\n---END---</PRE>";
2743
+                }
2744
+
2745
+                // note that using =& will raise an error if $GLOBALS['_xh']['st'] does not generate an object.
2746
+                $v =& $GLOBALS['_xh']['value'];
2747
+
2748
+                if($GLOBALS['_xh']['isf'])
2749
+                {
2750
+                    /// @todo we should test here if server sent an int and a string,
2751
+                    /// and/or coerce them into such...
2752
+                    if ($return_type == 'xmlrpcvals')
2753
+                    {
2754
+                        $errno_v = $v->structmem('faultCode');
2755
+                        $errstr_v = $v->structmem('faultString');
2756
+                        $errno = $errno_v->scalarval();
2757
+                        $errstr = $errstr_v->scalarval();
2758
+                    }
2759
+                    else
2760
+                    {
2761
+                        $errno = $v['faultCode'];
2762
+                        $errstr = $v['faultString'];
2763
+                    }
2764
+
2765
+                    if($errno == 0)
2766
+                    {
2767
+                        // FAULT returned, errno needs to reflect that
2768
+                        $errno = -1;
2769
+                    }
2770
+
2771
+                    $r = new xmlrpcresp(0, $errno, $errstr);
2772
+                }
2773
+                else
2774
+                {
2775
+                    $r=new xmlrpcresp($v, 0, '', $return_type);
2776
+                }
2777
+            }
2778
+
2779
+            $r->hdrs = $GLOBALS['_xh']['headers'];
2780
+            $r->_cookies = $GLOBALS['_xh']['cookies'];
2781
+            $r->raw_data = $raw_data;
2782
+            return $r;
2783
+        }
2784
+    }
2785
+
2786
+    class xmlrpcval
2787
+    {
2788
+        var $me=array();
2789
+        var $mytype=0;
2790
+        var $_php_class=null;
2791
+
2792
+        /**
2793
+         * @param mixed $val
2794
+         * @param string $type any valid xmlrpc type name (lowercase). If null, 'string' is assumed
2795
+         */
2796
+        function __construct($val=-1, $type='')
2797
+        {
2798
+            /// @todo: optimization creep - do not call addXX, do it all inline.
2799
+            /// downside: booleans will not be coerced anymore
2800
+            if($val!==-1 || $type!='')
2801
+            {
2802
+                // optimization creep: inlined all work done by constructor
2803
+                switch($type)
2804
+                {
2805
+                    case '':
2806
+                        $this->mytype=1;
2807
+                        $this->me['string']=$val;
2808
+                        break;
2809
+                    case 'i4':
2810
+                    case 'int':
2811
+                    case 'double':
2812
+                    case 'string':
2813
+                    case 'boolean':
2814
+                    case 'dateTime.iso8601':
2815
+                    case 'base64':
2816
+                    case 'null':
2817
+                        $this->mytype=1;
2818
+                        $this->me[$type]=$val;
2819
+                        break;
2820
+                    case 'array':
2821
+                        $this->mytype=2;
2822
+                        $this->me['array']=$val;
2823
+                        break;
2824
+                    case 'struct':
2825
+                        $this->mytype=3;
2826
+                        $this->me['struct']=$val;
2827
+                        break;
2828
+                    default:
2829
+                        error_log("XML-RPC: ".__METHOD__.": not a known type ($type)");
2830
+                }
2831
+                /*if($type=='')
2832 2832
 				{
2833 2833
 					$type='string';
2834 2834
 				}
@@ -2844,1078 +2844,1078 @@  discard block
 block discarded – undo
2844 2844
 				{
2845 2845
 					$this->addStruct($val);
2846 2846
 				}*/
2847
-			}
2848
-		}
2849
-
2850
-		/**
2851
-		* @deprecated
2852
-		*/
2853
-		function xmlrpcval($val=-1, $type='')
2854
-		{
2855
-			self::__construct($val, $type);
2856
-		}
2857
-
2858
-		/**
2859
-		* Add a single php value to an (unitialized) xmlrpcval
2860
-		* @param mixed $val
2861
-		* @param string $type
2862
-		* @return int 1 or 0 on failure
2863
-		*/
2864
-		function addScalar($val, $type='string')
2865
-		{
2866
-			$typeof=@$GLOBALS['xmlrpcTypes'][$type];
2867
-			if($typeof!=1)
2868
-			{
2869
-				error_log("XML-RPC: ".__METHOD__.": not a scalar type ($type)");
2870
-				return 0;
2871
-			}
2872
-
2873
-			// coerce booleans into correct values
2874
-			// NB: we should either do it for datetimes, integers and doubles, too,
2875
-			// or just plain remove this check, implemented on booleans only...
2876
-			if($type==$GLOBALS['xmlrpcBoolean'])
2877
-			{
2878
-				if(strcasecmp($val,'true')==0 || $val==1 || ($val==true && strcasecmp($val,'false')))
2879
-				{
2880
-					$val=true;
2881
-				}
2882
-				else
2883
-				{
2884
-					$val=false;
2885
-				}
2886
-			}
2887
-
2888
-			switch($this->mytype)
2889
-			{
2890
-				case 1:
2891
-					error_log('XML-RPC: '.__METHOD__.': scalar xmlrpcval can have only one value');
2892
-					return 0;
2893
-				case 3:
2894
-					error_log('XML-RPC: '.__METHOD__.': cannot add anonymous scalar to struct xmlrpcval');
2895
-					return 0;
2896
-				case 2:
2897
-					// we're adding a scalar value to an array here
2898
-					//$ar=$this->me['array'];
2899
-					//$ar[]=new xmlrpcval($val, $type);
2900
-					//$this->me['array']=$ar;
2901
-					// Faster (?) avoid all the costly array-copy-by-val done here...
2902
-					$this->me['array'][]=new xmlrpcval($val, $type);
2903
-					return 1;
2904
-				default:
2905
-					// a scalar, so set the value and remember we're scalar
2906
-					$this->me[$type]=$val;
2907
-					$this->mytype=$typeof;
2908
-					return 1;
2909
-			}
2910
-		}
2911
-
2912
-		/**
2913
-		* Add an array of xmlrpcval objects to an xmlrpcval
2914
-		* @param array $vals
2915
-		* @return int 1 or 0 on failure
2916
-		* @access public
2917
-		*
2918
-		* @todo add some checking for $vals to be an array of xmlrpcvals?
2919
-		*/
2920
-		function addArray($vals)
2921
-		{
2922
-			if($this->mytype==0)
2923
-			{
2924
-				$this->mytype=$GLOBALS['xmlrpcTypes']['array'];
2925
-				$this->me['array']=$vals;
2926
-				return 1;
2927
-			}
2928
-			elseif($this->mytype==2)
2929
-			{
2930
-				// we're adding to an array here
2931
-				$this->me['array'] = array_merge($this->me['array'], $vals);
2932
-				return 1;
2933
-			}
2934
-			else
2935
-			{
2936
-				error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');
2937
-				return 0;
2938
-			}
2939
-		}
2940
-
2941
-		/**
2942
-		* Add an array of named xmlrpcval objects to an xmlrpcval
2943
-		* @param array $vals
2944
-		* @return int 1 or 0 on failure
2945
-		* @access public
2946
-		*
2947
-		* @todo add some checking for $vals to be an array?
2948
-		*/
2949
-		function addStruct($vals)
2950
-		{
2951
-			if($this->mytype==0)
2952
-			{
2953
-				$this->mytype=$GLOBALS['xmlrpcTypes']['struct'];
2954
-				$this->me['struct']=$vals;
2955
-				return 1;
2956
-			}
2957
-			elseif($this->mytype==3)
2958
-			{
2959
-				// we're adding to a struct here
2960
-				$this->me['struct'] = array_merge($this->me['struct'], $vals);
2961
-				return 1;
2962
-			}
2963
-			else
2964
-			{
2965
-				error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');
2966
-				return 0;
2967
-			}
2968
-		}
2969
-
2970
-		// poor man's version of print_r ???
2971
-		// DEPRECATED!
2972
-		function dump($ar)
2973
-		{
2974
-			foreach($ar as $key => $val)
2975
-			{
2976
-				echo "$key => $val<br />";
2977
-				if($key == 'array')
2978
-				{
2979
-					while(list($key2, $val2) = each($val))
2980
-					{
2981
-						echo "-- $key2 => $val2<br />";
2982
-					}
2983
-				}
2984
-			}
2985
-		}
2986
-
2987
-		/**
2988
-		* Returns a string containing "struct", "array" or "scalar" describing the base type of the value
2989
-		* @return string
2990
-		* @access public
2991
-		*/
2992
-		function kindOf()
2993
-		{
2994
-			switch($this->mytype)
2995
-			{
2996
-				case 3:
2997
-					return 'struct';
2998
-					break;
2999
-				case 2:
3000
-					return 'array';
3001
-					break;
3002
-				case 1:
3003
-					return 'scalar';
3004
-					break;
3005
-				default:
3006
-					return 'undef';
3007
-			}
3008
-		}
3009
-
3010
-		/**
3011
-		* @access private
3012
-		*/
3013
-		function serializedata($typ, $val, $charset_encoding='')
3014
-		{
3015
-			$rs='';
3016
-			switch(@$GLOBALS['xmlrpcTypes'][$typ])
3017
-			{
3018
-				case 1:
3019
-					switch($typ)
3020
-					{
3021
-						case $GLOBALS['xmlrpcBase64']:
3022
-							$rs.="<${typ}>" . base64_encode($val) . "</${typ}>";
3023
-							break;
3024
-						case $GLOBALS['xmlrpcBoolean']:
3025
-							$rs.="<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
3026
-							break;
3027
-						case $GLOBALS['xmlrpcString']:
3028
-							// G. Giunta 2005/2/13: do NOT use htmlentities, since
3029
-							// it will produce named html entities, which are invalid xml
3030
-							$rs.="<${typ}>" . xmlrpc_encode_entitites($val, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding). "</${typ}>";
3031
-							break;
3032
-						case $GLOBALS['xmlrpcInt']:
3033
-						case $GLOBALS['xmlrpcI4']:
3034
-							$rs.="<${typ}>".(int)$val."</${typ}>";
3035
-							break;
3036
-						case $GLOBALS['xmlrpcDouble']:
3037
-							// avoid using standard conversion of float to string because it is locale-dependent,
3038
-							// and also because the xmlrpc spec forbids exponential notation.
3039
-							// sprintf('%F') could be most likely ok but it fails eg. on 2e-14.
3040
-							// The code below tries its best at keeping max precision while avoiding exp notation,
3041
-							// but there is of course no limit in the number of decimal places to be used...
3042
-							$rs.="<${typ}>".preg_replace('/\\.?0+$/','',number_format((double)$val, 128, '.', ''))."</${typ}>";
3043
-							break;
3044
-						case $GLOBALS['xmlrpcDateTime']:
3045
-							if (is_string($val))
3046
-							{
3047
-								$rs.="<${typ}>${val}</${typ}>";
3048
-							}
3049
-							else if(is_a($val, 'DateTime'))
3050
-							{
3051
-								$rs.="<${typ}>".$val->format('Ymd\TH:i:s')."</${typ}>";
3052
-							}
3053
-							else if(is_int($val))
3054
-							{
3055
-								$rs.="<${typ}>".strftime("%Y%m%dT%H:%M:%S", $val)."</${typ}>";
3056
-							}
3057
-							else
3058
-							{
3059
-								// not really a good idea here: but what shall we output anyway? left for backward compat...
3060
-								$rs.="<${typ}>${val}</${typ}>";
3061
-							}
3062
-							break;
3063
-						case $GLOBALS['xmlrpcNull']:
3064
-							if ($GLOBALS['xmlrpc_null_apache_encoding'])
3065
-							{
3066
-								$rs.="<ex:nil/>";
3067
-							}
3068
-							else
3069
-							{
3070
-								$rs.="<nil/>";
3071
-							}
3072
-							break;
3073
-						default:
3074
-							// no standard type value should arrive here, but provide a possibility
3075
-							// for xmlrpcvals of unknown type...
3076
-							$rs.="<${typ}>${val}</${typ}>";
3077
-					}
3078
-					break;
3079
-				case 3:
3080
-					// struct
3081
-					if ($this->_php_class)
3082
-					{
3083
-						$rs.='<struct php_class="' . $this->_php_class . "\">\n";
3084
-					}
3085
-					else
3086
-					{
3087
-						$rs.="<struct>\n";
3088
-					}
3089
-					foreach($val as $key2 => $val2)
3090
-					{
3091
-						$rs.='<member><name>'.xmlrpc_encode_entitites($key2, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</name>\n";
3092
-						//$rs.=$this->serializeval($val2);
3093
-						$rs.=$val2->serialize($charset_encoding);
3094
-						$rs.="</member>\n";
3095
-					}
3096
-					$rs.='</struct>';
3097
-					break;
3098
-				case 2:
3099
-					// array
3100
-					$rs.="<array>\n<data>\n";
3101
-					for($i=0; $i<count($val); $i++)
3102
-					{
3103
-						//$rs.=$this->serializeval($val[$i]);
3104
-						$rs.=$val[$i]->serialize($charset_encoding);
3105
-					}
3106
-					$rs.="</data>\n</array>";
3107
-					break;
3108
-				default:
3109
-					break;
3110
-			}
3111
-			return $rs;
3112
-		}
3113
-
3114
-		/**
3115
-		* Returns xml representation of the value. XML prologue not included
3116
-		* @param string $charset_encoding the charset to be used for serialization. if null, US-ASCII is assumed
3117
-		* @return string
3118
-		* @access public
3119
-		*/
3120
-		function serialize($charset_encoding='')
3121
-		{
3122
-			// add check? slower, but helps to avoid recursion in serializing broken xmlrpcvals...
3123
-			//if (is_object($o) && (get_class($o) == 'xmlrpcval' || is_subclass_of($o, 'xmlrpcval')))
3124
-			//{
3125
-				$val = reset($this->me);
3126
-				$typ = key($this->me);
3127
-				return '<value>' . $this->serializedata($typ, $val, $charset_encoding) . "</value>\n";
3128
-			//}
3129
-		}
3130
-
3131
-		// DEPRECATED
3132
-		function serializeval($o)
3133
-		{
3134
-			// add check? slower, but helps to avoid recursion in serializing broken xmlrpcvals...
3135
-			//if (is_object($o) && (get_class($o) == 'xmlrpcval' || is_subclass_of($o, 'xmlrpcval')))
3136
-			//{
3137
-				$val = reset($o->me);
3138
-				$typ = key($o->me);
3139
-				return '<value>' . $this->serializedata($typ, $val) . "</value>\n";
3140
-			//}
3141
-		}
3142
-
3143
-		/**
3144
-		* Checks whether a struct member with a given name is present.
3145
-		* Works only on xmlrpcvals of type struct.
3146
-		* @param string $m the name of the struct member to be looked up
3147
-		* @return boolean
3148
-		* @access public
3149
-		*/
3150
-		function structmemexists($m)
3151
-		{
3152
-			return array_key_exists($m, $this->me['struct']);
3153
-		}
3154
-
3155
-		/**
3156
-		* Returns the value of a given struct member (an xmlrpcval object in itself).
3157
-		* Will raise a php warning if struct member of given name does not exist
3158
-		* @param string $m the name of the struct member to be looked up
3159
-		* @return xmlrpcval
3160
-		* @access public
3161
-		*/
3162
-		function structmem($m)
3163
-		{
3164
-			return $this->me['struct'][$m];
3165
-		}
3166
-
3167
-		/**
3168
-		* Reset internal pointer for xmlrpcvals of type struct.
3169
-		* @access public
3170
-		*/
3171
-		function structreset()
3172
-		{
3173
-			reset($this->me['struct']);
3174
-		}
3175
-
3176
-		/**
3177
-		* Return next member element for xmlrpcvals of type struct.
3178
-		* @return xmlrpcval
3179
-		* @access public
3180
-		*/
3181
-		function structeach()
3182
-		{
3183
-			return each($this->me['struct']);
3184
-		}
3185
-
3186
-		// DEPRECATED! this code looks like it is very fragile and has not been fixed
3187
-		// for a long long time. Shall we remove it for 2.0?
3188
-		function getval()
3189
-		{
3190
-			// UNSTABLE
3191
-			reset($this->me);
3192
-			list($a,$b)=each($this->me);
3193
-			// contributed by I Sofer, 2001-03-24
3194
-			// add support for nested arrays to scalarval
3195
-			// i've created a new method here, so as to
3196
-			// preserve back compatibility
3197
-
3198
-			if(is_array($b))
3199
-			{
3200
-				@reset($b);
3201
-				while(list($id,$cont) = @each($b))
3202
-				{
3203
-					$b[$id] = $cont->scalarval();
3204
-				}
3205
-			}
3206
-
3207
-			// add support for structures directly encoding php objects
3208
-			if(is_object($b))
3209
-			{
3210
-				$t = get_object_vars($b);
3211
-				@reset($t);
3212
-				while(list($id,$cont) = @each($t))
3213
-				{
3214
-					$t[$id] = $cont->scalarval();
3215
-				}
3216
-				@reset($t);
3217
-				while(list($id,$cont) = @each($t))
3218
-				{
3219
-					@$b->$id = $cont;
3220
-				}
3221
-			}
3222
-			// end contrib
3223
-			return $b;
3224
-		}
3225
-
3226
-		/**
3227
-		* Returns the value of a scalar xmlrpcval
3228
-		* @return mixed
3229
-		* @access public
3230
-		*/
3231
-		function scalarval()
3232
-		{
3233
-			reset($this->me);
3234
-			list(,$b)=each($this->me);
3235
-			return $b;
3236
-		}
3237
-
3238
-		/**
3239
-		* Returns the type of the xmlrpcval.
3240
-		* For integers, 'int' is always returned in place of 'i4'
3241
-		* @return string
3242
-		* @access public
3243
-		*/
3244
-		function scalartyp()
3245
-		{
3246
-			reset($this->me);
3247
-			list($a,)=each($this->me);
3248
-			if($a==$GLOBALS['xmlrpcI4'])
3249
-			{
3250
-				$a=$GLOBALS['xmlrpcInt'];
3251
-			}
3252
-			return $a;
3253
-		}
3254
-
3255
-		/**
3256
-		* Returns the m-th member of an xmlrpcval of struct type
3257
-		* @param integer $m the index of the value to be retrieved (zero based)
3258
-		* @return xmlrpcval
3259
-		* @access public
3260
-		*/
3261
-		function arraymem($m)
3262
-		{
3263
-			return $this->me['array'][$m];
3264
-		}
3265
-
3266
-		/**
3267
-		* Returns the number of members in an xmlrpcval of array type
3268
-		* @return integer
3269
-		* @access public
3270
-		*/
3271
-		function arraysize()
3272
-		{
3273
-			return count($this->me['array']);
3274
-		}
3275
-
3276
-		/**
3277
-		* Returns the number of members in an xmlrpcval of struct type
3278
-		* @return integer
3279
-		* @access public
3280
-		*/
3281
-		function structsize()
3282
-		{
3283
-			return count($this->me['struct']);
3284
-		}
3285
-	}
3286
-
3287
-
3288
-	// date helpers
3289
-
3290
-	/**
3291
-	* Given a timestamp, return the corresponding ISO8601 encoded string.
3292
-	*
3293
-	* Really, timezones ought to be supported
3294
-	* but the XML-RPC spec says:
3295
-	*
3296
-	* "Don't assume a timezone. It should be specified by the server in its
3297
-	* documentation what assumptions it makes about timezones."
3298
-	*
3299
-	* These routines always assume localtime unless
3300
-	* $utc is set to 1, in which case UTC is assumed
3301
-	* and an adjustment for locale is made when encoding
3302
-	*
3303
-	* @param int $timet (timestamp)
3304
-	* @param int $utc (0 or 1)
3305
-	* @return string
3306
-	*/
3307
-	function iso8601_encode($timet, $utc=0)
3308
-	{
3309
-		if(!$utc)
3310
-		{
3311
-			$t=strftime("%Y%m%dT%H:%M:%S", $timet);
3312
-		}
3313
-		else
3314
-		{
3315
-			if(function_exists('gmstrftime'))
3316
-			{
3317
-				// gmstrftime doesn't exist in some versions
3318
-				// of PHP
3319
-				$t=gmstrftime("%Y%m%dT%H:%M:%S", $timet);
3320
-			}
3321
-			else
3322
-			{
3323
-				$t=strftime("%Y%m%dT%H:%M:%S", $timet-date('Z'));
3324
-			}
3325
-		}
3326
-		return $t;
3327
-	}
3328
-
3329
-	/**
3330
-	* Given an ISO8601 date string, return a timet in the localtime, or UTC
3331
-	* @param string $idate
3332
-	* @param int $utc either 0 or 1
3333
-	* @return int (datetime)
3334
-	*/
3335
-	function iso8601_decode($idate, $utc=0)
3336
-	{
3337
-		$t=0;
3338
-		if(preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $idate, $regs))
3339
-		{
3340
-			if($utc)
3341
-			{
3342
-				$t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3343
-			}
3344
-			else
3345
-			{
3346
-				$t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3347
-			}
3348
-		}
3349
-		return $t;
3350
-	}
3351
-
3352
-	/**
3353
-	* Takes an xmlrpc value in PHP xmlrpcval object format and translates it into native PHP types.
3354
-	*
3355
-	* Works with xmlrpc message objects as input, too.
3356
-	*
3357
-	* Given proper options parameter, can rebuild generic php object instances
3358
-	* (provided those have been encoded to xmlrpc format using a corresponding
3359
-	* option in php_xmlrpc_encode())
3360
-	* PLEASE NOTE that rebuilding php objects involves calling their constructor function.
3361
-	* This means that the remote communication end can decide which php code will
3362
-	* get executed on your server, leaving the door possibly open to 'php-injection'
3363
-	* style of attacks (provided you have some classes defined on your server that
3364
-	* might wreak havoc if instances are built outside an appropriate context).
3365
-	* Make sure you trust the remote server/client before eanbling this!
3366
-	*
3367
-	* @author Dan Libby ([email protected])
3368
-	*
3369
-	* @param xmlrpcval $xmlrpc_val
3370
-	* @param array $options if 'decode_php_objs' is set in the options array, xmlrpc structs can be decoded into php objects; if 'dates_as_objects' is set xmlrpc datetimes are decoded as php DateTime objects (standard is
3371
-	* @return mixed
3372
-	*/
3373
-	function php_xmlrpc_decode($xmlrpc_val, $options=array())
3374
-	{
3375
-		switch($xmlrpc_val->kindOf())
3376
-		{
3377
-			case 'scalar':
3378
-				if (in_array('extension_api', $options))
3379
-				{
3380
-					reset($xmlrpc_val->me);
3381
-					list($typ,$val) = each($xmlrpc_val->me);
3382
-					switch ($typ)
3383
-					{
3384
-						case 'dateTime.iso8601':
3385
-							$xmlrpc_val->scalar = $val;
3386
-							$xmlrpc_val->xmlrpc_type = 'datetime';
3387
-							$xmlrpc_val->timestamp = iso8601_decode($val);
3388
-							return $xmlrpc_val;
3389
-						case 'base64':
3390
-							$xmlrpc_val->scalar = $val;
3391
-							$xmlrpc_val->type = $typ;
3392
-							return $xmlrpc_val;
3393
-						default:
3394
-							return $xmlrpc_val->scalarval();
3395
-					}
3396
-				}
3397
-				if (in_array('dates_as_objects', $options) && $xmlrpc_val->scalartyp() == 'dateTime.iso8601')
3398
-				{
3399
-					// we return a Datetime object instead of a string
3400
-					// since now the constructor of xmlrpcval accepts safely strings, ints and datetimes,
3401
-					// we cater to all 3 cases here
3402
-					$out = $xmlrpc_val->scalarval();
3403
-					if (is_string($out))
3404
-					{
3405
-						$out = strtotime($out);
3406
-					}
3407
-					if (is_int($out))
3408
-					{
3409
-						$result = new Datetime();
3410
-						$result->setTimestamp($out);
3411
-						return $result;
3412
-					}
3413
-					elseif (is_a($out, 'Datetime'))
3414
-					{
3415
-						return $out;
3416
-					}
3417
-				}
3418
-				return $xmlrpc_val->scalarval();
3419
-			case 'array':
3420
-				$size = $xmlrpc_val->arraysize();
3421
-				$arr = array();
3422
-				for($i = 0; $i < $size; $i++)
3423
-				{
3424
-					$arr[] = php_xmlrpc_decode($xmlrpc_val->arraymem($i), $options);
3425
-				}
3426
-				return $arr;
3427
-			case 'struct':
3428
-				$xmlrpc_val->structreset();
3429
-				// If user said so, try to rebuild php objects for specific struct vals.
3430
-				/// @todo should we raise a warning for class not found?
3431
-				// shall we check for proper subclass of xmlrpcval instead of
3432
-				// presence of _php_class to detect what we can do?
3433
-				if (in_array('decode_php_objs', $options) && $xmlrpc_val->_php_class != ''
3434
-					&& class_exists($xmlrpc_val->_php_class))
3435
-				{
3436
-					$obj = @new $xmlrpc_val->_php_class;
3437
-					while(list($key,$value)=$xmlrpc_val->structeach())
3438
-					{
3439
-						$obj->$key = php_xmlrpc_decode($value, $options);
3440
-					}
3441
-					return $obj;
3442
-				}
3443
-				else
3444
-				{
3445
-					$arr = array();
3446
-					while(list($key,$value)=$xmlrpc_val->structeach())
3447
-					{
3448
-						$arr[$key] = php_xmlrpc_decode($value, $options);
3449
-					}
3450
-					return $arr;
3451
-				}
3452
-			case 'msg':
3453
-				$paramcount = $xmlrpc_val->getNumParams();
3454
-				$arr = array();
3455
-				for($i = 0; $i < $paramcount; $i++)
3456
-				{
3457
-					$arr[] = php_xmlrpc_decode($xmlrpc_val->getParam($i));
3458
-				}
3459
-				return $arr;
3460
-			}
3461
-	}
3462
-
3463
-	// This constant left here only for historical reasons...
3464
-	// it was used to decide if we have to define xmlrpc_encode on our own, but
3465
-	// we do not do it anymore
3466
-	if(function_exists('xmlrpc_decode'))
3467
-	{
3468
-		define('XMLRPC_EPI_ENABLED','1');
3469
-	}
3470
-	else
3471
-	{
3472
-		define('XMLRPC_EPI_ENABLED','0');
3473
-	}
3474
-
3475
-	/**
3476
-	* Takes native php types and encodes them into xmlrpc PHP object format.
3477
-	* It will not re-encode xmlrpcval objects.
3478
-	*
3479
-	* Feature creep -- could support more types via optional type argument
3480
-	* (string => datetime support has been added, ??? => base64 not yet)
3481
-	*
3482
-	* If given a proper options parameter, php object instances will be encoded
3483
-	* into 'special' xmlrpc values, that can later be decoded into php objects
3484
-	* by calling php_xmlrpc_decode() with a corresponding option
3485
-	*
3486
-	* @author Dan Libby ([email protected])
3487
-	*
3488
-	* @param mixed $php_val the value to be converted into an xmlrpcval object
3489
-	* @param array $options	can include 'encode_php_objs', 'auto_dates', 'null_extension' or 'extension_api'
3490
-	* @return xmlrpcval
3491
-	*/
3492
-	function php_xmlrpc_encode($php_val, $options=array())
3493
-	{
3494
-		$type = gettype($php_val);
3495
-		switch($type)
3496
-		{
3497
-			case 'string':
3498
-				if (in_array('auto_dates', $options) && preg_match('/^[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $php_val))
3499
-					$xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcDateTime']);
3500
-				else
3501
-					$xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcString']);
3502
-				break;
3503
-			case 'integer':
3504
-				$xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcInt']);
3505
-				break;
3506
-			case 'double':
3507
-				$xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcDouble']);
3508
-				break;
3509
-				// <G_Giunta_2001-02-29>
3510
-				// Add support for encoding/decoding of booleans, since they are supported in PHP
3511
-			case 'boolean':
3512
-				$xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcBoolean']);
3513
-				break;
3514
-				// </G_Giunta_2001-02-29>
3515
-			case 'array':
3516
-				// PHP arrays can be encoded to either xmlrpc structs or arrays,
3517
-				// depending on wheter they are hashes or plain 0..n integer indexed
3518
-				// A shorter one-liner would be
3519
-				// $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
3520
-				// but execution time skyrockets!
3521
-				$j = 0;
3522
-				$arr = array();
3523
-				$ko = false;
3524
-				foreach($php_val as $key => $val)
3525
-				{
3526
-					$arr[$key] = php_xmlrpc_encode($val, $options);
3527
-					if(!$ko && $key !== $j)
3528
-					{
3529
-						$ko = true;
3530
-					}
3531
-					$j++;
3532
-				}
3533
-				if($ko)
3534
-				{
3535
-					$xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcStruct']);
3536
-				}
3537
-				else
3538
-				{
3539
-					$xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcArray']);
3540
-				}
3541
-				break;
3542
-			case 'object':
3543
-				if(is_a($php_val, 'xmlrpcval'))
3544
-				{
3545
-					$xmlrpc_val = $php_val;
3546
-				}
3547
-				else if(is_a($php_val, 'DateTime'))
3548
-				{
3549
-					$xmlrpc_val = new xmlrpcval($php_val->format('Ymd\TH:i:s'), $GLOBALS['xmlrpcStruct']);
3550
-				}
3551
-				else
3552
-				{
3553
-					$arr = array();
3554
-					reset($php_val);
3555
-					while(list($k,$v) = each($php_val))
3556
-					{
3557
-						$arr[$k] = php_xmlrpc_encode($v, $options);
3558
-					}
3559
-					$xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcStruct']);
3560
-					if (in_array('encode_php_objs', $options))
3561
-					{
3562
-						// let's save original class name into xmlrpcval:
3563
-						// might be useful later on...
3564
-						$xmlrpc_val->_php_class = get_class($php_val);
3565
-					}
3566
-				}
3567
-				break;
3568
-			case 'NULL':
3569
-				if (in_array('extension_api', $options))
3570
-				{
3571
-					$xmlrpc_val = new xmlrpcval('', $GLOBALS['xmlrpcString']);
3572
-				}
3573
-				else if (in_array('null_extension', $options))
3574
-				{
3575
-					$xmlrpc_val = new xmlrpcval('', $GLOBALS['xmlrpcNull']);
3576
-				}
3577
-				else
3578
-				{
3579
-					$xmlrpc_val = new xmlrpcval();
3580
-				}
3581
-				break;
3582
-			case 'resource':
3583
-				if (in_array('extension_api', $options))
3584
-				{
3585
-					$xmlrpc_val = new xmlrpcval((int)$php_val, $GLOBALS['xmlrpcInt']);
3586
-				}
3587
-				else
3588
-				{
3589
-					$xmlrpc_val = new xmlrpcval();
3590
-				}
3591
-			// catch "user function", "unknown type"
3592
-			default:
3593
-				// giancarlo pinerolo <[email protected]>
3594
-				// it has to return
3595
-				// an empty object in case, not a boolean.
3596
-				$xmlrpc_val = new xmlrpcval();
3597
-				break;
3598
-			}
3599
-			return $xmlrpc_val;
3600
-	}
3601
-
3602
-	/**
3603
-	* Convert the xml representation of a method response, method request or single
3604
-	* xmlrpc value into the appropriate object (a.k.a. deserialize)
3605
-	* @param string $xml_val
3606
-	* @param array $options
3607
-	* @return mixed false on error, or an instance of either xmlrpcval, xmlrpcmsg or xmlrpcresp
3608
-	*/
3609
-	function php_xmlrpc_decode_xml($xml_val, $options=array())
3610
-	{
3611
-		$GLOBALS['_xh'] = array();
3612
-		$GLOBALS['_xh']['ac'] = '';
3613
-		$GLOBALS['_xh']['stack'] = array();
3614
-		$GLOBALS['_xh']['valuestack'] = array();
3615
-		$GLOBALS['_xh']['params'] = array();
3616
-		$GLOBALS['_xh']['pt'] = array();
3617
-		$GLOBALS['_xh']['isf'] = 0;
3618
-		$GLOBALS['_xh']['isf_reason'] = '';
3619
-		$GLOBALS['_xh']['method'] = false;
3620
-		$GLOBALS['_xh']['rt'] = '';
3621
-
3622
-		// 'guestimate' encoding
3623
-		$val_encoding = guess_encoding('', $xml_val);
3624
-
3625
-		// Since parsing will fail if charset is not specified in the xml prologue,
3626
-		// the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
3627
-		// The following code might be better for mb_string enabled installs, but
3628
-		// makes the lib about 200% slower...
3629
-		//if (!is_valid_charset($val_encoding, array('UTF-8')))
3630
-		if (!in_array($val_encoding, array('UTF-8', 'US-ASCII')) && !has_encoding($xml_val)) {
3631
-			if ($val_encoding == 'ISO-8859-1') {
3632
-				$xml_val = utf8_encode($xml_val);
3633
-			} else {
3634
-				if (extension_loaded('mbstring')) {
3635
-					$xml_val = mb_convert_encoding($xml_val, 'UTF-8', $val_encoding);
3636
-				} else {
3637
-					error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $val_encoding);
3638
-				}
3639
-			}
3640
-		}
3641
-
3642
-		$parser = xml_parser_create();
3643
-		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
3644
-		// What if internal encoding is not in one of the 3 allowed?
3645
-		// we use the broadest one, ie. utf8!
3646
-		if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
3647
-		{
3648
-			xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
3649
-		}
3650
-		else
3651
-		{
3652
-			xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
3653
-		}
3654
-		xml_set_element_handler($parser, 'xmlrpc_se_any', 'xmlrpc_ee');
3655
-		xml_set_character_data_handler($parser, 'xmlrpc_cd');
3656
-		xml_set_default_handler($parser, 'xmlrpc_dh');
3657
-		if(!xml_parse($parser, $xml_val, 1))
3658
-		{
3659
-			$errstr = sprintf('XML error: %s at line %d, column %d',
3660
-						xml_error_string(xml_get_error_code($parser)),
3661
-						xml_get_current_line_number($parser), xml_get_current_column_number($parser));
3662
-			error_log($errstr);
3663
-			xml_parser_free($parser);
3664
-			return false;
3665
-		}
3666
-		xml_parser_free($parser);
3667
-		if ($GLOBALS['_xh']['isf'] > 1) // test that $GLOBALS['_xh']['value'] is an obj, too???
3668
-		{
3669
-			error_log($GLOBALS['_xh']['isf_reason']);
3670
-			return false;
3671
-		}
3672
-		switch ($GLOBALS['_xh']['rt'])
3673
-		{
3674
-			case 'methodresponse':
3675
-				$v =& $GLOBALS['_xh']['value'];
3676
-				if ($GLOBALS['_xh']['isf'] == 1)
3677
-				{
3678
-					$vc = $v->structmem('faultCode');
3679
-					$vs = $v->structmem('faultString');
3680
-					$r = new xmlrpcresp(0, $vc->scalarval(), $vs->scalarval());
3681
-				}
3682
-				else
3683
-				{
3684
-					$r = new xmlrpcresp($v);
3685
-				}
3686
-				return $r;
3687
-			case 'methodcall':
3688
-				$m = new xmlrpcmsg($GLOBALS['_xh']['method']);
3689
-				for($i=0; $i < count($GLOBALS['_xh']['params']); $i++)
3690
-				{
3691
-					$m->addParam($GLOBALS['_xh']['params'][$i]);
3692
-				}
3693
-				return $m;
3694
-			case 'value':
3695
-				return $GLOBALS['_xh']['value'];
3696
-			default:
3697
-				return false;
3698
-		}
3699
-	}
3700
-
3701
-	/**
3702
-	* decode a string that is encoded w/ "chunked" transfer encoding
3703
-	* as defined in rfc2068 par. 19.4.6
3704
-	* code shamelessly stolen from nusoap library by Dietrich Ayala
3705
-	*
3706
-	* @param string $buffer the string to be decoded
3707
-	* @return string
3708
-	*/
3709
-	function decode_chunked($buffer)
3710
-	{
3711
-		// length := 0
3712
-		$length = 0;
3713
-		$new = '';
3714
-
3715
-		// read chunk-size, chunk-extension (if any) and crlf
3716
-		// get the position of the linebreak
3717
-		$chunkend = strpos($buffer,"\r\n") + 2;
3718
-		$temp = substr($buffer,0,$chunkend);
3719
-		$chunk_size = hexdec( trim($temp) );
3720
-		$chunkstart = $chunkend;
3721
-		while($chunk_size > 0)
3722
-		{
3723
-			$chunkend = strpos($buffer, "\r\n", $chunkstart + $chunk_size);
3724
-
3725
-			// just in case we got a broken connection
3726
-			if($chunkend == false)
3727
-			{
3728
-				$chunk = substr($buffer,$chunkstart);
3729
-				// append chunk-data to entity-body
3730
-				$new .= $chunk;
3731
-				$length += strlen($chunk);
3732
-				break;
3733
-			}
3734
-
3735
-			// read chunk-data and crlf
3736
-			$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
3737
-			// append chunk-data to entity-body
3738
-			$new .= $chunk;
3739
-			// length := length + chunk-size
3740
-			$length += strlen($chunk);
3741
-			// read chunk-size and crlf
3742
-			$chunkstart = $chunkend + 2;
3743
-
3744
-			$chunkend = strpos($buffer,"\r\n",$chunkstart)+2;
3745
-			if($chunkend == false)
3746
-			{
3747
-				break; //just in case we got a broken connection
3748
-			}
3749
-			$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
3750
-			$chunk_size = hexdec( trim($temp) );
3751
-			$chunkstart = $chunkend;
3752
-		}
3753
-		return $new;
3754
-	}
3755
-
3756
-	/**
3757
-	* xml charset encoding guessing helper function.
3758
-	* Tries to determine the charset encoding of an XML chunk received over HTTP.
3759
-	* NB: according to the spec (RFC 3023), if text/xml content-type is received over HTTP without a content-type,
3760
-	* we SHOULD assume it is strictly US-ASCII. But we try to be more tolerant of unconforming (legacy?) clients/servers,
3761
-	* which will be most probably using UTF-8 anyway...
3762
-	*
3763
-	* @param string $httpheader the http Content-type header
3764
-	* @param string $xmlchunk xml content buffer
3765
-	* @param string $encoding_prefs comma separated list of character encodings to be used as default (when mb extension is enabled)
3766
-	* @return string
3767
-	*
3768
-	* @todo explore usage of mb_http_input(): does it detect http headers + post data? if so, use it instead of hand-detection!!!
3769
-	*/
3770
-	function guess_encoding($httpheader='', $xmlchunk='', $encoding_prefs=null)
3771
-	{
3772
-		// discussion: see http://www.yale.edu/pclt/encoding/
3773
-		// 1 - test if encoding is specified in HTTP HEADERS
3774
-
3775
-		//Details:
3776
-		// LWS:           (\13\10)?( |\t)+
3777
-		// token:         (any char but excluded stuff)+
3778
-		// quoted string: " (any char but double quotes and cointrol chars)* "
3779
-		// header:        Content-type = ...; charset=value(; ...)*
3780
-		//   where value is of type token, no LWS allowed between 'charset' and value
3781
-		// Note: we do not check for invalid chars in VALUE:
3782
-		//   this had better be done using pure ereg as below
3783
-		// Note 2: we might be removing whitespace/tabs that ought to be left in if
3784
-		//   the received charset is a quoted string. But nobody uses such charset names...
3785
-
3786
-		/// @todo this test will pass if ANY header has charset specification, not only Content-Type. Fix it?
3787
-		$matches = array();
3788
-		if(preg_match('/;\s*charset\s*=([^;]+)/i', $httpheader, $matches))
3789
-		{
3790
-			return strtoupper(trim($matches[1], " \t\""));
3791
-		}
3792
-
3793
-		// 2 - scan the first bytes of the data for a UTF-16 (or other) BOM pattern
3794
-		//     (source: http://www.w3.org/TR/2000/REC-xml-20001006)
3795
-		//     NOTE: actually, according to the spec, even if we find the BOM and determine
3796
-		//     an encoding, we should check if there is an encoding specified
3797
-		//     in the xml declaration, and verify if they match.
3798
-		/// @todo implement check as described above?
3799
-		/// @todo implement check for first bytes of string even without a BOM? (It sure looks harder than for cases WITH a BOM)
3800
-		if(preg_match('/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x00\x00\xFF\xFE|\xFE\xFF\x00\x00)/', $xmlchunk))
3801
-		{
3802
-			return 'UCS-4';
3803
-		}
3804
-		elseif(preg_match('/^(\xFE\xFF|\xFF\xFE)/', $xmlchunk))
3805
-		{
3806
-			return 'UTF-16';
3807
-		}
3808
-		elseif(preg_match('/^(\xEF\xBB\xBF)/', $xmlchunk))
3809
-		{
3810
-			return 'UTF-8';
3811
-		}
3812
-
3813
-		// 3 - test if encoding is specified in the xml declaration
3814
-		// Details:
3815
-		// SPACE:         (#x20 | #x9 | #xD | #xA)+ === [ \x9\xD\xA]+
3816
-		// EQ:            SPACE?=SPACE? === [ \x9\xD\xA]*=[ \x9\xD\xA]*
3817
-		if (preg_match('/^<\?xml\s+version\s*=\s*'. "((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))".
3818
-			'\s+encoding\s*=\s*' . "((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3819
-			$xmlchunk, $matches))
3820
-		{
3821
-			return strtoupper(substr($matches[2], 1, -1));
3822
-		}
3823
-
3824
-		// 4 - if mbstring is available, let it do the guesswork
3825
-		// NB: we favour finding an encoding that is compatible with what we can process
3826
-		if(extension_loaded('mbstring'))
3827
-		{
3828
-			if($encoding_prefs)
3829
-			{
3830
-				$enc = mb_detect_encoding($xmlchunk, $encoding_prefs);
3831
-			}
3832
-			else
3833
-			{
3834
-				$enc = mb_detect_encoding($xmlchunk);
3835
-			}
3836
-			// NB: mb_detect likes to call it ascii, xml parser likes to call it US_ASCII...
3837
-			// IANA also likes better US-ASCII, so go with it
3838
-			if($enc == 'ASCII')
3839
-			{
3840
-				$enc = 'US-'.$enc;
3841
-			}
3842
-			return $enc;
3843
-		}
3844
-		else
3845
-		{
3846
-			// no encoding specified: as per HTTP1.1 assume it is iso-8859-1?
3847
-			// Both RFC 2616 (HTTP 1.1) and 1945 (HTTP 1.0) clearly state that for text/xxx content types
3848
-			// this should be the standard. And we should be getting text/xml as request and response.
3849
-			// BUT we have to be backward compatible with the lib, which always used UTF-8 as default...
3850
-			return $GLOBALS['xmlrpc_defencoding'];
3851
-		}
3852
-	}
3853
-
3854
-	/**
3855
-	 * Helper function: checks if an xml chunk as a charset declaration (BOM or in the xml declaration)
3856
-	 *
3857
-	 * @param string $xmlChunk
3858
-	 * @return bool
3859
-	 */
3860
-	function has_encoding($xmlChunk)
3861
-	{
3862
-		// scan the first bytes of the data for a UTF-16 (or other) BOM pattern
3863
-		//	 (source: http://www.w3.org/TR/2000/REC-xml-20001006)
3864
-		if (preg_match('/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x00\x00\xFF\xFE|\xFE\xFF\x00\x00)/', $xmlChunk))
3865
-		{
3866
-			return true;
3867
-		}
3868
-		elseif (preg_match('/^(\xFE\xFF|\xFF\xFE)/', $xmlChunk))
3869
-		{
3870
-			return true;
3871
-		}
3872
-		elseif (preg_match('/^(\xEF\xBB\xBF)/', $xmlChunk))
3873
-		{
3874
-			return true;
3875
-		}
3876
-
3877
-		// test if encoding is specified in the xml declaration
3878
-		// Details:
3879
-		// SPACE:		(#x20 | #x9 | #xD | #xA)+ === [ \x9\xD\xA]+
3880
-		// EQ:			SPACE?=SPACE? === [ \x9\xD\xA]*=[ \x9\xD\xA]*
3881
-		if (preg_match('/^<\?xml\s+version\s*=\s*' . "((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))" .
3882
-			'\s+encoding\s*=\s*' . "((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3883
-			$xmlChunk, $matches))
3884
-		{
3885
-			return true;
3886
-		}
3887
-
3888
-		return false;
3889
-	}
3890
-
3891
-	/**
3892
-	* Checks if a given charset encoding is present in a list of encodings or
3893
-	* if it is a valid subset of any encoding in the list
3894
-	* @param string $encoding charset to be tested
3895
-	* @param mixed $validlist comma separated list of valid charsets (or array of charsets)
3896
-	* @return bool
3897
-	*/
3898
-	function is_valid_charset($encoding, $validlist)
3899
-	{
3900
-		$charset_supersets = array(
3901
-			'US-ASCII' => array ('ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
3902
-				'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8',
3903
-				'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-12',
3904
-				'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'UTF-8',
3905
-				'EUC-JP', 'EUC-', 'EUC-KR', 'EUC-CN')
3906
-		);
3907
-		if (is_string($validlist))
3908
-			$validlist = explode(',', $validlist);
3909
-		if (@in_array(strtoupper($encoding), $validlist))
3910
-			return true;
3911
-		else
3912
-		{
3913
-			if (array_key_exists($encoding, $charset_supersets))
3914
-				foreach ($validlist as $allowed)
3915
-					if (in_array($allowed, $charset_supersets[$encoding]))
3916
-						return true;
3917
-			return false;
3918
-		}
3919
-	}
2847
+            }
2848
+        }
2849
+
2850
+        /**
2851
+         * @deprecated
2852
+         */
2853
+        function xmlrpcval($val=-1, $type='')
2854
+        {
2855
+            self::__construct($val, $type);
2856
+        }
2857
+
2858
+        /**
2859
+         * Add a single php value to an (unitialized) xmlrpcval
2860
+         * @param mixed $val
2861
+         * @param string $type
2862
+         * @return int 1 or 0 on failure
2863
+         */
2864
+        function addScalar($val, $type='string')
2865
+        {
2866
+            $typeof=@$GLOBALS['xmlrpcTypes'][$type];
2867
+            if($typeof!=1)
2868
+            {
2869
+                error_log("XML-RPC: ".__METHOD__.": not a scalar type ($type)");
2870
+                return 0;
2871
+            }
2872
+
2873
+            // coerce booleans into correct values
2874
+            // NB: we should either do it for datetimes, integers and doubles, too,
2875
+            // or just plain remove this check, implemented on booleans only...
2876
+            if($type==$GLOBALS['xmlrpcBoolean'])
2877
+            {
2878
+                if(strcasecmp($val,'true')==0 || $val==1 || ($val==true && strcasecmp($val,'false')))
2879
+                {
2880
+                    $val=true;
2881
+                }
2882
+                else
2883
+                {
2884
+                    $val=false;
2885
+                }
2886
+            }
2887
+
2888
+            switch($this->mytype)
2889
+            {
2890
+                case 1:
2891
+                    error_log('XML-RPC: '.__METHOD__.': scalar xmlrpcval can have only one value');
2892
+                    return 0;
2893
+                case 3:
2894
+                    error_log('XML-RPC: '.__METHOD__.': cannot add anonymous scalar to struct xmlrpcval');
2895
+                    return 0;
2896
+                case 2:
2897
+                    // we're adding a scalar value to an array here
2898
+                    //$ar=$this->me['array'];
2899
+                    //$ar[]=new xmlrpcval($val, $type);
2900
+                    //$this->me['array']=$ar;
2901
+                    // Faster (?) avoid all the costly array-copy-by-val done here...
2902
+                    $this->me['array'][]=new xmlrpcval($val, $type);
2903
+                    return 1;
2904
+                default:
2905
+                    // a scalar, so set the value and remember we're scalar
2906
+                    $this->me[$type]=$val;
2907
+                    $this->mytype=$typeof;
2908
+                    return 1;
2909
+            }
2910
+        }
2911
+
2912
+        /**
2913
+         * Add an array of xmlrpcval objects to an xmlrpcval
2914
+         * @param array $vals
2915
+         * @return int 1 or 0 on failure
2916
+         * @access public
2917
+         *
2918
+         * @todo add some checking for $vals to be an array of xmlrpcvals?
2919
+         */
2920
+        function addArray($vals)
2921
+        {
2922
+            if($this->mytype==0)
2923
+            {
2924
+                $this->mytype=$GLOBALS['xmlrpcTypes']['array'];
2925
+                $this->me['array']=$vals;
2926
+                return 1;
2927
+            }
2928
+            elseif($this->mytype==2)
2929
+            {
2930
+                // we're adding to an array here
2931
+                $this->me['array'] = array_merge($this->me['array'], $vals);
2932
+                return 1;
2933
+            }
2934
+            else
2935
+            {
2936
+                error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');
2937
+                return 0;
2938
+            }
2939
+        }
2940
+
2941
+        /**
2942
+         * Add an array of named xmlrpcval objects to an xmlrpcval
2943
+         * @param array $vals
2944
+         * @return int 1 or 0 on failure
2945
+         * @access public
2946
+         *
2947
+         * @todo add some checking for $vals to be an array?
2948
+         */
2949
+        function addStruct($vals)
2950
+        {
2951
+            if($this->mytype==0)
2952
+            {
2953
+                $this->mytype=$GLOBALS['xmlrpcTypes']['struct'];
2954
+                $this->me['struct']=$vals;
2955
+                return 1;
2956
+            }
2957
+            elseif($this->mytype==3)
2958
+            {
2959
+                // we're adding to a struct here
2960
+                $this->me['struct'] = array_merge($this->me['struct'], $vals);
2961
+                return 1;
2962
+            }
2963
+            else
2964
+            {
2965
+                error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');
2966
+                return 0;
2967
+            }
2968
+        }
2969
+
2970
+        // poor man's version of print_r ???
2971
+        // DEPRECATED!
2972
+        function dump($ar)
2973
+        {
2974
+            foreach($ar as $key => $val)
2975
+            {
2976
+                echo "$key => $val<br />";
2977
+                if($key == 'array')
2978
+                {
2979
+                    while(list($key2, $val2) = each($val))
2980
+                    {
2981
+                        echo "-- $key2 => $val2<br />";
2982
+                    }
2983
+                }
2984
+            }
2985
+        }
2986
+
2987
+        /**
2988
+         * Returns a string containing "struct", "array" or "scalar" describing the base type of the value
2989
+         * @return string
2990
+         * @access public
2991
+         */
2992
+        function kindOf()
2993
+        {
2994
+            switch($this->mytype)
2995
+            {
2996
+                case 3:
2997
+                    return 'struct';
2998
+                    break;
2999
+                case 2:
3000
+                    return 'array';
3001
+                    break;
3002
+                case 1:
3003
+                    return 'scalar';
3004
+                    break;
3005
+                default:
3006
+                    return 'undef';
3007
+            }
3008
+        }
3009
+
3010
+        /**
3011
+         * @access private
3012
+         */
3013
+        function serializedata($typ, $val, $charset_encoding='')
3014
+        {
3015
+            $rs='';
3016
+            switch(@$GLOBALS['xmlrpcTypes'][$typ])
3017
+            {
3018
+                case 1:
3019
+                    switch($typ)
3020
+                    {
3021
+                        case $GLOBALS['xmlrpcBase64']:
3022
+                            $rs.="<${typ}>" . base64_encode($val) . "</${typ}>";
3023
+                            break;
3024
+                        case $GLOBALS['xmlrpcBoolean']:
3025
+                            $rs.="<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
3026
+                            break;
3027
+                        case $GLOBALS['xmlrpcString']:
3028
+                            // G. Giunta 2005/2/13: do NOT use htmlentities, since
3029
+                            // it will produce named html entities, which are invalid xml
3030
+                            $rs.="<${typ}>" . xmlrpc_encode_entitites($val, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding). "</${typ}>";
3031
+                            break;
3032
+                        case $GLOBALS['xmlrpcInt']:
3033
+                        case $GLOBALS['xmlrpcI4']:
3034
+                            $rs.="<${typ}>".(int)$val."</${typ}>";
3035
+                            break;
3036
+                        case $GLOBALS['xmlrpcDouble']:
3037
+                            // avoid using standard conversion of float to string because it is locale-dependent,
3038
+                            // and also because the xmlrpc spec forbids exponential notation.
3039
+                            // sprintf('%F') could be most likely ok but it fails eg. on 2e-14.
3040
+                            // The code below tries its best at keeping max precision while avoiding exp notation,
3041
+                            // but there is of course no limit in the number of decimal places to be used...
3042
+                            $rs.="<${typ}>".preg_replace('/\\.?0+$/','',number_format((double)$val, 128, '.', ''))."</${typ}>";
3043
+                            break;
3044
+                        case $GLOBALS['xmlrpcDateTime']:
3045
+                            if (is_string($val))
3046
+                            {
3047
+                                $rs.="<${typ}>${val}</${typ}>";
3048
+                            }
3049
+                            else if(is_a($val, 'DateTime'))
3050
+                            {
3051
+                                $rs.="<${typ}>".$val->format('Ymd\TH:i:s')."</${typ}>";
3052
+                            }
3053
+                            else if(is_int($val))
3054
+                            {
3055
+                                $rs.="<${typ}>".strftime("%Y%m%dT%H:%M:%S", $val)."</${typ}>";
3056
+                            }
3057
+                            else
3058
+                            {
3059
+                                // not really a good idea here: but what shall we output anyway? left for backward compat...
3060
+                                $rs.="<${typ}>${val}</${typ}>";
3061
+                            }
3062
+                            break;
3063
+                        case $GLOBALS['xmlrpcNull']:
3064
+                            if ($GLOBALS['xmlrpc_null_apache_encoding'])
3065
+                            {
3066
+                                $rs.="<ex:nil/>";
3067
+                            }
3068
+                            else
3069
+                            {
3070
+                                $rs.="<nil/>";
3071
+                            }
3072
+                            break;
3073
+                        default:
3074
+                            // no standard type value should arrive here, but provide a possibility
3075
+                            // for xmlrpcvals of unknown type...
3076
+                            $rs.="<${typ}>${val}</${typ}>";
3077
+                    }
3078
+                    break;
3079
+                case 3:
3080
+                    // struct
3081
+                    if ($this->_php_class)
3082
+                    {
3083
+                        $rs.='<struct php_class="' . $this->_php_class . "\">\n";
3084
+                    }
3085
+                    else
3086
+                    {
3087
+                        $rs.="<struct>\n";
3088
+                    }
3089
+                    foreach($val as $key2 => $val2)
3090
+                    {
3091
+                        $rs.='<member><name>'.xmlrpc_encode_entitites($key2, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</name>\n";
3092
+                        //$rs.=$this->serializeval($val2);
3093
+                        $rs.=$val2->serialize($charset_encoding);
3094
+                        $rs.="</member>\n";
3095
+                    }
3096
+                    $rs.='</struct>';
3097
+                    break;
3098
+                case 2:
3099
+                    // array
3100
+                    $rs.="<array>\n<data>\n";
3101
+                    for($i=0; $i<count($val); $i++)
3102
+                    {
3103
+                        //$rs.=$this->serializeval($val[$i]);
3104
+                        $rs.=$val[$i]->serialize($charset_encoding);
3105
+                    }
3106
+                    $rs.="</data>\n</array>";
3107
+                    break;
3108
+                default:
3109
+                    break;
3110
+            }
3111
+            return $rs;
3112
+        }
3113
+
3114
+        /**
3115
+         * Returns xml representation of the value. XML prologue not included
3116
+         * @param string $charset_encoding the charset to be used for serialization. if null, US-ASCII is assumed
3117
+         * @return string
3118
+         * @access public
3119
+         */
3120
+        function serialize($charset_encoding='')
3121
+        {
3122
+            // add check? slower, but helps to avoid recursion in serializing broken xmlrpcvals...
3123
+            //if (is_object($o) && (get_class($o) == 'xmlrpcval' || is_subclass_of($o, 'xmlrpcval')))
3124
+            //{
3125
+                $val = reset($this->me);
3126
+                $typ = key($this->me);
3127
+                return '<value>' . $this->serializedata($typ, $val, $charset_encoding) . "</value>\n";
3128
+            //}
3129
+        }
3130
+
3131
+        // DEPRECATED
3132
+        function serializeval($o)
3133
+        {
3134
+            // add check? slower, but helps to avoid recursion in serializing broken xmlrpcvals...
3135
+            //if (is_object($o) && (get_class($o) == 'xmlrpcval' || is_subclass_of($o, 'xmlrpcval')))
3136
+            //{
3137
+                $val = reset($o->me);
3138
+                $typ = key($o->me);
3139
+                return '<value>' . $this->serializedata($typ, $val) . "</value>\n";
3140
+            //}
3141
+        }
3142
+
3143
+        /**
3144
+         * Checks whether a struct member with a given name is present.
3145
+         * Works only on xmlrpcvals of type struct.
3146
+         * @param string $m the name of the struct member to be looked up
3147
+         * @return boolean
3148
+         * @access public
3149
+         */
3150
+        function structmemexists($m)
3151
+        {
3152
+            return array_key_exists($m, $this->me['struct']);
3153
+        }
3154
+
3155
+        /**
3156
+         * Returns the value of a given struct member (an xmlrpcval object in itself).
3157
+         * Will raise a php warning if struct member of given name does not exist
3158
+         * @param string $m the name of the struct member to be looked up
3159
+         * @return xmlrpcval
3160
+         * @access public
3161
+         */
3162
+        function structmem($m)
3163
+        {
3164
+            return $this->me['struct'][$m];
3165
+        }
3166
+
3167
+        /**
3168
+         * Reset internal pointer for xmlrpcvals of type struct.
3169
+         * @access public
3170
+         */
3171
+        function structreset()
3172
+        {
3173
+            reset($this->me['struct']);
3174
+        }
3175
+
3176
+        /**
3177
+         * Return next member element for xmlrpcvals of type struct.
3178
+         * @return xmlrpcval
3179
+         * @access public
3180
+         */
3181
+        function structeach()
3182
+        {
3183
+            return each($this->me['struct']);
3184
+        }
3185
+
3186
+        // DEPRECATED! this code looks like it is very fragile and has not been fixed
3187
+        // for a long long time. Shall we remove it for 2.0?
3188
+        function getval()
3189
+        {
3190
+            // UNSTABLE
3191
+            reset($this->me);
3192
+            list($a,$b)=each($this->me);
3193
+            // contributed by I Sofer, 2001-03-24
3194
+            // add support for nested arrays to scalarval
3195
+            // i've created a new method here, so as to
3196
+            // preserve back compatibility
3197
+
3198
+            if(is_array($b))
3199
+            {
3200
+                @reset($b);
3201
+                while(list($id,$cont) = @each($b))
3202
+                {
3203
+                    $b[$id] = $cont->scalarval();
3204
+                }
3205
+            }
3206
+
3207
+            // add support for structures directly encoding php objects
3208
+            if(is_object($b))
3209
+            {
3210
+                $t = get_object_vars($b);
3211
+                @reset($t);
3212
+                while(list($id,$cont) = @each($t))
3213
+                {
3214
+                    $t[$id] = $cont->scalarval();
3215
+                }
3216
+                @reset($t);
3217
+                while(list($id,$cont) = @each($t))
3218
+                {
3219
+                    @$b->$id = $cont;
3220
+                }
3221
+            }
3222
+            // end contrib
3223
+            return $b;
3224
+        }
3225
+
3226
+        /**
3227
+         * Returns the value of a scalar xmlrpcval
3228
+         * @return mixed
3229
+         * @access public
3230
+         */
3231
+        function scalarval()
3232
+        {
3233
+            reset($this->me);
3234
+            list(,$b)=each($this->me);
3235
+            return $b;
3236
+        }
3237
+
3238
+        /**
3239
+         * Returns the type of the xmlrpcval.
3240
+         * For integers, 'int' is always returned in place of 'i4'
3241
+         * @return string
3242
+         * @access public
3243
+         */
3244
+        function scalartyp()
3245
+        {
3246
+            reset($this->me);
3247
+            list($a,)=each($this->me);
3248
+            if($a==$GLOBALS['xmlrpcI4'])
3249
+            {
3250
+                $a=$GLOBALS['xmlrpcInt'];
3251
+            }
3252
+            return $a;
3253
+        }
3254
+
3255
+        /**
3256
+         * Returns the m-th member of an xmlrpcval of struct type
3257
+         * @param integer $m the index of the value to be retrieved (zero based)
3258
+         * @return xmlrpcval
3259
+         * @access public
3260
+         */
3261
+        function arraymem($m)
3262
+        {
3263
+            return $this->me['array'][$m];
3264
+        }
3265
+
3266
+        /**
3267
+         * Returns the number of members in an xmlrpcval of array type
3268
+         * @return integer
3269
+         * @access public
3270
+         */
3271
+        function arraysize()
3272
+        {
3273
+            return count($this->me['array']);
3274
+        }
3275
+
3276
+        /**
3277
+         * Returns the number of members in an xmlrpcval of struct type
3278
+         * @return integer
3279
+         * @access public
3280
+         */
3281
+        function structsize()
3282
+        {
3283
+            return count($this->me['struct']);
3284
+        }
3285
+    }
3286
+
3287
+
3288
+    // date helpers
3289
+
3290
+    /**
3291
+     * Given a timestamp, return the corresponding ISO8601 encoded string.
3292
+     *
3293
+     * Really, timezones ought to be supported
3294
+     * but the XML-RPC spec says:
3295
+     *
3296
+     * "Don't assume a timezone. It should be specified by the server in its
3297
+     * documentation what assumptions it makes about timezones."
3298
+     *
3299
+     * These routines always assume localtime unless
3300
+     * $utc is set to 1, in which case UTC is assumed
3301
+     * and an adjustment for locale is made when encoding
3302
+     *
3303
+     * @param int $timet (timestamp)
3304
+     * @param int $utc (0 or 1)
3305
+     * @return string
3306
+     */
3307
+    function iso8601_encode($timet, $utc=0)
3308
+    {
3309
+        if(!$utc)
3310
+        {
3311
+            $t=strftime("%Y%m%dT%H:%M:%S", $timet);
3312
+        }
3313
+        else
3314
+        {
3315
+            if(function_exists('gmstrftime'))
3316
+            {
3317
+                // gmstrftime doesn't exist in some versions
3318
+                // of PHP
3319
+                $t=gmstrftime("%Y%m%dT%H:%M:%S", $timet);
3320
+            }
3321
+            else
3322
+            {
3323
+                $t=strftime("%Y%m%dT%H:%M:%S", $timet-date('Z'));
3324
+            }
3325
+        }
3326
+        return $t;
3327
+    }
3328
+
3329
+    /**
3330
+     * Given an ISO8601 date string, return a timet in the localtime, or UTC
3331
+     * @param string $idate
3332
+     * @param int $utc either 0 or 1
3333
+     * @return int (datetime)
3334
+     */
3335
+    function iso8601_decode($idate, $utc=0)
3336
+    {
3337
+        $t=0;
3338
+        if(preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $idate, $regs))
3339
+        {
3340
+            if($utc)
3341
+            {
3342
+                $t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3343
+            }
3344
+            else
3345
+            {
3346
+                $t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3347
+            }
3348
+        }
3349
+        return $t;
3350
+    }
3351
+
3352
+    /**
3353
+     * Takes an xmlrpc value in PHP xmlrpcval object format and translates it into native PHP types.
3354
+     *
3355
+     * Works with xmlrpc message objects as input, too.
3356
+     *
3357
+     * Given proper options parameter, can rebuild generic php object instances
3358
+     * (provided those have been encoded to xmlrpc format using a corresponding
3359
+     * option in php_xmlrpc_encode())
3360
+     * PLEASE NOTE that rebuilding php objects involves calling their constructor function.
3361
+     * This means that the remote communication end can decide which php code will
3362
+     * get executed on your server, leaving the door possibly open to 'php-injection'
3363
+     * style of attacks (provided you have some classes defined on your server that
3364
+     * might wreak havoc if instances are built outside an appropriate context).
3365
+     * Make sure you trust the remote server/client before eanbling this!
3366
+     *
3367
+     * @author Dan Libby ([email protected])
3368
+     *
3369
+     * @param xmlrpcval $xmlrpc_val
3370
+     * @param array $options if 'decode_php_objs' is set in the options array, xmlrpc structs can be decoded into php objects; if 'dates_as_objects' is set xmlrpc datetimes are decoded as php DateTime objects (standard is
3371
+     * @return mixed
3372
+     */
3373
+    function php_xmlrpc_decode($xmlrpc_val, $options=array())
3374
+    {
3375
+        switch($xmlrpc_val->kindOf())
3376
+        {
3377
+            case 'scalar':
3378
+                if (in_array('extension_api', $options))
3379
+                {
3380
+                    reset($xmlrpc_val->me);
3381
+                    list($typ,$val) = each($xmlrpc_val->me);
3382
+                    switch ($typ)
3383
+                    {
3384
+                        case 'dateTime.iso8601':
3385
+                            $xmlrpc_val->scalar = $val;
3386
+                            $xmlrpc_val->xmlrpc_type = 'datetime';
3387
+                            $xmlrpc_val->timestamp = iso8601_decode($val);
3388
+                            return $xmlrpc_val;
3389
+                        case 'base64':
3390
+                            $xmlrpc_val->scalar = $val;
3391
+                            $xmlrpc_val->type = $typ;
3392
+                            return $xmlrpc_val;
3393
+                        default:
3394
+                            return $xmlrpc_val->scalarval();
3395
+                    }
3396
+                }
3397
+                if (in_array('dates_as_objects', $options) && $xmlrpc_val->scalartyp() == 'dateTime.iso8601')
3398
+                {
3399
+                    // we return a Datetime object instead of a string
3400
+                    // since now the constructor of xmlrpcval accepts safely strings, ints and datetimes,
3401
+                    // we cater to all 3 cases here
3402
+                    $out = $xmlrpc_val->scalarval();
3403
+                    if (is_string($out))
3404
+                    {
3405
+                        $out = strtotime($out);
3406
+                    }
3407
+                    if (is_int($out))
3408
+                    {
3409
+                        $result = new Datetime();
3410
+                        $result->setTimestamp($out);
3411
+                        return $result;
3412
+                    }
3413
+                    elseif (is_a($out, 'Datetime'))
3414
+                    {
3415
+                        return $out;
3416
+                    }
3417
+                }
3418
+                return $xmlrpc_val->scalarval();
3419
+            case 'array':
3420
+                $size = $xmlrpc_val->arraysize();
3421
+                $arr = array();
3422
+                for($i = 0; $i < $size; $i++)
3423
+                {
3424
+                    $arr[] = php_xmlrpc_decode($xmlrpc_val->arraymem($i), $options);
3425
+                }
3426
+                return $arr;
3427
+            case 'struct':
3428
+                $xmlrpc_val->structreset();
3429
+                // If user said so, try to rebuild php objects for specific struct vals.
3430
+                /// @todo should we raise a warning for class not found?
3431
+                // shall we check for proper subclass of xmlrpcval instead of
3432
+                // presence of _php_class to detect what we can do?
3433
+                if (in_array('decode_php_objs', $options) && $xmlrpc_val->_php_class != ''
3434
+                    && class_exists($xmlrpc_val->_php_class))
3435
+                {
3436
+                    $obj = @new $xmlrpc_val->_php_class;
3437
+                    while(list($key,$value)=$xmlrpc_val->structeach())
3438
+                    {
3439
+                        $obj->$key = php_xmlrpc_decode($value, $options);
3440
+                    }
3441
+                    return $obj;
3442
+                }
3443
+                else
3444
+                {
3445
+                    $arr = array();
3446
+                    while(list($key,$value)=$xmlrpc_val->structeach())
3447
+                    {
3448
+                        $arr[$key] = php_xmlrpc_decode($value, $options);
3449
+                    }
3450
+                    return $arr;
3451
+                }
3452
+            case 'msg':
3453
+                $paramcount = $xmlrpc_val->getNumParams();
3454
+                $arr = array();
3455
+                for($i = 0; $i < $paramcount; $i++)
3456
+                {
3457
+                    $arr[] = php_xmlrpc_decode($xmlrpc_val->getParam($i));
3458
+                }
3459
+                return $arr;
3460
+            }
3461
+    }
3462
+
3463
+    // This constant left here only for historical reasons...
3464
+    // it was used to decide if we have to define xmlrpc_encode on our own, but
3465
+    // we do not do it anymore
3466
+    if(function_exists('xmlrpc_decode'))
3467
+    {
3468
+        define('XMLRPC_EPI_ENABLED','1');
3469
+    }
3470
+    else
3471
+    {
3472
+        define('XMLRPC_EPI_ENABLED','0');
3473
+    }
3474
+
3475
+    /**
3476
+     * Takes native php types and encodes them into xmlrpc PHP object format.
3477
+     * It will not re-encode xmlrpcval objects.
3478
+     *
3479
+     * Feature creep -- could support more types via optional type argument
3480
+     * (string => datetime support has been added, ??? => base64 not yet)
3481
+     *
3482
+     * If given a proper options parameter, php object instances will be encoded
3483
+     * into 'special' xmlrpc values, that can later be decoded into php objects
3484
+     * by calling php_xmlrpc_decode() with a corresponding option
3485
+     *
3486
+     * @author Dan Libby ([email protected])
3487
+     *
3488
+     * @param mixed $php_val the value to be converted into an xmlrpcval object
3489
+     * @param array $options	can include 'encode_php_objs', 'auto_dates', 'null_extension' or 'extension_api'
3490
+     * @return xmlrpcval
3491
+     */
3492
+    function php_xmlrpc_encode($php_val, $options=array())
3493
+    {
3494
+        $type = gettype($php_val);
3495
+        switch($type)
3496
+        {
3497
+            case 'string':
3498
+                if (in_array('auto_dates', $options) && preg_match('/^[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $php_val))
3499
+                    $xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcDateTime']);
3500
+                else
3501
+                    $xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcString']);
3502
+                break;
3503
+            case 'integer':
3504
+                $xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcInt']);
3505
+                break;
3506
+            case 'double':
3507
+                $xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcDouble']);
3508
+                break;
3509
+                // <G_Giunta_2001-02-29>
3510
+                // Add support for encoding/decoding of booleans, since they are supported in PHP
3511
+            case 'boolean':
3512
+                $xmlrpc_val = new xmlrpcval($php_val, $GLOBALS['xmlrpcBoolean']);
3513
+                break;
3514
+                // </G_Giunta_2001-02-29>
3515
+            case 'array':
3516
+                // PHP arrays can be encoded to either xmlrpc structs or arrays,
3517
+                // depending on wheter they are hashes or plain 0..n integer indexed
3518
+                // A shorter one-liner would be
3519
+                // $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
3520
+                // but execution time skyrockets!
3521
+                $j = 0;
3522
+                $arr = array();
3523
+                $ko = false;
3524
+                foreach($php_val as $key => $val)
3525
+                {
3526
+                    $arr[$key] = php_xmlrpc_encode($val, $options);
3527
+                    if(!$ko && $key !== $j)
3528
+                    {
3529
+                        $ko = true;
3530
+                    }
3531
+                    $j++;
3532
+                }
3533
+                if($ko)
3534
+                {
3535
+                    $xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcStruct']);
3536
+                }
3537
+                else
3538
+                {
3539
+                    $xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcArray']);
3540
+                }
3541
+                break;
3542
+            case 'object':
3543
+                if(is_a($php_val, 'xmlrpcval'))
3544
+                {
3545
+                    $xmlrpc_val = $php_val;
3546
+                }
3547
+                else if(is_a($php_val, 'DateTime'))
3548
+                {
3549
+                    $xmlrpc_val = new xmlrpcval($php_val->format('Ymd\TH:i:s'), $GLOBALS['xmlrpcStruct']);
3550
+                }
3551
+                else
3552
+                {
3553
+                    $arr = array();
3554
+                    reset($php_val);
3555
+                    while(list($k,$v) = each($php_val))
3556
+                    {
3557
+                        $arr[$k] = php_xmlrpc_encode($v, $options);
3558
+                    }
3559
+                    $xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcStruct']);
3560
+                    if (in_array('encode_php_objs', $options))
3561
+                    {
3562
+                        // let's save original class name into xmlrpcval:
3563
+                        // might be useful later on...
3564
+                        $xmlrpc_val->_php_class = get_class($php_val);
3565
+                    }
3566
+                }
3567
+                break;
3568
+            case 'NULL':
3569
+                if (in_array('extension_api', $options))
3570
+                {
3571
+                    $xmlrpc_val = new xmlrpcval('', $GLOBALS['xmlrpcString']);
3572
+                }
3573
+                else if (in_array('null_extension', $options))
3574
+                {
3575
+                    $xmlrpc_val = new xmlrpcval('', $GLOBALS['xmlrpcNull']);
3576
+                }
3577
+                else
3578
+                {
3579
+                    $xmlrpc_val = new xmlrpcval();
3580
+                }
3581
+                break;
3582
+            case 'resource':
3583
+                if (in_array('extension_api', $options))
3584
+                {
3585
+                    $xmlrpc_val = new xmlrpcval((int)$php_val, $GLOBALS['xmlrpcInt']);
3586
+                }
3587
+                else
3588
+                {
3589
+                    $xmlrpc_val = new xmlrpcval();
3590
+                }
3591
+            // catch "user function", "unknown type"
3592
+            default:
3593
+                // giancarlo pinerolo <[email protected]>
3594
+                // it has to return
3595
+                // an empty object in case, not a boolean.
3596
+                $xmlrpc_val = new xmlrpcval();
3597
+                break;
3598
+            }
3599
+            return $xmlrpc_val;
3600
+    }
3601
+
3602
+    /**
3603
+     * Convert the xml representation of a method response, method request or single
3604
+     * xmlrpc value into the appropriate object (a.k.a. deserialize)
3605
+     * @param string $xml_val
3606
+     * @param array $options
3607
+     * @return mixed false on error, or an instance of either xmlrpcval, xmlrpcmsg or xmlrpcresp
3608
+     */
3609
+    function php_xmlrpc_decode_xml($xml_val, $options=array())
3610
+    {
3611
+        $GLOBALS['_xh'] = array();
3612
+        $GLOBALS['_xh']['ac'] = '';
3613
+        $GLOBALS['_xh']['stack'] = array();
3614
+        $GLOBALS['_xh']['valuestack'] = array();
3615
+        $GLOBALS['_xh']['params'] = array();
3616
+        $GLOBALS['_xh']['pt'] = array();
3617
+        $GLOBALS['_xh']['isf'] = 0;
3618
+        $GLOBALS['_xh']['isf_reason'] = '';
3619
+        $GLOBALS['_xh']['method'] = false;
3620
+        $GLOBALS['_xh']['rt'] = '';
3621
+
3622
+        // 'guestimate' encoding
3623
+        $val_encoding = guess_encoding('', $xml_val);
3624
+
3625
+        // Since parsing will fail if charset is not specified in the xml prologue,
3626
+        // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
3627
+        // The following code might be better for mb_string enabled installs, but
3628
+        // makes the lib about 200% slower...
3629
+        //if (!is_valid_charset($val_encoding, array('UTF-8')))
3630
+        if (!in_array($val_encoding, array('UTF-8', 'US-ASCII')) && !has_encoding($xml_val)) {
3631
+            if ($val_encoding == 'ISO-8859-1') {
3632
+                $xml_val = utf8_encode($xml_val);
3633
+            } else {
3634
+                if (extension_loaded('mbstring')) {
3635
+                    $xml_val = mb_convert_encoding($xml_val, 'UTF-8', $val_encoding);
3636
+                } else {
3637
+                    error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $val_encoding);
3638
+                }
3639
+            }
3640
+        }
3641
+
3642
+        $parser = xml_parser_create();
3643
+        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
3644
+        // What if internal encoding is not in one of the 3 allowed?
3645
+        // we use the broadest one, ie. utf8!
3646
+        if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
3647
+        {
3648
+            xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
3649
+        }
3650
+        else
3651
+        {
3652
+            xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
3653
+        }
3654
+        xml_set_element_handler($parser, 'xmlrpc_se_any', 'xmlrpc_ee');
3655
+        xml_set_character_data_handler($parser, 'xmlrpc_cd');
3656
+        xml_set_default_handler($parser, 'xmlrpc_dh');
3657
+        if(!xml_parse($parser, $xml_val, 1))
3658
+        {
3659
+            $errstr = sprintf('XML error: %s at line %d, column %d',
3660
+                        xml_error_string(xml_get_error_code($parser)),
3661
+                        xml_get_current_line_number($parser), xml_get_current_column_number($parser));
3662
+            error_log($errstr);
3663
+            xml_parser_free($parser);
3664
+            return false;
3665
+        }
3666
+        xml_parser_free($parser);
3667
+        if ($GLOBALS['_xh']['isf'] > 1) // test that $GLOBALS['_xh']['value'] is an obj, too???
3668
+        {
3669
+            error_log($GLOBALS['_xh']['isf_reason']);
3670
+            return false;
3671
+        }
3672
+        switch ($GLOBALS['_xh']['rt'])
3673
+        {
3674
+            case 'methodresponse':
3675
+                $v =& $GLOBALS['_xh']['value'];
3676
+                if ($GLOBALS['_xh']['isf'] == 1)
3677
+                {
3678
+                    $vc = $v->structmem('faultCode');
3679
+                    $vs = $v->structmem('faultString');
3680
+                    $r = new xmlrpcresp(0, $vc->scalarval(), $vs->scalarval());
3681
+                }
3682
+                else
3683
+                {
3684
+                    $r = new xmlrpcresp($v);
3685
+                }
3686
+                return $r;
3687
+            case 'methodcall':
3688
+                $m = new xmlrpcmsg($GLOBALS['_xh']['method']);
3689
+                for($i=0; $i < count($GLOBALS['_xh']['params']); $i++)
3690
+                {
3691
+                    $m->addParam($GLOBALS['_xh']['params'][$i]);
3692
+                }
3693
+                return $m;
3694
+            case 'value':
3695
+                return $GLOBALS['_xh']['value'];
3696
+            default:
3697
+                return false;
3698
+        }
3699
+    }
3700
+
3701
+    /**
3702
+     * decode a string that is encoded w/ "chunked" transfer encoding
3703
+     * as defined in rfc2068 par. 19.4.6
3704
+     * code shamelessly stolen from nusoap library by Dietrich Ayala
3705
+     *
3706
+     * @param string $buffer the string to be decoded
3707
+     * @return string
3708
+     */
3709
+    function decode_chunked($buffer)
3710
+    {
3711
+        // length := 0
3712
+        $length = 0;
3713
+        $new = '';
3714
+
3715
+        // read chunk-size, chunk-extension (if any) and crlf
3716
+        // get the position of the linebreak
3717
+        $chunkend = strpos($buffer,"\r\n") + 2;
3718
+        $temp = substr($buffer,0,$chunkend);
3719
+        $chunk_size = hexdec( trim($temp) );
3720
+        $chunkstart = $chunkend;
3721
+        while($chunk_size > 0)
3722
+        {
3723
+            $chunkend = strpos($buffer, "\r\n", $chunkstart + $chunk_size);
3724
+
3725
+            // just in case we got a broken connection
3726
+            if($chunkend == false)
3727
+            {
3728
+                $chunk = substr($buffer,$chunkstart);
3729
+                // append chunk-data to entity-body
3730
+                $new .= $chunk;
3731
+                $length += strlen($chunk);
3732
+                break;
3733
+            }
3734
+
3735
+            // read chunk-data and crlf
3736
+            $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
3737
+            // append chunk-data to entity-body
3738
+            $new .= $chunk;
3739
+            // length := length + chunk-size
3740
+            $length += strlen($chunk);
3741
+            // read chunk-size and crlf
3742
+            $chunkstart = $chunkend + 2;
3743
+
3744
+            $chunkend = strpos($buffer,"\r\n",$chunkstart)+2;
3745
+            if($chunkend == false)
3746
+            {
3747
+                break; //just in case we got a broken connection
3748
+            }
3749
+            $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
3750
+            $chunk_size = hexdec( trim($temp) );
3751
+            $chunkstart = $chunkend;
3752
+        }
3753
+        return $new;
3754
+    }
3755
+
3756
+    /**
3757
+     * xml charset encoding guessing helper function.
3758
+     * Tries to determine the charset encoding of an XML chunk received over HTTP.
3759
+     * NB: according to the spec (RFC 3023), if text/xml content-type is received over HTTP without a content-type,
3760
+     * we SHOULD assume it is strictly US-ASCII. But we try to be more tolerant of unconforming (legacy?) clients/servers,
3761
+     * which will be most probably using UTF-8 anyway...
3762
+     *
3763
+     * @param string $httpheader the http Content-type header
3764
+     * @param string $xmlchunk xml content buffer
3765
+     * @param string $encoding_prefs comma separated list of character encodings to be used as default (when mb extension is enabled)
3766
+     * @return string
3767
+     *
3768
+     * @todo explore usage of mb_http_input(): does it detect http headers + post data? if so, use it instead of hand-detection!!!
3769
+     */
3770
+    function guess_encoding($httpheader='', $xmlchunk='', $encoding_prefs=null)
3771
+    {
3772
+        // discussion: see http://www.yale.edu/pclt/encoding/
3773
+        // 1 - test if encoding is specified in HTTP HEADERS
3774
+
3775
+        //Details:
3776
+        // LWS:           (\13\10)?( |\t)+
3777
+        // token:         (any char but excluded stuff)+
3778
+        // quoted string: " (any char but double quotes and cointrol chars)* "
3779
+        // header:        Content-type = ...; charset=value(; ...)*
3780
+        //   where value is of type token, no LWS allowed between 'charset' and value
3781
+        // Note: we do not check for invalid chars in VALUE:
3782
+        //   this had better be done using pure ereg as below
3783
+        // Note 2: we might be removing whitespace/tabs that ought to be left in if
3784
+        //   the received charset is a quoted string. But nobody uses such charset names...
3785
+
3786
+        /// @todo this test will pass if ANY header has charset specification, not only Content-Type. Fix it?
3787
+        $matches = array();
3788
+        if(preg_match('/;\s*charset\s*=([^;]+)/i', $httpheader, $matches))
3789
+        {
3790
+            return strtoupper(trim($matches[1], " \t\""));
3791
+        }
3792
+
3793
+        // 2 - scan the first bytes of the data for a UTF-16 (or other) BOM pattern
3794
+        //     (source: http://www.w3.org/TR/2000/REC-xml-20001006)
3795
+        //     NOTE: actually, according to the spec, even if we find the BOM and determine
3796
+        //     an encoding, we should check if there is an encoding specified
3797
+        //     in the xml declaration, and verify if they match.
3798
+        /// @todo implement check as described above?
3799
+        /// @todo implement check for first bytes of string even without a BOM? (It sure looks harder than for cases WITH a BOM)
3800
+        if(preg_match('/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x00\x00\xFF\xFE|\xFE\xFF\x00\x00)/', $xmlchunk))
3801
+        {
3802
+            return 'UCS-4';
3803
+        }
3804
+        elseif(preg_match('/^(\xFE\xFF|\xFF\xFE)/', $xmlchunk))
3805
+        {
3806
+            return 'UTF-16';
3807
+        }
3808
+        elseif(preg_match('/^(\xEF\xBB\xBF)/', $xmlchunk))
3809
+        {
3810
+            return 'UTF-8';
3811
+        }
3812
+
3813
+        // 3 - test if encoding is specified in the xml declaration
3814
+        // Details:
3815
+        // SPACE:         (#x20 | #x9 | #xD | #xA)+ === [ \x9\xD\xA]+
3816
+        // EQ:            SPACE?=SPACE? === [ \x9\xD\xA]*=[ \x9\xD\xA]*
3817
+        if (preg_match('/^<\?xml\s+version\s*=\s*'. "((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))".
3818
+            '\s+encoding\s*=\s*' . "((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3819
+            $xmlchunk, $matches))
3820
+        {
3821
+            return strtoupper(substr($matches[2], 1, -1));
3822
+        }
3823
+
3824
+        // 4 - if mbstring is available, let it do the guesswork
3825
+        // NB: we favour finding an encoding that is compatible with what we can process
3826
+        if(extension_loaded('mbstring'))
3827
+        {
3828
+            if($encoding_prefs)
3829
+            {
3830
+                $enc = mb_detect_encoding($xmlchunk, $encoding_prefs);
3831
+            }
3832
+            else
3833
+            {
3834
+                $enc = mb_detect_encoding($xmlchunk);
3835
+            }
3836
+            // NB: mb_detect likes to call it ascii, xml parser likes to call it US_ASCII...
3837
+            // IANA also likes better US-ASCII, so go with it
3838
+            if($enc == 'ASCII')
3839
+            {
3840
+                $enc = 'US-'.$enc;
3841
+            }
3842
+            return $enc;
3843
+        }
3844
+        else
3845
+        {
3846
+            // no encoding specified: as per HTTP1.1 assume it is iso-8859-1?
3847
+            // Both RFC 2616 (HTTP 1.1) and 1945 (HTTP 1.0) clearly state that for text/xxx content types
3848
+            // this should be the standard. And we should be getting text/xml as request and response.
3849
+            // BUT we have to be backward compatible with the lib, which always used UTF-8 as default...
3850
+            return $GLOBALS['xmlrpc_defencoding'];
3851
+        }
3852
+    }
3853
+
3854
+    /**
3855
+     * Helper function: checks if an xml chunk as a charset declaration (BOM or in the xml declaration)
3856
+     *
3857
+     * @param string $xmlChunk
3858
+     * @return bool
3859
+     */
3860
+    function has_encoding($xmlChunk)
3861
+    {
3862
+        // scan the first bytes of the data for a UTF-16 (or other) BOM pattern
3863
+        //	 (source: http://www.w3.org/TR/2000/REC-xml-20001006)
3864
+        if (preg_match('/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x00\x00\xFF\xFE|\xFE\xFF\x00\x00)/', $xmlChunk))
3865
+        {
3866
+            return true;
3867
+        }
3868
+        elseif (preg_match('/^(\xFE\xFF|\xFF\xFE)/', $xmlChunk))
3869
+        {
3870
+            return true;
3871
+        }
3872
+        elseif (preg_match('/^(\xEF\xBB\xBF)/', $xmlChunk))
3873
+        {
3874
+            return true;
3875
+        }
3876
+
3877
+        // test if encoding is specified in the xml declaration
3878
+        // Details:
3879
+        // SPACE:		(#x20 | #x9 | #xD | #xA)+ === [ \x9\xD\xA]+
3880
+        // EQ:			SPACE?=SPACE? === [ \x9\xD\xA]*=[ \x9\xD\xA]*
3881
+        if (preg_match('/^<\?xml\s+version\s*=\s*' . "((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))" .
3882
+            '\s+encoding\s*=\s*' . "((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3883
+            $xmlChunk, $matches))
3884
+        {
3885
+            return true;
3886
+        }
3887
+
3888
+        return false;
3889
+    }
3890
+
3891
+    /**
3892
+     * Checks if a given charset encoding is present in a list of encodings or
3893
+     * if it is a valid subset of any encoding in the list
3894
+     * @param string $encoding charset to be tested
3895
+     * @param mixed $validlist comma separated list of valid charsets (or array of charsets)
3896
+     * @return bool
3897
+     */
3898
+    function is_valid_charset($encoding, $validlist)
3899
+    {
3900
+        $charset_supersets = array(
3901
+            'US-ASCII' => array ('ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
3902
+                'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8',
3903
+                'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-12',
3904
+                'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'UTF-8',
3905
+                'EUC-JP', 'EUC-', 'EUC-KR', 'EUC-CN')
3906
+        );
3907
+        if (is_string($validlist))
3908
+            $validlist = explode(',', $validlist);
3909
+        if (@in_array(strtoupper($encoding), $validlist))
3910
+            return true;
3911
+        else
3912
+        {
3913
+            if (array_key_exists($encoding, $charset_supersets))
3914
+                foreach ($validlist as $allowed)
3915
+                    if (in_array($allowed, $charset_supersets[$encoding]))
3916
+                        return true;
3917
+            return false;
3918
+        }
3919
+    }
3920 3920
 
3921 3921
 ?>
Please login to merge, or discard this patch.
Spacing   +567 added lines, -567 removed lines patch added patch discarded remove patch
@@ -34,11 +34,11 @@  discard block
 block discarded – undo
34 34
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35 35
 // OF THE POSSIBILITY OF SUCH DAMAGE.
36 36
 
37
-	if(!function_exists('xml_parser_create'))
37
+	if (!function_exists('xml_parser_create'))
38 38
 	{
39 39
 		// For PHP 4 onward, XML functionality is always compiled-in on windows:
40 40
 		// no more need to dl-open it. It might have been compiled out on *nix...
41
-		if(strtoupper(substr(PHP_OS, 0, 3) != 'WIN'))
41
+		if (strtoupper(substr(PHP_OS, 0, 3) != 'WIN'))
42 42
 		{
43 43
 			dl('xml.so');
44 44
 		}
@@ -47,18 +47,18 @@  discard block
 block discarded – undo
47 47
 	// G. Giunta 2005/01/29: declare global these variables,
48 48
 	// so that xmlrpc.inc will work even if included from within a function
49 49
 	// Milosch: 2005/08/07 - explicitly request these via $GLOBALS where used.
50
-	$GLOBALS['xmlrpcI4']='i4';
51
-	$GLOBALS['xmlrpcInt']='int';
52
-	$GLOBALS['xmlrpcBoolean']='boolean';
53
-	$GLOBALS['xmlrpcDouble']='double';
54
-	$GLOBALS['xmlrpcString']='string';
55
-	$GLOBALS['xmlrpcDateTime']='dateTime.iso8601';
56
-	$GLOBALS['xmlrpcBase64']='base64';
57
-	$GLOBALS['xmlrpcArray']='array';
58
-	$GLOBALS['xmlrpcStruct']='struct';
59
-	$GLOBALS['xmlrpcValue']='undefined';
60
-
61
-	$GLOBALS['xmlrpcTypes']=array(
50
+	$GLOBALS['xmlrpcI4'] = 'i4';
51
+	$GLOBALS['xmlrpcInt'] = 'int';
52
+	$GLOBALS['xmlrpcBoolean'] = 'boolean';
53
+	$GLOBALS['xmlrpcDouble'] = 'double';
54
+	$GLOBALS['xmlrpcString'] = 'string';
55
+	$GLOBALS['xmlrpcDateTime'] = 'dateTime.iso8601';
56
+	$GLOBALS['xmlrpcBase64'] = 'base64';
57
+	$GLOBALS['xmlrpcArray'] = 'array';
58
+	$GLOBALS['xmlrpcStruct'] = 'struct';
59
+	$GLOBALS['xmlrpcValue'] = 'undefined';
60
+
61
+	$GLOBALS['xmlrpcTypes'] = array(
62 62
 		$GLOBALS['xmlrpcI4']       => 1,
63 63
 		$GLOBALS['xmlrpcInt']      => 1,
64 64
 		$GLOBALS['xmlrpcBoolean']  => 1,
@@ -93,12 +93,12 @@  discard block
 block discarded – undo
93 93
 	);
94 94
 
95 95
 	// define extra types for supporting NULL (useful for json or <NIL/>)
96
-	$GLOBALS['xmlrpcNull']='null';
97
-	$GLOBALS['xmlrpcTypes']['null']=1;
96
+	$GLOBALS['xmlrpcNull'] = 'null';
97
+	$GLOBALS['xmlrpcTypes']['null'] = 1;
98 98
 
99 99
 	// Not in use anymore since 2.0. Shall we remove it?
100 100
 	/// @deprecated
101
-	$GLOBALS['xmlEntities']=array(
101
+	$GLOBALS['xmlEntities'] = array(
102 102
 		'amp'  => '&',
103 103
 		'quot' => '"',
104 104
 		'lt'   => '<',
@@ -108,15 +108,15 @@  discard block
 block discarded – undo
108 108
 
109 109
 	// tables used for transcoding different charsets into us-ascii xml
110 110
 
111
-	$GLOBALS['xml_iso88591_Entities']=array();
111
+	$GLOBALS['xml_iso88591_Entities'] = array();
112 112
 	$GLOBALS['xml_iso88591_Entities']['in'] = array();
113 113
 	$GLOBALS['xml_iso88591_Entities']['out'] = array();
114
-	for ($i = 0; $i < 32; $i++)
114
+	for ($i = 0; $i<32; $i++)
115 115
 	{
116 116
 		$GLOBALS['xml_iso88591_Entities']['in'][] = chr($i);
117 117
 		$GLOBALS['xml_iso88591_Entities']['out'][] = '&#'.$i.';';
118 118
 	}
119
-	for ($i = 160; $i < 256; $i++)
119
+	for ($i = 160; $i<256; $i++)
120 120
 	{
121 121
 		$GLOBALS['xml_iso88591_Entities']['in'][] = chr($i);
122 122
 		$GLOBALS['xml_iso88591_Entities']['out'][] = '&#'.$i.';';
@@ -200,32 +200,32 @@  discard block
 block discarded – undo
200 200
 	// The charset encoding used by the server for received messages and
201 201
 	// by the client for received responses when received charset cannot be determined
202 202
 	// or is not supported
203
-	$GLOBALS['xmlrpc_defencoding']='UTF-8';
203
+	$GLOBALS['xmlrpc_defencoding'] = 'UTF-8';
204 204
 
205 205
 	// The encoding used internally by PHP.
206 206
 	// String values received as xml will be converted to this, and php strings will be converted to xml
207 207
 	// as if having been coded with this
208
-	$GLOBALS['xmlrpc_internalencoding']='ISO-8859-1';
208
+	$GLOBALS['xmlrpc_internalencoding'] = 'ISO-8859-1';
209 209
 
210
-	$GLOBALS['xmlrpcName']='XML-RPC for PHP';
211
-	$GLOBALS['xmlrpcVersion']='3.1.1';
210
+	$GLOBALS['xmlrpcName'] = 'XML-RPC for PHP';
211
+	$GLOBALS['xmlrpcVersion'] = '3.1.1';
212 212
 
213 213
 	// let user errors start at 800
214
-	$GLOBALS['xmlrpcerruser']=800;
214
+	$GLOBALS['xmlrpcerruser'] = 800;
215 215
 	// let XML parse errors start at 100
216
-	$GLOBALS['xmlrpcerrxml']=100;
216
+	$GLOBALS['xmlrpcerrxml'] = 100;
217 217
 
218 218
 	// formulate backslashes for escaping regexp
219 219
 	// Not in use anymore since 2.0. Shall we remove it?
220 220
 	/// @deprecated
221
-	$GLOBALS['xmlrpc_backslash']=chr(92).chr(92);
221
+	$GLOBALS['xmlrpc_backslash'] = chr(92).chr(92);
222 222
 
223 223
 	// set to TRUE to enable correct decoding of <NIL/> and <EX:NIL/> values
224
-	$GLOBALS['xmlrpc_null_extension']=false;
224
+	$GLOBALS['xmlrpc_null_extension'] = false;
225 225
 
226 226
 	// set to TRUE to enable encoding of php NULL values to <EX:NIL/> instead of <NIL/>
227
-	$GLOBALS['xmlrpc_null_apache_encoding']=false;
228
-	$GLOBALS['xmlrpc_null_apache_encoding_ns']='http://ws.apache.org/xmlrpc/namespaces/extensions';
227
+	$GLOBALS['xmlrpc_null_apache_encoding'] = false;
228
+	$GLOBALS['xmlrpc_null_apache_encoding_ns'] = 'http://ws.apache.org/xmlrpc/namespaces/extensions';
229 229
 
230 230
 	// used to store state during parsing
231 231
 	// quick explanation of components:
@@ -238,7 +238,7 @@  discard block
 block discarded – undo
238 238
 	//   method - used to store method name
239 239
 	//   stack - array with genealogy of xml elements names:
240 240
 	//           used to validate nesting of xmlrpc elements
241
-	$GLOBALS['_xh']=null;
241
+	$GLOBALS['_xh'] = null;
242 242
 
243 243
 	/**
244 244
 	* Convert a string to the correct XML representation in a target charset
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
 	* @todo do a bit of basic benchmarking (strtr vs. str_replace)
255 255
 	* @todo	make usage of iconv() or recode_string() or mb_string() where available
256 256
 	*/
257
-	function xmlrpc_encode_entitites($data, $src_encoding='', $dest_encoding='')
257
+	function xmlrpc_encode_entitites($data, $src_encoding = '', $dest_encoding = '')
258 258
 	{
259 259
 		if ($src_encoding == '')
260 260
 		{
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
 			$src_encoding = $GLOBALS['xmlrpc_internalencoding'];
263 263
 		}
264 264
 
265
-		switch(strtoupper($src_encoding.'_'.$dest_encoding))
265
+		switch (strtoupper($src_encoding.'_'.$dest_encoding))
266 266
 		{
267 267
 			case 'ISO-8859-1_':
268 268
 			case 'ISO-8859-1_US-ASCII':
@@ -289,16 +289,16 @@  discard block
 block discarded – undo
289 289
 	$escaped_data = '';
290 290
 	// be kind to users creating string xmlrpcvals out of different php types
291 291
 	$data = (string) $data;
292
-	$ns = strlen ($data);
293
-	for ($nn = 0; $nn < $ns; $nn++)
292
+	$ns = strlen($data);
293
+	for ($nn = 0; $nn<$ns; $nn++)
294 294
 	{
295 295
 		$ch = $data[$nn];
296 296
 		$ii = ord($ch);
297 297
 		//1 7 0bbbbbbb (127)
298
-		if ($ii < 128)
298
+		if ($ii<128)
299 299
 		{
300 300
 			/// @todo shall we replace this with a (supposedly) faster str_replace?
301
-			switch($ii){
301
+			switch ($ii) {
302 302
 				case 34:
303 303
 					$escaped_data .= '&quot;';
304 304
 					break;
@@ -319,31 +319,31 @@  discard block
 block discarded – undo
319 319
 			} // switch
320 320
 		}
321 321
 		//2 11 110bbbbb 10bbbbbb (2047)
322
-		else if ($ii>>5 == 6)
322
+		else if ($ii >> 5 == 6)
323 323
 		{
324 324
 			$b1 = ($ii & 31);
325 325
 			$ii = ord($data[$nn+1]);
326 326
 			$b2 = ($ii & 63);
327
-			$ii = ($b1 * 64) + $b2;
328
-			$ent = sprintf ('&#%d;', $ii);
327
+			$ii = ($b1 * 64)+$b2;
328
+			$ent = sprintf('&#%d;', $ii);
329 329
 			$escaped_data .= $ent;
330 330
 			$nn += 1;
331 331
 		}
332 332
 		//3 16 1110bbbb 10bbbbbb 10bbbbbb
333
-		else if ($ii>>4 == 14)
333
+		else if ($ii >> 4 == 14)
334 334
 		{
335 335
 			$b1 = ($ii & 15);
336 336
 			$ii = ord($data[$nn+1]);
337 337
 			$b2 = ($ii & 63);
338 338
 			$ii = ord($data[$nn+2]);
339 339
 			$b3 = ($ii & 63);
340
-			$ii = ((($b1 * 64) + $b2) * 64) + $b3;
341
-			$ent = sprintf ('&#%d;', $ii);
340
+			$ii = ((($b1 * 64)+$b2) * 64)+$b3;
341
+			$ent = sprintf('&#%d;', $ii);
342 342
 			$escaped_data .= $ent;
343 343
 			$nn += 2;
344 344
 		}
345 345
 		//4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
346
-		else if ($ii>>3 == 30)
346
+		else if ($ii >> 3 == 30)
347 347
 		{
348 348
 			$b1 = ($ii & 7);
349 349
 			$ii = ord($data[$nn+1]);
@@ -352,8 +352,8 @@  discard block
 block discarded – undo
352 352
 			$b3 = ($ii & 63);
353 353
 			$ii = ord($data[$nn+3]);
354 354
 			$b4 = ($ii & 63);
355
-			$ii = ((((($b1 * 64) + $b2) * 64) + $b3) * 64) + $b4;
356
-			$ent = sprintf ('&#%d;', $ii);
355
+			$ii = ((((($b1 * 64)+$b2) * 64)+$b3) * 64)+$b4;
356
+			$ent = sprintf('&#%d;', $ii);
357 357
 			$escaped_data .= $ent;
358 358
 			$nn += 3;
359 359
 		}
@@ -386,10 +386,10 @@  discard block
 block discarded – undo
386 386
 	}
387 387
 
388 388
 	/// xml parser handler function for opening element tags
389
-	function xmlrpc_se($parser, $name, $attrs, $accept_single_vals=false)
389
+	function xmlrpc_se($parser, $name, $attrs, $accept_single_vals = false)
390 390
 	{
391 391
 		// if invalid xmlrpc already detected, skip all processing
392
-		if ($GLOBALS['_xh']['isf'] < 2)
392
+		if ($GLOBALS['_xh']['isf']<2)
393 393
 		{
394 394
 			// check for correct element nesting
395 395
 			// top level element can only be of 2 types
@@ -422,15 +422,15 @@  discard block
 block discarded – undo
422 422
 				}
423 423
 			}
424 424
 
425
-			switch($name)
425
+			switch ($name)
426 426
 			{
427 427
 				// optimize for speed switch cases: most common cases first
428 428
 				case 'VALUE':
429 429
 					/// @todo we could check for 2 VALUE elements inside a MEMBER or PARAM element
430
-					$GLOBALS['_xh']['vt']='value'; // indicator: no value found yet
431
-					$GLOBALS['_xh']['ac']='';
432
-					$GLOBALS['_xh']['lv']=1;
433
-					$GLOBALS['_xh']['php_class']=null;
430
+					$GLOBALS['_xh']['vt'] = 'value'; // indicator: no value found yet
431
+					$GLOBALS['_xh']['ac'] = '';
432
+					$GLOBALS['_xh']['lv'] = 1;
433
+					$GLOBALS['_xh']['php_class'] = null;
434 434
 					break;
435 435
 				case 'I4':
436 436
 				case 'INT':
@@ -439,18 +439,18 @@  discard block
 block discarded – undo
439 439
 				case 'DOUBLE':
440 440
 				case 'DATETIME.ISO8601':
441 441
 				case 'BASE64':
442
-					if ($GLOBALS['_xh']['vt']!='value')
442
+					if ($GLOBALS['_xh']['vt'] != 'value')
443 443
 					{
444 444
 						//two data elements inside a value: an error occurred!
445 445
 						$GLOBALS['_xh']['isf'] = 2;
446 446
 						$GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
447 447
 						return;
448 448
 					}
449
-					$GLOBALS['_xh']['ac']=''; // reset the accumulator
449
+					$GLOBALS['_xh']['ac'] = ''; // reset the accumulator
450 450
 					break;
451 451
 				case 'STRUCT':
452 452
 				case 'ARRAY':
453
-					if ($GLOBALS['_xh']['vt']!='value')
453
+					if ($GLOBALS['_xh']['vt'] != 'value')
454 454
 					{
455 455
 						//two data elements inside a value: an error occurred!
456 456
 						$GLOBALS['_xh']['isf'] = 2;
@@ -468,10 +468,10 @@  discard block
 block discarded – undo
468 468
 						$cur_val['php_class'] = $attrs['PHP_CLASS'];
469 469
 					}
470 470
 					$GLOBALS['_xh']['valuestack'][] = $cur_val;
471
-					$GLOBALS['_xh']['vt']='data'; // be prepared for a data element next
471
+					$GLOBALS['_xh']['vt'] = 'data'; // be prepared for a data element next
472 472
 					break;
473 473
 				case 'DATA':
474
-					if ($GLOBALS['_xh']['vt']!='data')
474
+					if ($GLOBALS['_xh']['vt'] != 'data')
475 475
 					{
476 476
 						//two data elements inside a value: an error occurred!
477 477
 						$GLOBALS['_xh']['isf'] = 2;
@@ -486,31 +486,31 @@  discard block
 block discarded – undo
486 486
 				case 'METHODNAME':
487 487
 				case 'NAME':
488 488
 					/// @todo we could check for 2 NAME elements inside a MEMBER element
489
-					$GLOBALS['_xh']['ac']='';
489
+					$GLOBALS['_xh']['ac'] = '';
490 490
 					break;
491 491
 				case 'FAULT':
492
-					$GLOBALS['_xh']['isf']=1;
492
+					$GLOBALS['_xh']['isf'] = 1;
493 493
 					break;
494 494
 				case 'MEMBER':
495
-					$GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name']=''; // set member name to null, in case we do not find in the xml later on
495
+					$GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name'] = ''; // set member name to null, in case we do not find in the xml later on
496 496
 					//$GLOBALS['_xh']['ac']='';
497 497
 					// Drop trough intentionally
498 498
 				case 'PARAM':
499 499
 					// clear value type, so we can check later if no value has been passed for this param/member
500
-					$GLOBALS['_xh']['vt']=null;
500
+					$GLOBALS['_xh']['vt'] = null;
501 501
 					break;
502 502
 				case 'NIL':
503 503
 				case 'EX:NIL':
504 504
 					if ($GLOBALS['xmlrpc_null_extension'])
505 505
 					{
506
-						if ($GLOBALS['_xh']['vt']!='value')
506
+						if ($GLOBALS['_xh']['vt'] != 'value')
507 507
 						{
508 508
 							//two data elements inside a value: an error occurred!
509 509
 							$GLOBALS['_xh']['isf'] = 2;
510 510
 							$GLOBALS['_xh']['isf_reason'] = "$name element following a {$GLOBALS['_xh']['vt']} element inside a single value";
511 511
 							return;
512 512
 						}
513
-						$GLOBALS['_xh']['ac']=''; // reset the accumulator
513
+						$GLOBALS['_xh']['ac'] = ''; // reset the accumulator
514 514
 						break;
515 515
 					}
516 516
 					// we do not support the <NIL/> extension, so
@@ -526,9 +526,9 @@  discard block
 block discarded – undo
526 526
 			$GLOBALS['_xh']['stack'][] = $name;
527 527
 
528 528
 			/// @todo optimization creep: move this inside the big switch() above
529
-			if($name!='VALUE')
529
+			if ($name != 'VALUE')
530 530
 			{
531
-				$GLOBALS['_xh']['lv']=0;
531
+				$GLOBALS['_xh']['lv'] = 0;
532 532
 			}
533 533
 		}
534 534
 	}
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
 	/// xml parser handler function for close element tags
543 543
 	function xmlrpc_ee($parser, $name, $rebuild_xmlrpcvals = true)
544 544
 	{
545
-		if ($GLOBALS['_xh']['isf'] < 2)
545
+		if ($GLOBALS['_xh']['isf']<2)
546 546
 		{
547 547
 			// push this element name from stack
548 548
 			// NB: if XML validates, correct opening/closing is guaranteed and
@@ -550,14 +550,14 @@  discard block
 block discarded – undo
550 550
 			// we also checked for proper nesting at start of elements...
551 551
 			$curr_elem = array_pop($GLOBALS['_xh']['stack']);
552 552
 
553
-			switch($name)
553
+			switch ($name)
554 554
 			{
555 555
 				case 'VALUE':
556 556
 					// This if() detects if no scalar was inside <VALUE></VALUE>
557
-					if ($GLOBALS['_xh']['vt']=='value')
557
+					if ($GLOBALS['_xh']['vt'] == 'value')
558 558
 					{
559
-						$GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
560
-						$GLOBALS['_xh']['vt']=$GLOBALS['xmlrpcString'];
559
+						$GLOBALS['_xh']['value'] = $GLOBALS['_xh']['ac'];
560
+						$GLOBALS['_xh']['vt'] = $GLOBALS['xmlrpcString'];
561 561
 					}
562 562
 
563 563
 					if ($rebuild_xmlrpcvals)
@@ -571,7 +571,7 @@  discard block
 block discarded – undo
571 571
 						// check if we are inside an array or struct:
572 572
 						// if value just built is inside an array, let's move it into array on the stack
573 573
 						$vscount = count($GLOBALS['_xh']['valuestack']);
574
-						if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type']=='ARRAY')
574
+						if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type'] == 'ARRAY')
575 575
 						{
576 576
 							$GLOBALS['_xh']['valuestack'][$vscount-1]['values'][] = $temp;
577 577
 						}
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
 						// check if we are inside an array or struct:
593 593
 						// if value just built is inside an array, let's move it into array on the stack
594 594
 						$vscount = count($GLOBALS['_xh']['valuestack']);
595
-						if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type']=='ARRAY')
595
+						if ($vscount && $GLOBALS['_xh']['valuestack'][$vscount-1]['type'] == 'ARRAY')
596 596
 						{
597 597
 							$GLOBALS['_xh']['valuestack'][$vscount-1]['values'][] = $GLOBALS['_xh']['value'];
598 598
 						}
@@ -605,28 +605,28 @@  discard block
 block discarded – undo
605 605
 				case 'DOUBLE':
606 606
 				case 'DATETIME.ISO8601':
607 607
 				case 'BASE64':
608
-					$GLOBALS['_xh']['vt']=strtolower($name);
608
+					$GLOBALS['_xh']['vt'] = strtolower($name);
609 609
 					/// @todo: optimization creep - remove the if/elseif cycle below
610 610
 					/// since the case() in which we are already did that
611
-					if ($name=='STRING')
611
+					if ($name == 'STRING')
612 612
 					{
613
-						$GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
613
+						$GLOBALS['_xh']['value'] = $GLOBALS['_xh']['ac'];
614 614
 					}
615
-					elseif ($name=='DATETIME.ISO8601')
615
+					elseif ($name == 'DATETIME.ISO8601')
616 616
 					{
617 617
 						if (!preg_match('/^[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $GLOBALS['_xh']['ac']))
618 618
 						{
619 619
 							error_log('XML-RPC: invalid value received in DATETIME: '.$GLOBALS['_xh']['ac']);
620 620
 						}
621
-						$GLOBALS['_xh']['vt']=$GLOBALS['xmlrpcDateTime'];
622
-						$GLOBALS['_xh']['value']=$GLOBALS['_xh']['ac'];
621
+						$GLOBALS['_xh']['vt'] = $GLOBALS['xmlrpcDateTime'];
622
+						$GLOBALS['_xh']['value'] = $GLOBALS['_xh']['ac'];
623 623
 					}
624
-					elseif ($name=='BASE64')
624
+					elseif ($name == 'BASE64')
625 625
 					{
626 626
 						/// @todo check for failure of base64 decoding / catch warnings
627
-						$GLOBALS['_xh']['value']=base64_decode($GLOBALS['_xh']['ac']);
627
+						$GLOBALS['_xh']['value'] = base64_decode($GLOBALS['_xh']['ac']);
628 628
 					}
629
-					elseif ($name=='BOOLEAN')
629
+					elseif ($name == 'BOOLEAN')
630 630
 					{
631 631
 						// special case here: we translate boolean 1 or 0 into PHP
632 632
 						// constants true or false.
@@ -634,19 +634,19 @@  discard block
 block discarded – undo
634 634
 						// spec never mentions them (see eg. Blogger api docs)
635 635
 						// NB: this simple checks helps a lot sanitizing input, ie no
636 636
 						// security problems around here
637
-						if ($GLOBALS['_xh']['ac']=='1' || strcasecmp($GLOBALS['_xh']['ac'], 'true') == 0)
637
+						if ($GLOBALS['_xh']['ac'] == '1' || strcasecmp($GLOBALS['_xh']['ac'], 'true') == 0)
638 638
 						{
639
-							$GLOBALS['_xh']['value']=true;
639
+							$GLOBALS['_xh']['value'] = true;
640 640
 						}
641 641
 						else
642 642
 						{
643 643
 							// log if receiveing something strange, even though we set the value to false anyway
644
-							if ($GLOBALS['_xh']['ac']!='0' && strcasecmp($GLOBALS['_xh']['ac'], 'false') != 0)
644
+							if ($GLOBALS['_xh']['ac'] != '0' && strcasecmp($GLOBALS['_xh']['ac'], 'false') != 0)
645 645
 								error_log('XML-RPC: invalid value received in BOOLEAN: '.$GLOBALS['_xh']['ac']);
646
-							$GLOBALS['_xh']['value']=false;
646
+							$GLOBALS['_xh']['value'] = false;
647 647
 						}
648 648
 					}
649
-					elseif ($name=='DOUBLE')
649
+					elseif ($name == 'DOUBLE')
650 650
 					{
651 651
 						// we have a DOUBLE
652 652
 						// we must check that only 0123456789-.<space> are characters here
@@ -655,12 +655,12 @@  discard block
 block discarded – undo
655 655
 						{
656 656
 							/// @todo: find a better way of throwing an error than this!
657 657
 							error_log('XML-RPC: non numeric value received in DOUBLE: '.$GLOBALS['_xh']['ac']);
658
-							$GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
658
+							$GLOBALS['_xh']['value'] = 'ERROR_NON_NUMERIC_FOUND';
659 659
 						}
660 660
 						else
661 661
 						{
662 662
 							// it's ok, add it on
663
-							$GLOBALS['_xh']['value']=(double)$GLOBALS['_xh']['ac'];
663
+							$GLOBALS['_xh']['value'] = (double) $GLOBALS['_xh']['ac'];
664 664
 						}
665 665
 					}
666 666
 					else
@@ -671,16 +671,16 @@  discard block
 block discarded – undo
671 671
 						{
672 672
 							/// @todo find a better way of throwing an error than this!
673 673
 							error_log('XML-RPC: non numeric value received in INT: '.$GLOBALS['_xh']['ac']);
674
-							$GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
674
+							$GLOBALS['_xh']['value'] = 'ERROR_NON_NUMERIC_FOUND';
675 675
 						}
676 676
 						else
677 677
 						{
678 678
 							// it's ok, add it on
679
-							$GLOBALS['_xh']['value']=(int)$GLOBALS['_xh']['ac'];
679
+							$GLOBALS['_xh']['value'] = (int) $GLOBALS['_xh']['ac'];
680 680
 						}
681 681
 					}
682 682
 					//$GLOBALS['_xh']['ac']=''; // is this necessary?
683
-					$GLOBALS['_xh']['lv']=3; // indicate we've found a value
683
+					$GLOBALS['_xh']['lv'] = 3; // indicate we've found a value
684 684
 					break;
685 685
 				case 'NAME':
686 686
 					$GLOBALS['_xh']['valuestack'][count($GLOBALS['_xh']['valuestack'])-1]['name'] = $GLOBALS['_xh']['ac'];
@@ -698,14 +698,14 @@  discard block
 block discarded – undo
698 698
 					break;
699 699
 				case 'DATA':
700 700
 					//$GLOBALS['_xh']['ac']=''; // is this necessary?
701
-					$GLOBALS['_xh']['vt']=null; // reset this to check for 2 data elements in a row - even if they're empty
701
+					$GLOBALS['_xh']['vt'] = null; // reset this to check for 2 data elements in a row - even if they're empty
702 702
 					break;
703 703
 				case 'STRUCT':
704 704
 				case 'ARRAY':
705 705
 					// fetch out of stack array of values, and promote it to current value
706 706
 					$curr_val = array_pop($GLOBALS['_xh']['valuestack']);
707 707
 					$GLOBALS['_xh']['value'] = $curr_val['values'];
708
-					$GLOBALS['_xh']['vt']=strtolower($name);
708
+					$GLOBALS['_xh']['vt'] = strtolower($name);
709 709
 					if (isset($curr_val['php_class']))
710 710
 					{
711 711
 						$GLOBALS['_xh']['php_class'] = $curr_val['php_class'];
@@ -716,22 +716,22 @@  discard block
 block discarded – undo
716 716
 					// unless no VALUE was found
717 717
 					if ($GLOBALS['_xh']['vt'])
718 718
 					{
719
-						$GLOBALS['_xh']['params'][]=$GLOBALS['_xh']['value'];
720
-						$GLOBALS['_xh']['pt'][]=$GLOBALS['_xh']['vt'];
719
+						$GLOBALS['_xh']['params'][] = $GLOBALS['_xh']['value'];
720
+						$GLOBALS['_xh']['pt'][] = $GLOBALS['_xh']['vt'];
721 721
 					}
722 722
 					else
723 723
 						error_log('XML-RPC: missing VALUE inside PARAM in received xml');
724 724
 					break;
725 725
 				case 'METHODNAME':
726
-					$GLOBALS['_xh']['method']=preg_replace('/^[\n\r\t ]+/', '', $GLOBALS['_xh']['ac']);
726
+					$GLOBALS['_xh']['method'] = preg_replace('/^[\n\r\t ]+/', '', $GLOBALS['_xh']['ac']);
727 727
 					break;
728 728
 				case 'NIL':
729 729
 				case 'EX:NIL':
730 730
 					if ($GLOBALS['xmlrpc_null_extension'])
731 731
 					{
732
-						$GLOBALS['_xh']['vt']='null';
733
-						$GLOBALS['_xh']['value']=null;
734
-						$GLOBALS['_xh']['lv']=3;
732
+						$GLOBALS['_xh']['vt'] = 'null';
733
+						$GLOBALS['_xh']['value'] = null;
734
+						$GLOBALS['_xh']['lv'] = 3;
735 735
 						break;
736 736
 					}
737 737
 					// drop through intentionally if nil extension not enabled
@@ -758,11 +758,11 @@  discard block
 block discarded – undo
758 758
 	function xmlrpc_cd($parser, $data)
759 759
 	{
760 760
 		// skip processing if xml fault already detected
761
-		if ($GLOBALS['_xh']['isf'] < 2)
761
+		if ($GLOBALS['_xh']['isf']<2)
762 762
 		{
763 763
 			// "lookforvalue==3" means that we've found an entire value
764 764
 			// and should discard any further character data
765
-			if($GLOBALS['_xh']['lv']!=3)
765
+			if ($GLOBALS['_xh']['lv'] != 3)
766 766
 			{
767 767
 				// G. Giunta 2006-08-23: useless change of 'lv' from 1 to 2
768 768
 				//if($GLOBALS['_xh']['lv']==1)
@@ -776,7 +776,7 @@  discard block
 block discarded – undo
776 776
 				//{
777 777
 				//	$GLOBALS['_xh']['ac'] = '';
778 778
 				//}
779
-				$GLOBALS['_xh']['ac'].=$data;
779
+				$GLOBALS['_xh']['ac'] .= $data;
780 780
 			}
781 781
 		}
782 782
 	}
@@ -786,16 +786,16 @@  discard block
 block discarded – undo
786 786
 	function xmlrpc_dh($parser, $data)
787 787
 	{
788 788
 		// skip processing if xml fault already detected
789
-		if ($GLOBALS['_xh']['isf'] < 2)
789
+		if ($GLOBALS['_xh']['isf']<2)
790 790
 		{
791
-			if(substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
791
+			if (substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
792 792
 			{
793 793
 				// G. Giunta 2006-08-25: useless change of 'lv' from 1 to 2
794 794
 				//if($GLOBALS['_xh']['lv']==1)
795 795
 				//{
796 796
 				//	$GLOBALS['_xh']['lv']=2;
797 797
 				//}
798
-				$GLOBALS['_xh']['ac'].=$data;
798
+				$GLOBALS['_xh']['ac'] .= $data;
799 799
 			}
800 800
 		}
801 801
 		return true;
@@ -805,31 +805,31 @@  discard block
 block discarded – undo
805 805
 	{
806 806
 		var $path;
807 807
 		var $server;
808
-		var $port=0;
809
-		var $method='http';
808
+		var $port = 0;
809
+		var $method = 'http';
810 810
 		var $errno;
811 811
 		var $errstr;
812
-		var $debug=0;
813
-		var $username='';
814
-		var $password='';
815
-		var $authtype=1;
816
-		var $cert='';
817
-		var $certpass='';
818
-		var $cacert='';
819
-		var $cacertdir='';
820
-		var $key='';
821
-		var $keypass='';
822
-		var $verifypeer=true;
823
-		var $verifyhost=1;
824
-		var $sslversion=0; // corresponds to CURL_SSLVERSION_DEFAULT
825
-		var $no_multicall=false;
826
-		var $proxy='';
827
-		var $proxyport=0;
828
-		var $proxy_user='';
829
-		var $proxy_pass='';
830
-		var $proxy_authtype=1;
831
-		var $cookies=array();
832
-		var $extracurlopts=array();
812
+		var $debug = 0;
813
+		var $username = '';
814
+		var $password = '';
815
+		var $authtype = 1;
816
+		var $cert = '';
817
+		var $certpass = '';
818
+		var $cacert = '';
819
+		var $cacertdir = '';
820
+		var $key = '';
821
+		var $keypass = '';
822
+		var $verifypeer = true;
823
+		var $verifyhost = 1;
824
+		var $sslversion = 0; // corresponds to CURL_SSLVERSION_DEFAULT
825
+		var $no_multicall = false;
826
+		var $proxy = '';
827
+		var $proxyport = 0;
828
+		var $proxy_user = '';
829
+		var $proxy_pass = '';
830
+		var $proxy_authtype = 1;
831
+		var $cookies = array();
832
+		var $extracurlopts = array();
833 833
 
834 834
 		/**
835 835
 		* List of http compression methods accepted by the client for responses.
@@ -873,59 +873,59 @@  discard block
 block discarded – undo
873 873
 		* @param integer $port the port the server is listening on, defaults to 80 or 443 depending on protocol used
874 874
 		* @param string $method the http protocol variant: defaults to 'http', 'https' and 'http11' can be used if CURL is installed
875 875
 		*/
876
-		function __construct($path, $server='', $port='', $method='')
876
+		function __construct($path, $server = '', $port = '', $method = '')
877 877
 		{
878 878
 			// allow user to specify all params in $path
879
-			if($server == '' and $port == '' and $method == '')
879
+			if ($server == '' and $port == '' and $method == '')
880 880
 			{
881 881
 				$parts = parse_url($path);
882 882
 				$server = $parts['host'];
883 883
 				$path = isset($parts['path']) ? $parts['path'] : '';
884
-				if(isset($parts['query']))
884
+				if (isset($parts['query']))
885 885
 				{
886 886
 					$path .= '?'.$parts['query'];
887 887
 				}
888
-				if(isset($parts['fragment']))
888
+				if (isset($parts['fragment']))
889 889
 				{
890 890
 					$path .= '#'.$parts['fragment'];
891 891
 				}
892
-				if(isset($parts['port']))
892
+				if (isset($parts['port']))
893 893
 				{
894 894
 					$port = $parts['port'];
895 895
 				}
896
-				if(isset($parts['scheme']))
896
+				if (isset($parts['scheme']))
897 897
 				{
898 898
 					$method = $parts['scheme'];
899 899
 				}
900
-				if(isset($parts['user']))
900
+				if (isset($parts['user']))
901 901
 				{
902 902
 					$this->username = $parts['user'];
903 903
 				}
904
-				if(isset($parts['pass']))
904
+				if (isset($parts['pass']))
905 905
 				{
906 906
 					$this->password = $parts['pass'];
907 907
 				}
908 908
 			}
909
-			if($path == '' || $path[0] != '/')
909
+			if ($path == '' || $path[0] != '/')
910 910
 			{
911
-				$this->path='/'.$path;
911
+				$this->path = '/'.$path;
912 912
 			}
913 913
 			else
914 914
 			{
915
-				$this->path=$path;
915
+				$this->path = $path;
916 916
 			}
917
-			$this->server=$server;
918
-			if($port != '')
917
+			$this->server = $server;
918
+			if ($port != '')
919 919
 			{
920
-				$this->port=$port;
920
+				$this->port = $port;
921 921
 			}
922
-			if($method != '')
922
+			if ($method != '')
923 923
 			{
924
-				$this->method=$method;
924
+				$this->method = $method;
925 925
 			}
926 926
 
927 927
 			// if ZLIB is enabled, let the client by default accept compressed responses
928
-			if(function_exists('gzinflate') || (
928
+			if (function_exists('gzinflate') || (
929 929
 				function_exists('curl_init') && (($info = curl_version()) &&
930 930
 				((is_string($info) && strpos($info, 'zlib') !== null) || isset($info['libz_version'])))
931 931
 			))
@@ -940,13 +940,13 @@  discard block
 block discarded – undo
940 940
 			$this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
941 941
 
942 942
 			// initialize user_agent string
943
-			$this->user_agent = $GLOBALS['xmlrpcName'] . ' ' . $GLOBALS['xmlrpcVersion'];
943
+			$this->user_agent = $GLOBALS['xmlrpcName'].' '.$GLOBALS['xmlrpcVersion'];
944 944
 		}
945 945
 
946 946
 		/**
947 947
 		* @deprecated
948 948
 		*/
949
-		function xmlrpc_client($path, $server='', $port='', $method='')
949
+		function xmlrpc_client($path, $server = '', $port = '', $method = '')
950 950
 		{
951 951
 			self::__construct($path, $server, $port, $method);
952 952
 		}
@@ -958,7 +958,7 @@  discard block
 block discarded – undo
958 958
 		*/
959 959
 		function setDebug($in)
960 960
 		{
961
-			$this->debug=$in;
961
+			$this->debug = $in;
962 962
 		}
963 963
 
964 964
 		/**
@@ -968,11 +968,11 @@  discard block
 block discarded – undo
968 968
 		* @param integer $t auth type. See curl_setopt man page for supported auth types. Defaults to CURLAUTH_BASIC (basic auth)
969 969
 		* @access public
970 970
 		*/
971
-		function setCredentials($u, $p, $t=1)
971
+		function setCredentials($u, $p, $t = 1)
972 972
 		{
973
-			$this->username=$u;
974
-			$this->password=$p;
975
-			$this->authtype=$t;
973
+			$this->username = $u;
974
+			$this->password = $p;
975
+			$this->authtype = $t;
976 976
 		}
977 977
 
978 978
 		/**
@@ -994,7 +994,7 @@  discard block
 block discarded – undo
994 994
 		* @param bool $is_dir set to true to indicate cacert is a dir. defaults to false
995 995
 		* @access public
996 996
 		*/
997
-		function setCaCertificate($cacert, $is_dir=false)
997
+		function setCaCertificate($cacert, $is_dir = false)
998 998
 		{
999 999
 			if ($is_dir)
1000 1000
 			{
@@ -1081,7 +1081,7 @@  discard block
 block discarded – undo
1081 1081
 			if ($compmethod == 'any')
1082 1082
 				$this->accepted_compression = array('gzip', 'deflate');
1083 1083
 			else
1084
-				if ($compmethod == false )
1084
+				if ($compmethod == false)
1085 1085
 					$this->accepted_compression = array();
1086 1086
 				else
1087 1087
 					$this->accepted_compression = array($compmethod);
@@ -1112,7 +1112,7 @@  discard block
 block discarded – undo
1112 1112
 		*
1113 1113
 		* @todo check correctness of urlencoding cookie value (copied from php way of doing it...)
1114 1114
 		*/
1115
-		function setCookie($name, $value='', $path='', $domain='', $port=null)
1115
+		function setCookie($name, $value = '', $path = '', $domain = '', $port = null)
1116 1116
 		{
1117 1117
 			$this->cookies[$name]['value'] = urlencode($value);
1118 1118
 			if ($path || $domain || $port)
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
 		* It allows eg. to bind client to a specific IP interface / address
1134 1134
 		* @param array $options
1135 1135
 		*/
1136
-		function SetCurlOptions( $options )
1136
+		function SetCurlOptions($options)
1137 1137
 		{
1138 1138
 			$this->extracurlopts = $options;
1139 1139
 		}
@@ -1142,7 +1142,7 @@  discard block
 block discarded – undo
1142 1142
 		* Set user-agent string that will be used by this client instance
1143 1143
 		* in http headers sent to the server
1144 1144
 		*/
1145
-		function SetUserAgent( $agentstring )
1145
+		function SetUserAgent($agentstring)
1146 1146
 		{
1147 1147
 			$this->user_agent = $agentstring;
1148 1148
 		}
@@ -1155,22 +1155,22 @@  discard block
 block discarded – undo
1155 1155
 		* @return xmlrpcresp
1156 1156
 		* @access public
1157 1157
 		*/
1158
-		function& send($msg, $timeout=0, $method='')
1158
+		function& send($msg, $timeout = 0, $method = '')
1159 1159
 		{
1160 1160
 			// if user deos not specify http protocol, use native method of this client
1161 1161
 			// (i.e. method set during call to constructor)
1162
-			if($method == '')
1162
+			if ($method == '')
1163 1163
 			{
1164 1164
 				$method = $this->method;
1165 1165
 			}
1166 1166
 
1167
-			if(is_array($msg))
1167
+			if (is_array($msg))
1168 1168
 			{
1169 1169
 				// $msg is an array of xmlrpcmsg's
1170 1170
 				$r = $this->multicall($msg, $timeout, $method);
1171 1171
 				return $r;
1172 1172
 			}
1173
-			elseif(is_string($msg))
1173
+			elseif (is_string($msg))
1174 1174
 			{
1175 1175
 				$n = new xmlrpcmsg('');
1176 1176
 				$n->payload = $msg;
@@ -1178,11 +1178,11 @@  discard block
 block discarded – undo
1178 1178
 			}
1179 1179
 
1180 1180
 			// where msg is an xmlrpcmsg
1181
-			$msg->debug=$this->debug;
1181
+			$msg->debug = $this->debug;
1182 1182
 
1183
-			if($method == 'https')
1183
+			if ($method == 'https')
1184 1184
 			{
1185
-				$r =& $this->sendPayloadHTTPS(
1185
+				$r = & $this->sendPayloadHTTPS(
1186 1186
 					$msg,
1187 1187
 					$this->server,
1188 1188
 					$this->port,
@@ -1205,9 +1205,9 @@  discard block
 block discarded – undo
1205 1205
 					$this->sslversion
1206 1206
 				);
1207 1207
 			}
1208
-			elseif($method == 'http11')
1208
+			elseif ($method == 'http11')
1209 1209
 			{
1210
-				$r =& $this->sendPayloadCURL(
1210
+				$r = & $this->sendPayloadCURL(
1211 1211
 					$msg,
1212 1212
 					$this->server,
1213 1213
 					$this->port,
@@ -1230,7 +1230,7 @@  discard block
 block discarded – undo
1230 1230
 			}
1231 1231
 			else
1232 1232
 			{
1233
-				$r =& $this->sendPayloadHTTP10(
1233
+				$r = & $this->sendPayloadHTTP10(
1234 1234
 					$msg,
1235 1235
 					$this->server,
1236 1236
 					$this->port,
@@ -1252,29 +1252,29 @@  discard block
 block discarded – undo
1252 1252
 		/**
1253 1253
 		* @access private
1254 1254
 		*/
1255
-		function &sendPayloadHTTP10($msg, $server, $port, $timeout=0,
1256
-			$username='', $password='', $authtype=1, $proxyhost='',
1257
-			$proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1)
1255
+		function &sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
1256
+			$username = '', $password = '', $authtype = 1, $proxyhost = '',
1257
+			$proxyport = 0, $proxyusername = '', $proxypassword = '', $proxyauthtype = 1)
1258 1258
 		{
1259
-			if($port==0)
1259
+			if ($port == 0)
1260 1260
 			{
1261
-				$port=80;
1261
+				$port = 80;
1262 1262
 			}
1263 1263
 
1264 1264
 			// Only create the payload if it was not created previously
1265
-			if(empty($msg->payload))
1265
+			if (empty($msg->payload))
1266 1266
 			{
1267 1267
 				$msg->createPayload($this->request_charset_encoding);
1268 1268
 			}
1269 1269
 
1270 1270
 			$payload = $msg->payload;
1271 1271
 			// Deflate request body and set appropriate request headers
1272
-			if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1272
+			if (function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1273 1273
 			{
1274
-				if($this->request_compression == 'gzip')
1274
+				if ($this->request_compression == 'gzip')
1275 1275
 				{
1276 1276
 					$a = @gzencode($payload);
1277
-					if($a)
1277
+					if ($a)
1278 1278
 					{
1279 1279
 						$payload = $a;
1280 1280
 						$encoding_hdr = "Content-Encoding: gzip\r\n";
@@ -1283,7 +1283,7 @@  discard block
 block discarded – undo
1283 1283
 				else
1284 1284
 				{
1285 1285
 					$a = @gzcompress($payload);
1286
-					if($a)
1286
+					if ($a)
1287 1287
 					{
1288 1288
 						$payload = $a;
1289 1289
 						$encoding_hdr = "Content-Encoding: deflate\r\n";
@@ -1296,10 +1296,10 @@  discard block
 block discarded – undo
1296 1296
 			}
1297 1297
 
1298 1298
 			// thanks to Grant Rauscher <[email protected]> for this
1299
-			$credentials='';
1300
-			if($username!='')
1299
+			$credentials = '';
1300
+			if ($username != '')
1301 1301
 			{
1302
-				$credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n";
1302
+				$credentials = 'Authorization: Basic '.base64_encode($username.':'.$password)."\r\n";
1303 1303
 				if ($authtype != 1)
1304 1304
 				{
1305 1305
 					error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported with HTTP 1.0');
@@ -1307,28 +1307,28 @@  discard block
 block discarded – undo
1307 1307
 			}
1308 1308
 
1309 1309
 			$accepted_encoding = '';
1310
-			if(is_array($this->accepted_compression) && count($this->accepted_compression))
1310
+			if (is_array($this->accepted_compression) && count($this->accepted_compression))
1311 1311
 			{
1312
-				$accepted_encoding = 'Accept-Encoding: ' . implode(', ', $this->accepted_compression) . "\r\n";
1312
+				$accepted_encoding = 'Accept-Encoding: '.implode(', ', $this->accepted_compression)."\r\n";
1313 1313
 			}
1314 1314
 
1315 1315
 			$proxy_credentials = '';
1316
-			if($proxyhost)
1316
+			if ($proxyhost)
1317 1317
 			{
1318
-				if($proxyport == 0)
1318
+				if ($proxyport == 0)
1319 1319
 				{
1320 1320
 					$proxyport = 8080;
1321 1321
 				}
1322 1322
 				$connectserver = $proxyhost;
1323 1323
 				$connectport = $proxyport;
1324 1324
 				$uri = 'http://'.$server.':'.$port.$this->path;
1325
-				if($proxyusername != '')
1325
+				if ($proxyusername != '')
1326 1326
 				{
1327 1327
 					if ($proxyauthtype != 1)
1328 1328
 					{
1329 1329
 						error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported with HTTP 1.0');
1330 1330
 					}
1331
-					$proxy_credentials = 'Proxy-Authorization: Basic ' . base64_encode($proxyusername.':'.$proxypassword) . "\r\n";
1331
+					$proxy_credentials = 'Proxy-Authorization: Basic '.base64_encode($proxyusername.':'.$proxypassword)."\r\n";
1332 1332
 				}
1333 1333
 			}
1334 1334
 			else
@@ -1340,7 +1340,7 @@  discard block
 block discarded – undo
1340 1340
 
1341 1341
 			// Cookie generation, as per rfc2965 (version 1 cookies) or
1342 1342
 			// netscape's rules (version 0 cookies)
1343
-			$cookieheader='';
1343
+			$cookieheader = '';
1344 1344
 			if (count($this->cookies))
1345 1345
 			{
1346 1346
 				$version = '';
@@ -1348,73 +1348,73 @@  discard block
 block discarded – undo
1348 1348
 				{
1349 1349
 					if ($cookie['version'])
1350 1350
 					{
1351
-						$version = ' $Version="' . $cookie['version'] . '";';
1352
-						$cookieheader .= ' ' . $name . '="' . $cookie['value'] . '";';
1351
+						$version = ' $Version="'.$cookie['version'].'";';
1352
+						$cookieheader .= ' '.$name.'="'.$cookie['value'].'";';
1353 1353
 						if ($cookie['path'])
1354
-							$cookieheader .= ' $Path="' . $cookie['path'] . '";';
1354
+							$cookieheader .= ' $Path="'.$cookie['path'].'";';
1355 1355
 						if ($cookie['domain'])
1356
-							$cookieheader .= ' $Domain="' . $cookie['domain'] . '";';
1356
+							$cookieheader .= ' $Domain="'.$cookie['domain'].'";';
1357 1357
 						if ($cookie['port'])
1358
-							$cookieheader .= ' $Port="' . $cookie['port'] . '";';
1358
+							$cookieheader .= ' $Port="'.$cookie['port'].'";';
1359 1359
 					}
1360 1360
 					else
1361 1361
 					{
1362
-						$cookieheader .= ' ' . $name . '=' . $cookie['value'] . ";";
1362
+						$cookieheader .= ' '.$name.'='.$cookie['value'].";";
1363 1363
 					}
1364 1364
 				}
1365
-				$cookieheader = 'Cookie:' . $version . substr($cookieheader, 0, -1) . "\r\n";
1365
+				$cookieheader = 'Cookie:'.$version.substr($cookieheader, 0, -1)."\r\n";
1366 1366
 			}
1367 1367
 
1368 1368
 			// omit port if 80
1369
-			$port = ($port == 80) ? '' : (':' . $port);
1370
-
1371
-			$op= 'POST ' . $uri. " HTTP/1.0\r\n" .
1372
-				'User-Agent: ' . $this->user_agent . "\r\n" .
1373
-				'Host: '. $server . $port . "\r\n" .
1374
-				$credentials .
1375
-				$proxy_credentials .
1376
-				$accepted_encoding .
1377
-				$encoding_hdr .
1378
-				'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings) . "\r\n" .
1379
-				$cookieheader .
1380
-				'Content-Type: ' . $msg->content_type . "\r\nContent-Length: " .
1381
-				strlen($payload) . "\r\n\r\n" .
1369
+			$port = ($port == 80) ? '' : (':'.$port);
1370
+
1371
+			$op = 'POST '.$uri." HTTP/1.0\r\n".
1372
+				'User-Agent: '.$this->user_agent."\r\n".
1373
+				'Host: '.$server.$port."\r\n".
1374
+				$credentials.
1375
+				$proxy_credentials.
1376
+				$accepted_encoding.
1377
+				$encoding_hdr.
1378
+				'Accept-Charset: '.implode(',', $this->accepted_charset_encodings)."\r\n".
1379
+				$cookieheader.
1380
+				'Content-Type: '.$msg->content_type."\r\nContent-Length: ".
1381
+				strlen($payload)."\r\n\r\n".
1382 1382
 				$payload;
1383 1383
 
1384
-			if($this->debug > 1)
1384
+			if ($this->debug>1)
1385 1385
 			{
1386
-				print "<PRE>\n---SENDING---\n" . htmlentities($op) . "\n---END---\n</PRE>";
1386
+				print "<PRE>\n---SENDING---\n".htmlentities($op)."\n---END---\n</PRE>";
1387 1387
 				// let the client see this now in case http times out...
1388 1388
 				flush();
1389 1389
 			}
1390 1390
 
1391
-			if($timeout>0)
1391
+			if ($timeout>0)
1392 1392
 			{
1393
-				$fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr, $timeout);
1393
+				$fp = @fsockopen($connectserver, $connectport, $this->errno, $this->errstr, $timeout);
1394 1394
 			}
1395 1395
 			else
1396 1396
 			{
1397
-				$fp=@fsockopen($connectserver, $connectport, $this->errno, $this->errstr);
1397
+				$fp = @fsockopen($connectserver, $connectport, $this->errno, $this->errstr);
1398 1398
 			}
1399
-			if($fp)
1399
+			if ($fp)
1400 1400
 			{
1401
-				if($timeout>0 && function_exists('stream_set_timeout'))
1401
+				if ($timeout>0 && function_exists('stream_set_timeout'))
1402 1402
 				{
1403 1403
 					stream_set_timeout($fp, $timeout);
1404 1404
 				}
1405 1405
 			}
1406 1406
 			else
1407 1407
 			{
1408
-				$this->errstr='Connect error: '.$this->errstr;
1409
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr . ' (' . $this->errno . ')');
1408
+				$this->errstr = 'Connect error: '.$this->errstr;
1409
+				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr.' ('.$this->errno.')');
1410 1410
 				return $r;
1411 1411
 			}
1412 1412
 
1413
-			if(!fputs($fp, $op, strlen($op)))
1413
+			if (!fputs($fp, $op, strlen($op)))
1414 1414
 			{
1415 1415
 				fclose($fp);
1416
-				$this->errstr='Write error';
1417
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr);
1416
+				$this->errstr = 'Write error';
1417
+				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $this->errstr);
1418 1418
 				return $r;
1419 1419
 			}
1420 1420
 			else
@@ -1424,15 +1424,15 @@  discard block
 block discarded – undo
1424 1424
 			}
1425 1425
 			// G. Giunta 2005/10/24: close socket before parsing.
1426 1426
 			// should yield slightly better execution times, and make easier recursive calls (e.g. to follow http redirects)
1427
-			$ipd='';
1427
+			$ipd = '';
1428 1428
 			do
1429 1429
 			{
1430 1430
 				// shall we check for $data === FALSE?
1431 1431
 				// as per the manual, it signals an error
1432
-				$ipd.=fread($fp, 32768);
1433
-			} while(!feof($fp));
1432
+				$ipd .= fread($fp, 32768);
1433
+			} while (!feof($fp));
1434 1434
 			fclose($fp);
1435
-			$r =& $msg->parseResponse($ipd, false, $this->return_type);
1435
+			$r = & $msg->parseResponse($ipd, false, $this->return_type);
1436 1436
 			return $r;
1437 1437
 
1438 1438
 		}
@@ -1440,12 +1440,12 @@  discard block
 block discarded – undo
1440 1440
 		/**
1441 1441
 		* @access private
1442 1442
 		*/
1443
-		function &sendPayloadHTTPS($msg, $server, $port, $timeout=0, $username='',
1444
-			$password='', $authtype=1, $cert='',$certpass='', $cacert='', $cacertdir='',
1445
-			$proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1,
1446
-			$keepalive=false, $key='', $keypass='', $sslVersion = 0)
1443
+		function &sendPayloadHTTPS($msg, $server, $port, $timeout = 0, $username = '',
1444
+			$password = '', $authtype = 1, $cert = '', $certpass = '', $cacert = '', $cacertdir = '',
1445
+			$proxyhost = '', $proxyport = 0, $proxyusername = '', $proxypassword = '', $proxyauthtype = 1,
1446
+			$keepalive = false, $key = '', $keypass = '', $sslVersion = 0)
1447 1447
 		{
1448
-			$r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username,
1448
+			$r = & $this->sendPayloadCURL($msg, $server, $port, $timeout, $username,
1449 1449
 				$password, $authtype, $cert, $certpass, $cacert, $cacertdir, $proxyhost, $proxyport,
1450 1450
 				$proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass, $sslVersion);
1451 1451
 			return $r;
@@ -1457,31 +1457,31 @@  discard block
 block discarded – undo
1457 1457
 		* NB: CURL versions before 7.11.10 cannot use proxy to talk to https servers!
1458 1458
 		* @access private
1459 1459
 		*/
1460
-		function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='',
1461
-			$password='', $authtype=1, $cert='', $certpass='', $cacert='', $cacertdir='',
1462
-			$proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $method='https',
1463
-			$keepalive=false, $key='', $keypass='', $sslVersion = 0)
1460
+		function &sendPayloadCURL($msg, $server, $port, $timeout = 0, $username = '',
1461
+			$password = '', $authtype = 1, $cert = '', $certpass = '', $cacert = '', $cacertdir = '',
1462
+			$proxyhost = '', $proxyport = 0, $proxyusername = '', $proxypassword = '', $proxyauthtype = 1, $method = 'https',
1463
+			$keepalive = false, $key = '', $keypass = '', $sslVersion = 0)
1464 1464
 		{
1465
-			if(!function_exists('curl_init'))
1465
+			if (!function_exists('curl_init'))
1466 1466
 			{
1467
-				$this->errstr='CURL unavailable on this install';
1468
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_curl'], $GLOBALS['xmlrpcstr']['no_curl']);
1467
+				$this->errstr = 'CURL unavailable on this install';
1468
+				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_curl'], $GLOBALS['xmlrpcstr']['no_curl']);
1469 1469
 				return $r;
1470 1470
 			}
1471
-			if($method == 'https')
1471
+			if ($method == 'https')
1472 1472
 			{
1473
-				if(($info = curl_version()) &&
1473
+				if (($info = curl_version()) &&
1474 1474
 					((is_string($info) && strpos($info, 'OpenSSL') === null) || (is_array($info) && !isset($info['ssl_version']))))
1475 1475
 				{
1476
-					$this->errstr='SSL unavailable on this install';
1477
-					$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_ssl'], $GLOBALS['xmlrpcstr']['no_ssl']);
1476
+					$this->errstr = 'SSL unavailable on this install';
1477
+					$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_ssl'], $GLOBALS['xmlrpcstr']['no_ssl']);
1478 1478
 					return $r;
1479 1479
 				}
1480 1480
 			}
1481 1481
 
1482
-			if($port == 0)
1482
+			if ($port == 0)
1483 1483
 			{
1484
-				if($method == 'http')
1484
+				if ($method == 'http')
1485 1485
 				{
1486 1486
 					$port = 80;
1487 1487
 				}
@@ -1492,19 +1492,19 @@  discard block
 block discarded – undo
1492 1492
 			}
1493 1493
 
1494 1494
 			// Only create the payload if it was not created previously
1495
-			if(empty($msg->payload))
1495
+			if (empty($msg->payload))
1496 1496
 			{
1497 1497
 				$msg->createPayload($this->request_charset_encoding);
1498 1498
 			}
1499 1499
 
1500 1500
 			// Deflate request body and set appropriate request headers
1501 1501
 			$payload = $msg->payload;
1502
-			if(function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1502
+			if (function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate'))
1503 1503
 			{
1504
-				if($this->request_compression == 'gzip')
1504
+				if ($this->request_compression == 'gzip')
1505 1505
 				{
1506 1506
 					$a = @gzencode($payload);
1507
-					if($a)
1507
+					if ($a)
1508 1508
 					{
1509 1509
 						$payload = $a;
1510 1510
 						$encoding_hdr = 'Content-Encoding: gzip';
@@ -1513,7 +1513,7 @@  discard block
 block discarded – undo
1513 1513
 				else
1514 1514
 				{
1515 1515
 					$a = @gzcompress($payload);
1516
-					if($a)
1516
+					if ($a)
1517 1517
 					{
1518 1518
 						$payload = $a;
1519 1519
 						$encoding_hdr = 'Content-Encoding: deflate';
@@ -1525,17 +1525,17 @@  discard block
 block discarded – undo
1525 1525
 				$encoding_hdr = '';
1526 1526
 			}
1527 1527
 
1528
-			if($this->debug > 1)
1528
+			if ($this->debug>1)
1529 1529
 			{
1530
-				print "<PRE>\n---SENDING---\n" . htmlentities($payload) . "\n---END---\n</PRE>";
1530
+				print "<PRE>\n---SENDING---\n".htmlentities($payload)."\n---END---\n</PRE>";
1531 1531
 				// let the client see this now in case http times out...
1532 1532
 				flush();
1533 1533
 			}
1534 1534
 
1535
-			if(!$keepalive || !$this->xmlrpc_curl_handle)
1535
+			if (!$keepalive || !$this->xmlrpc_curl_handle)
1536 1536
 			{
1537
-				$curl = curl_init($method . '://' . $server . ':' . $port . $this->path);
1538
-				if($keepalive)
1537
+				$curl = curl_init($method.'://'.$server.':'.$port.$this->path);
1538
+				if ($keepalive)
1539 1539
 				{
1540 1540
 					$this->xmlrpc_curl_handle = $curl;
1541 1541
 				}
@@ -1548,7 +1548,7 @@  discard block
 block discarded – undo
1548 1548
 			// results into variable
1549 1549
 			curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
1550 1550
 
1551
-			if($this->debug)
1551
+			if ($this->debug)
1552 1552
 			{
1553 1553
 				curl_setopt($curl, CURLOPT_VERBOSE, 1);
1554 1554
 			}
@@ -1564,7 +1564,7 @@  discard block
 block discarded – undo
1564 1564
 			// NB: if we set an empty string, CURL will add http header indicating
1565 1565
 			// ALL methods it is supporting. This is possibly a better option than
1566 1566
 			// letting the user tell what curl can / cannot do...
1567
-			if(is_array($this->accepted_compression) && count($this->accepted_compression))
1567
+			if (is_array($this->accepted_compression) && count($this->accepted_compression))
1568 1568
 			{
1569 1569
 				//curl_setopt($curl, CURLOPT_ENCODING, implode(',', $this->accepted_compression));
1570 1570
 				// empty string means 'any supported by CURL' (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
@@ -1576,26 +1576,26 @@  discard block
 block discarded – undo
1576 1576
 					curl_setopt($curl, CURLOPT_ENCODING, '');
1577 1577
 			}
1578 1578
 			// extra headers
1579
-			$headers = array('Content-Type: ' . $msg->content_type , 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings));
1579
+			$headers = array('Content-Type: '.$msg->content_type, 'Accept-Charset: '.implode(',', $this->accepted_charset_encodings));
1580 1580
 			// if no keepalive is wanted, let the server know it in advance
1581
-			if(!$keepalive)
1581
+			if (!$keepalive)
1582 1582
 			{
1583 1583
 				$headers[] = 'Connection: close';
1584 1584
 			}
1585 1585
 			// request compression header
1586
-			if($encoding_hdr)
1586
+			if ($encoding_hdr)
1587 1587
 			{
1588 1588
 				$headers[] = $encoding_hdr;
1589 1589
 			}
1590 1590
 
1591 1591
 			curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1592 1592
 			// timeout is borked
1593
-			if($timeout)
1593
+			if ($timeout)
1594 1594
 			{
1595
-				curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1);
1595
+				curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout-1);
1596 1596
 			}
1597 1597
 
1598
-			if($username && $password)
1598
+			if ($username && $password)
1599 1599
 			{
1600 1600
 				curl_setopt($curl, CURLOPT_USERPWD, $username.':'.$password);
1601 1601
 				if (defined('CURLOPT_HTTPAUTH'))
@@ -1608,43 +1608,43 @@  discard block
 block discarded – undo
1608 1608
 				}
1609 1609
 			}
1610 1610
 
1611
-			if($method == 'https')
1611
+			if ($method == 'https')
1612 1612
 			{
1613 1613
 				// set cert file
1614
-				if($cert)
1614
+				if ($cert)
1615 1615
 				{
1616 1616
 					curl_setopt($curl, CURLOPT_SSLCERT, $cert);
1617 1617
 				}
1618 1618
 				// set cert password
1619
-				if($certpass)
1619
+				if ($certpass)
1620 1620
 				{
1621 1621
 					curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $certpass);
1622 1622
 				}
1623 1623
 				// whether to verify remote host's cert
1624 1624
 				curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer);
1625 1625
 				// set ca certificates file/dir
1626
-				if($cacert)
1626
+				if ($cacert)
1627 1627
 				{
1628 1628
 					curl_setopt($curl, CURLOPT_CAINFO, $cacert);
1629 1629
 				}
1630
-				if($cacertdir)
1630
+				if ($cacertdir)
1631 1631
 				{
1632 1632
 					curl_setopt($curl, CURLOPT_CAPATH, $cacertdir);
1633 1633
 				}
1634 1634
 				// set key file (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1635
-				if($key)
1635
+				if ($key)
1636 1636
 				{
1637 1637
 					curl_setopt($curl, CURLOPT_SSLKEY, $key);
1638 1638
 				}
1639 1639
 				// set key password (shall we catch errors in case CURLOPT_SSLKEY undefined ?)
1640
-				if($keypass)
1640
+				if ($keypass)
1641 1641
 				{
1642 1642
 					curl_setopt($curl, CURLOPT_SSLKEYPASSWD, $keypass);
1643 1643
 				}
1644 1644
 
1645 1645
 				// Upgrade transparently to more stringent check for versions of php which do not support otherwise.
1646 1646
 				// Doing it in constructor would be cleaner; doing it here saves us a couple of function calls
1647
-				if($this->verifyhost == 1 && $info = curl_version() && version_compare($info['version'], '7.28.1') >= 0)
1647
+				if ($this->verifyhost == 1 && $info = curl_version() && version_compare($info['version'], '7.28.1')>=0)
1648 1648
 				{
1649 1649
 					$this->verifyhost = 2;
1650 1650
 				}
@@ -1655,15 +1655,15 @@  discard block
 block discarded – undo
1655 1655
 			}
1656 1656
 
1657 1657
 			// proxy info
1658
-			if($proxyhost)
1658
+			if ($proxyhost)
1659 1659
 			{
1660
-				if($proxyport == 0)
1660
+				if ($proxyport == 0)
1661 1661
 				{
1662 1662
 					$proxyport = 8080; // NB: even for HTTPS, local connection is on port 8080
1663 1663
 				}
1664 1664
 				curl_setopt($curl, CURLOPT_PROXY, $proxyhost.':'.$proxyport);
1665 1665
 				//curl_setopt($curl, CURLOPT_PROXYPORT,$proxyport);
1666
-				if($proxyusername)
1666
+				if ($proxyusername)
1667 1667
 				{
1668 1668
 					curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyusername.':'.$proxypassword);
1669 1669
 					if (defined('CURLOPT_PROXYAUTH'))
@@ -1685,7 +1685,7 @@  discard block
 block discarded – undo
1685 1685
 				$cookieheader = '';
1686 1686
 				foreach ($this->cookies as $name => $cookie)
1687 1687
 				{
1688
-					$cookieheader .= $name . '=' . $cookie['value'] . '; ';
1688
+					$cookieheader .= $name.'='.$cookie['value'].'; ';
1689 1689
 				}
1690 1690
 				curl_setopt($curl, CURLOPT_COOKIE, substr($cookieheader, 0, -2));
1691 1691
 			}
@@ -1697,40 +1697,40 @@  discard block
 block discarded – undo
1697 1697
 
1698 1698
 			$result = curl_exec($curl);
1699 1699
 
1700
-			if ($this->debug > 1)
1700
+			if ($this->debug>1)
1701 1701
 			{
1702 1702
 				print "<PRE>\n---CURL INFO---\n";
1703
-				foreach(curl_getinfo($curl) as $name => $val)
1703
+				foreach (curl_getinfo($curl) as $name => $val)
1704 1704
 				{
1705 1705
 					if (is_array($val))
1706 1706
 					{
1707 1707
 						$val = implode("\n", $val);
1708 1708
 					}
1709
-					print $name . ': ' . htmlentities($val) . "\n";
1709
+					print $name.': '.htmlentities($val)."\n";
1710 1710
 				}
1711 1711
 
1712 1712
 				print "---END---\n</PRE>";
1713 1713
 			}
1714 1714
 
1715
-			if(!$result) /// @todo we should use a better check here - what if we get back '' or '0'?
1715
+			if (!$result) /// @todo we should use a better check here - what if we get back '' or '0'?
1716 1716
 			{
1717
-				$this->errstr='no response';
1718
-				$resp=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['curl_fail'], $GLOBALS['xmlrpcstr']['curl_fail']. ': '. curl_error($curl));
1717
+				$this->errstr = 'no response';
1718
+				$resp = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['curl_fail'], $GLOBALS['xmlrpcstr']['curl_fail'].': '.curl_error($curl));
1719 1719
 				curl_close($curl);
1720
-				if($keepalive)
1720
+				if ($keepalive)
1721 1721
 				{
1722 1722
 					$this->xmlrpc_curl_handle = null;
1723 1723
 				}
1724 1724
 			}
1725 1725
 			else
1726 1726
 			{
1727
-				if(!$keepalive)
1727
+				if (!$keepalive)
1728 1728
 				{
1729 1729
 					curl_close($curl);
1730 1730
 				}
1731
-				$resp =& $msg->parseResponse($result, true, $this->return_type);
1731
+				$resp = & $msg->parseResponse($result, true, $this->return_type);
1732 1732
 				// if we got back a 302, we can not reuse the curl handle for later calls
1733
-				if($resp->faultCode() == $GLOBALS['xmlrpcerr']['http_error'] && $keepalive)
1733
+				if ($resp->faultCode() == $GLOBALS['xmlrpcerr']['http_error'] && $keepalive)
1734 1734
 				{
1735 1735
 					curl_close($curl);
1736 1736
 					$this->xmlrpc_curl_handle = null;
@@ -1761,16 +1761,16 @@  discard block
 block discarded – undo
1761 1761
 		* @return array
1762 1762
 		* @access public
1763 1763
 		*/
1764
-		function multicall($msgs, $timeout=0, $method='', $fallback=true)
1764
+		function multicall($msgs, $timeout = 0, $method = '', $fallback = true)
1765 1765
 		{
1766 1766
 			if ($method == '')
1767 1767
 			{
1768 1768
 				$method = $this->method;
1769 1769
 			}
1770
-			if(!$this->no_multicall)
1770
+			if (!$this->no_multicall)
1771 1771
 			{
1772 1772
 				$results = $this->_try_multicall($msgs, $timeout, $method);
1773
-				if(is_array($results))
1773
+				if (is_array($results))
1774 1774
 				{
1775 1775
 					// System.multicall succeeded
1776 1776
 					return $results;
@@ -1809,9 +1809,9 @@  discard block
 block discarded – undo
1809 1809
 			{
1810 1810
 				// system.multicall is (probably) unsupported by server:
1811 1811
 				// emulate multicall via multiple requests
1812
-				foreach($msgs as $msg)
1812
+				foreach ($msgs as $msg)
1813 1813
 				{
1814
-					$results[] =& $this->send($msg, $timeout, $method);
1814
+					$results[] = & $this->send($msg, $timeout, $method);
1815 1815
 				}
1816 1816
 			}
1817 1817
 			else
@@ -1819,7 +1819,7 @@  discard block
 block discarded – undo
1819 1819
 				// user does NOT want to fallback on many single calls:
1820 1820
 				// since we should always return an array of responses,
1821 1821
 				// return an array with the same error repeated n times
1822
-				foreach($msgs as $msg)
1822
+				foreach ($msgs as $msg)
1823 1823
 				{
1824 1824
 					$results[] = $result;
1825 1825
 				}
@@ -1837,12 +1837,12 @@  discard block
 block discarded – undo
1837 1837
 		{
1838 1838
 			// Construct multicall message
1839 1839
 			$calls = array();
1840
-			foreach($msgs as $msg)
1840
+			foreach ($msgs as $msg)
1841 1841
 			{
1842
-				$call['methodName'] = new xmlrpcval($msg->method(),'string');
1842
+				$call['methodName'] = new xmlrpcval($msg->method(), 'string');
1843 1843
 				$numParams = $msg->getNumParams();
1844 1844
 				$params = array();
1845
-				for($i = 0; $i < $numParams; $i++)
1845
+				for ($i = 0; $i<$numParams; $i++)
1846 1846
 				{
1847 1847
 					$params[$i] = $msg->getParam($i);
1848 1848
 				}
@@ -1853,9 +1853,9 @@  discard block
 block discarded – undo
1853 1853
 			$multicall->addParam(new xmlrpcval($calls, 'array'));
1854 1854
 
1855 1855
 			// Attempt RPC call
1856
-			$result =& $this->send($multicall, $timeout, $method);
1856
+			$result = & $this->send($multicall, $timeout, $method);
1857 1857
 
1858
-			if($result->faultCode() != 0)
1858
+			if ($result->faultCode() != 0)
1859 1859
 			{
1860 1860
 				// call to system.multicall failed
1861 1861
 				return $result;
@@ -1872,29 +1872,29 @@  discard block
 block discarded – undo
1872 1872
 			{
1873 1873
 				///@todo test this code branch...
1874 1874
 				$rets = $result->value();
1875
-				if(!is_array($rets))
1875
+				if (!is_array($rets))
1876 1876
 				{
1877
-					return false;		// bad return type from system.multicall
1877
+					return false; // bad return type from system.multicall
1878 1878
 				}
1879 1879
 				$numRets = count($rets);
1880
-				if($numRets != count($msgs))
1880
+				if ($numRets != count($msgs))
1881 1881
 				{
1882
-					return false;		// wrong number of return values.
1882
+					return false; // wrong number of return values.
1883 1883
 				}
1884 1884
 
1885 1885
 				$response = array();
1886
-				for($i = 0; $i < $numRets; $i++)
1886
+				for ($i = 0; $i<$numRets; $i++)
1887 1887
 				{
1888 1888
 					$val = $rets[$i];
1889 1889
 					if (!is_array($val)) {
1890 1890
 						return false;
1891 1891
 					}
1892
-					switch(count($val))
1892
+					switch (count($val))
1893 1893
 					{
1894 1894
 						case 1:
1895
-							if(!isset($val[0]))
1895
+							if (!isset($val[0]))
1896 1896
 							{
1897
-								return false;		// Bad value
1897
+								return false; // Bad value
1898 1898
 							}
1899 1899
 							// Normal return value
1900 1900
 							$response[$i] = new xmlrpcresp($val[0], 0, '', 'phpvals');
@@ -1902,12 +1902,12 @@  discard block
 block discarded – undo
1902 1902
 						case 2:
1903 1903
 							///	@todo remove usage of @: it is apparently quite slow
1904 1904
 							$code = @$val['faultCode'];
1905
-							if(!is_int($code))
1905
+							if (!is_int($code))
1906 1906
 							{
1907 1907
 								return false;
1908 1908
 							}
1909 1909
 							$str = @$val['faultString'];
1910
-							if(!is_string($str))
1910
+							if (!is_string($str))
1911 1911
 							{
1912 1912
 								return false;
1913 1913
 							}
@@ -1922,38 +1922,38 @@  discard block
 block discarded – undo
1922 1922
 			else // return type == 'xmlrpcvals'
1923 1923
 			{
1924 1924
 				$rets = $result->value();
1925
-				if($rets->kindOf() != 'array')
1925
+				if ($rets->kindOf() != 'array')
1926 1926
 				{
1927
-					return false;		// bad return type from system.multicall
1927
+					return false; // bad return type from system.multicall
1928 1928
 				}
1929 1929
 				$numRets = $rets->arraysize();
1930
-				if($numRets != count($msgs))
1930
+				if ($numRets != count($msgs))
1931 1931
 				{
1932
-					return false;		// wrong number of return values.
1932
+					return false; // wrong number of return values.
1933 1933
 				}
1934 1934
 
1935 1935
 				$response = array();
1936
-				for($i = 0; $i < $numRets; $i++)
1936
+				for ($i = 0; $i<$numRets; $i++)
1937 1937
 				{
1938 1938
 					$val = $rets->arraymem($i);
1939
-					switch($val->kindOf())
1939
+					switch ($val->kindOf())
1940 1940
 					{
1941 1941
 						case 'array':
1942
-							if($val->arraysize() != 1)
1942
+							if ($val->arraysize() != 1)
1943 1943
 							{
1944
-								return false;		// Bad value
1944
+								return false; // Bad value
1945 1945
 							}
1946 1946
 							// Normal return value
1947 1947
 							$response[$i] = new xmlrpcresp($val->arraymem(0));
1948 1948
 							break;
1949 1949
 						case 'struct':
1950 1950
 							$code = $val->structmem('faultCode');
1951
-							if($code->kindOf() != 'scalar' || $code->scalartyp() != 'int')
1951
+							if ($code->kindOf() != 'scalar' || $code->scalartyp() != 'int')
1952 1952
 							{
1953 1953
 								return false;
1954 1954
 							}
1955 1955
 							$str = $val->structmem('faultString');
1956
-							if($str->kindOf() != 'scalar' || $str->scalartyp() != 'string')
1956
+							if ($str->kindOf() != 'scalar' || $str->scalartyp() != 'string')
1957 1957
 							{
1958 1958
 								return false;
1959 1959
 							}
@@ -1990,9 +1990,9 @@  discard block
 block discarded – undo
1990 1990
 		* NB: as of now we do not do it, since it might be either an xmlrpcval or a plain
1991 1991
 		* php val, or a complete xml chunk, depending on usage of xmlrpc_client::send() inside which creator is called...
1992 1992
 		*/
1993
-		function __construct($val, $fcode = 0, $fstr = '', $valtyp='')
1993
+		function __construct($val, $fcode = 0, $fstr = '', $valtyp = '')
1994 1994
 		{
1995
-			if($fcode != 0)
1995
+			if ($fcode != 0)
1996 1996
 			{
1997 1997
 				// error response
1998 1998
 				$this->errno = $fcode;
@@ -2031,7 +2031,7 @@  discard block
 block discarded – undo
2031 2031
 		/**
2032 2032
 		* @deprecated
2033 2033
 		*/
2034
-		function xmlrpcresp($val, $fcode = 0, $fstr = '', $valtyp='')
2034
+		function xmlrpcresp($val, $fcode = 0, $fstr = '', $valtyp = '')
2035 2035
 		{
2036 2036
 			self::__construct($val, $fcode, $fstr, $valtyp);
2037 2037
 		}
@@ -2088,10 +2088,10 @@  discard block
 block discarded – undo
2088 2088
 		* @return string the xml representation of the response
2089 2089
 		* @access public
2090 2090
 		*/
2091
-		function serialize($charset_encoding='')
2091
+		function serialize($charset_encoding = '')
2092 2092
 		{
2093 2093
 			if ($charset_encoding != '')
2094
-				$this->content_type = 'text/xml; charset=' . $charset_encoding;
2094
+				$this->content_type = 'text/xml; charset='.$charset_encoding;
2095 2095
 			else
2096 2096
 				$this->content_type = 'text/xml';
2097 2097
 			if ($GLOBALS['xmlrpc_null_apache_encoding'])
@@ -2102,24 +2102,24 @@  discard block
 block discarded – undo
2102 2102
 			{
2103 2103
 			$result = "<methodResponse>\n";
2104 2104
 			}
2105
-			if($this->errno)
2105
+			if ($this->errno)
2106 2106
 			{
2107 2107
 				// G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients
2108 2108
 				// by xml-encoding non ascii chars
2109
-				$result .= "<fault>\n" .
2110
-"<value>\n<struct><member><name>faultCode</name>\n<value><int>" . $this->errno .
2111
-"</int></value>\n</member>\n<member>\n<name>faultString</name>\n<value><string>" .
2112
-xmlrpc_encode_entitites($this->errstr, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "</string></value>\n</member>\n" .
2109
+				$result .= "<fault>\n".
2110
+"<value>\n<struct><member><name>faultCode</name>\n<value><int>".$this->errno.
2111
+"</int></value>\n</member>\n<member>\n<name>faultString</name>\n<value><string>".
2112
+xmlrpc_encode_entitites($this->errstr, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</string></value>\n</member>\n".
2113 2113
 "</struct>\n</value>\n</fault>";
2114 2114
 			}
2115 2115
 			else
2116 2116
 			{
2117
-				if(!is_object($this->val) || !is_a($this->val, 'xmlrpcval'))
2117
+				if (!is_object($this->val) || !is_a($this->val, 'xmlrpcval'))
2118 2118
 				{
2119 2119
 					if (is_string($this->val) && $this->valtyp == 'xml')
2120 2120
 					{
2121
-						$result .= "<params>\n<param>\n" .
2122
-							$this->val .
2121
+						$result .= "<params>\n<param>\n".
2122
+							$this->val.
2123 2123
 							"</param>\n</params>";
2124 2124
 					}
2125 2125
 					else
@@ -2130,8 +2130,8 @@  discard block
 block discarded – undo
2130 2130
 				}
2131 2131
 				else
2132 2132
 				{
2133
-					$result .= "<params>\n<param>\n" .
2134
-						$this->val->serialize($charset_encoding) .
2133
+					$result .= "<params>\n<param>\n".
2134
+						$this->val->serialize($charset_encoding).
2135 2135
 						"</param>\n</params>";
2136 2136
 				}
2137 2137
 			}
@@ -2145,20 +2145,20 @@  discard block
 block discarded – undo
2145 2145
 	{
2146 2146
 		var $payload;
2147 2147
 		var $methodname;
2148
-		var $params=array();
2149
-		var $debug=0;
2148
+		var $params = array();
2149
+		var $debug = 0;
2150 2150
 		var $content_type = 'text/xml';
2151 2151
 
2152 2152
 		/**
2153 2153
 		* @param string $meth the name of the method to invoke
2154 2154
 		* @param array $pars array of parameters to be passed to the method (xmlrpcval objects)
2155 2155
 		*/
2156
-		function __construct($meth, $pars=0)
2156
+		function __construct($meth, $pars = 0)
2157 2157
 		{
2158
-			$this->methodname=$meth;
2159
-			if(is_array($pars) && count($pars)>0)
2158
+			$this->methodname = $meth;
2159
+			if (is_array($pars) && count($pars)>0)
2160 2160
 			{
2161
-				for($i=0; $i<count($pars); $i++)
2161
+				for ($i = 0; $i<count($pars); $i++)
2162 2162
 				{
2163 2163
 					$this->addParam($pars[$i]);
2164 2164
 				}
@@ -2168,7 +2168,7 @@  discard block
 block discarded – undo
2168 2168
 				/**
2169 2169
 		* @deprecated
2170 2170
 		*/
2171
-		function xmlrpcmsg($meth, $pars=0)
2171
+		function xmlrpcmsg($meth, $pars = 0)
2172 2172
 		{
2173 2173
 			self::__construct($meth, $pars);
2174 2174
 		}
@@ -2176,15 +2176,15 @@  discard block
 block discarded – undo
2176 2176
 		/**
2177 2177
 		* @access private
2178 2178
 		*/
2179
-		function xml_header($charset_encoding='')
2179
+		function xml_header($charset_encoding = '')
2180 2180
 		{
2181 2181
 			if ($charset_encoding != '')
2182 2182
 			{
2183
-				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\" ?" . ">\n<methodCall>\n";
2183
+				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\" ?".">\n<methodCall>\n";
2184 2184
 			}
2185 2185
 			else
2186 2186
 			{
2187
-				return "<?xml version=\"1.0\"?" . ">\n<methodCall>\n";
2187
+				return "<?xml version=\"1.0\"?".">\n<methodCall>\n";
2188 2188
 			}
2189 2189
 		}
2190 2190
 
@@ -2207,23 +2207,23 @@  discard block
 block discarded – undo
2207 2207
 		/**
2208 2208
 		* @access private
2209 2209
 		*/
2210
-		function createPayload($charset_encoding='')
2210
+		function createPayload($charset_encoding = '')
2211 2211
 		{
2212 2212
 			if ($charset_encoding != '')
2213
-				$this->content_type = 'text/xml; charset=' . $charset_encoding;
2213
+				$this->content_type = 'text/xml; charset='.$charset_encoding;
2214 2214
 			else
2215 2215
 				$this->content_type = 'text/xml';
2216
-			$this->payload=$this->xml_header($charset_encoding);
2217
-			$this->payload.='<methodName>' . xmlrpc_encode_entitites($this->methodname, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "</methodName>\n";
2218
-			$this->payload.="<params>\n";
2219
-			for($i=0; $i<count($this->params); $i++)
2216
+			$this->payload = $this->xml_header($charset_encoding);
2217
+			$this->payload .= '<methodName>'.xmlrpc_encode_entitites($this->methodname, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</methodName>\n";
2218
+			$this->payload .= "<params>\n";
2219
+			for ($i = 0; $i<count($this->params); $i++)
2220 2220
 			{
2221
-				$p=$this->params[$i];
2222
-				$this->payload.="<param>\n" . $p->serialize($charset_encoding) .
2221
+				$p = $this->params[$i];
2222
+				$this->payload .= "<param>\n".$p->serialize($charset_encoding).
2223 2223
 				"</param>\n";
2224 2224
 			}
2225
-			$this->payload.="</params>\n";
2226
-			$this->payload.=$this->xml_footer();
2225
+			$this->payload .= "</params>\n";
2226
+			$this->payload .= $this->xml_footer();
2227 2227
 		}
2228 2228
 
2229 2229
 		/**
@@ -2232,11 +2232,11 @@  discard block
 block discarded – undo
2232 2232
 		* @return string the method that will be invoked
2233 2233
 		* @access public
2234 2234
 		*/
2235
-		function method($meth='')
2235
+		function method($meth = '')
2236 2236
 		{
2237
-			if($meth!='')
2237
+			if ($meth != '')
2238 2238
 			{
2239
-				$this->methodname=$meth;
2239
+				$this->methodname = $meth;
2240 2240
 			}
2241 2241
 			return $this->methodname;
2242 2242
 		}
@@ -2247,7 +2247,7 @@  discard block
 block discarded – undo
2247 2247
 		* @return string the xml representation of the message, xml prologue included
2248 2248
 		* @access public
2249 2249
 		*/
2250
-		function serialize($charset_encoding='')
2250
+		function serialize($charset_encoding = '')
2251 2251
 		{
2252 2252
 			$this->createPayload($charset_encoding);
2253 2253
 			return $this->payload;
@@ -2262,9 +2262,9 @@  discard block
 block discarded – undo
2262 2262
 		function addParam($par)
2263 2263
 		{
2264 2264
 			// add check: do not add to self params which are not xmlrpcvals
2265
-			if(is_object($par) && is_a($par, 'xmlrpcval'))
2265
+			if (is_object($par) && is_a($par, 'xmlrpcval'))
2266 2266
 			{
2267
-				$this->params[]=$par;
2267
+				$this->params[] = $par;
2268 2268
 				return true;
2269 2269
 			}
2270 2270
 			else
@@ -2303,13 +2303,13 @@  discard block
 block discarded – undo
2303 2303
 		*/
2304 2304
 		function &parseResponseFile($fp)
2305 2305
 		{
2306
-			$ipd='';
2307
-			while($data=fread($fp, 32768))
2306
+			$ipd = '';
2307
+			while ($data = fread($fp, 32768))
2308 2308
 			{
2309
-				$ipd.=$data;
2309
+				$ipd .= $data;
2310 2310
 			}
2311 2311
 			//fclose($fp);
2312
-			$r =& $this->parseResponse($ipd);
2312
+			$r = & $this->parseResponse($ipd);
2313 2313
 			return $r;
2314 2314
 		}
2315 2315
 
@@ -2317,22 +2317,22 @@  discard block
 block discarded – undo
2317 2317
 		* Parses HTTP headers and separates them from data.
2318 2318
 		* @access private
2319 2319
 		*/
2320
-		function &parseResponseHeaders(&$data, $headers_processed=false)
2320
+		function &parseResponseHeaders(&$data, $headers_processed = false)
2321 2321
 		{
2322 2322
 				// Support "web-proxy-tunelling" connections for https through proxies
2323
-				if(preg_match('/^HTTP\/1\.[0-1] 200 Connection established/', $data))
2323
+				if (preg_match('/^HTTP\/1\.[0-1] 200 Connection established/', $data))
2324 2324
 				{
2325 2325
 					// Look for CR/LF or simple LF as line separator,
2326 2326
 					// (even though it is not valid http)
2327
-					$pos = strpos($data,"\r\n\r\n");
2328
-					if($pos || is_int($pos))
2327
+					$pos = strpos($data, "\r\n\r\n");
2328
+					if ($pos || is_int($pos))
2329 2329
 					{
2330 2330
 						$bd = $pos+4;
2331 2331
 					}
2332 2332
 					else
2333 2333
 					{
2334
-						$pos = strpos($data,"\n\n");
2335
-						if($pos || is_int($pos))
2334
+						$pos = strpos($data, "\n\n");
2335
+						if ($pos || is_int($pos))
2336 2336
 						{
2337 2337
 							$bd = $pos+2;
2338 2338
 						}
@@ -2351,28 +2351,28 @@  discard block
 block discarded – undo
2351 2351
 					else
2352 2352
 					{
2353 2353
 						error_log('XML-RPC: '.__METHOD__.': HTTPS via proxy error, tunnel connection possibly failed');
2354
-						$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (HTTPS via proxy error, tunnel connection possibly failed)');
2354
+						$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error'].' (HTTPS via proxy error, tunnel connection possibly failed)');
2355 2355
 						return $r;
2356 2356
 					}
2357 2357
 				}
2358 2358
 
2359 2359
 				// Strip HTTP 1.1 100 Continue header if present
2360
-				while(preg_match('/^HTTP\/1\.1 1[0-9]{2} /', $data))
2360
+				while (preg_match('/^HTTP\/1\.1 1[0-9]{2} /', $data))
2361 2361
 				{
2362 2362
 					$pos = strpos($data, 'HTTP', 12);
2363 2363
 					// server sent a Continue header without any (valid) content following...
2364 2364
 					// give the client a chance to know it
2365
-					if(!$pos && !is_int($pos)) // works fine in php 3, 4 and 5
2365
+					if (!$pos && !is_int($pos)) // works fine in php 3, 4 and 5
2366 2366
 					{
2367 2367
 						break;
2368 2368
 					}
2369 2369
 					$data = substr($data, $pos);
2370 2370
 				}
2371
-				if(!preg_match('/^HTTP\/[0-9.]+ 200 /', $data))
2371
+				if (!preg_match('/^HTTP\/[0-9.]+ 200 /', $data))
2372 2372
 				{
2373
-					$errstr= substr($data, 0, strpos($data, "\n")-1);
2374
-					error_log('XML-RPC: '.__METHOD__.': HTTP error, got response: ' .$errstr);
2375
-					$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (' . $errstr . ')');
2373
+					$errstr = substr($data, 0, strpos($data, "\n")-1);
2374
+					error_log('XML-RPC: '.__METHOD__.': HTTP error, got response: '.$errstr);
2375
+					$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error'].' ('.$errstr.')');
2376 2376
 					return $r;
2377 2377
 				}
2378 2378
 
@@ -2381,15 +2381,15 @@  discard block
 block discarded – undo
2381 2381
 
2382 2382
 				// be tolerant to usage of \n instead of \r\n to separate headers and data
2383 2383
 				// (even though it is not valid http)
2384
-				$pos = strpos($data,"\r\n\r\n");
2385
-				if($pos || is_int($pos))
2384
+				$pos = strpos($data, "\r\n\r\n");
2385
+				if ($pos || is_int($pos))
2386 2386
 				{
2387 2387
 					$bd = $pos+4;
2388 2388
 				}
2389 2389
 				else
2390 2390
 				{
2391
-					$pos = strpos($data,"\n\n");
2392
-					if($pos || is_int($pos))
2391
+					$pos = strpos($data, "\n\n");
2392
+					if ($pos || is_int($pos))
2393 2393
 					{
2394 2394
 						$bd = $pos+2;
2395 2395
 					}
@@ -2402,11 +2402,11 @@  discard block
 block discarded – undo
2402 2402
 				}
2403 2403
 				// be tolerant to line endings, and extra empty lines
2404 2404
 				$ar = preg_split("/\r?\n/", trim(substr($data, 0, $pos)));
2405
-				while(list(,$line) = @each($ar))
2405
+				while (list(,$line) = @each($ar))
2406 2406
 				{
2407 2407
 					// take care of multi-line headers and cookies
2408
-					$arr = explode(':',$line,2);
2409
-					if(count($arr) > 1)
2408
+					$arr = explode(':', $line, 2);
2409
+					if (count($arr)>1)
2410 2410
 					{
2411 2411
 						$header_name = strtolower(trim($arr[0]));
2412 2412
 						/// @todo some other headers (the ones that allow a CSV list of values)
@@ -2430,7 +2430,7 @@  discard block
 block discarded – undo
2430 2430
 								// glue together all received cookies, using a comma to separate them
2431 2431
 								// (same as php does with getallheaders())
2432 2432
 								if (isset($GLOBALS['_xh']['headers'][$header_name]))
2433
-									$GLOBALS['_xh']['headers'][$header_name] .= ', ' . trim($cookie);
2433
+									$GLOBALS['_xh']['headers'][$header_name] .= ', '.trim($cookie);
2434 2434
 								else
2435 2435
 									$GLOBALS['_xh']['headers'][$header_name] = trim($cookie);
2436 2436
 								// parse cookie attributes, in case user wants to correctly honour them
@@ -2464,23 +2464,23 @@  discard block
 block discarded – undo
2464 2464
 							$GLOBALS['_xh']['headers'][$header_name] = trim($arr[1]);
2465 2465
 						}
2466 2466
 					}
2467
-					elseif(isset($header_name))
2467
+					elseif (isset($header_name))
2468 2468
 					{
2469 2469
 						///	@todo version1 cookies might span multiple lines, thus breaking the parsing above
2470
-						$GLOBALS['_xh']['headers'][$header_name] .= ' ' . trim($line);
2470
+						$GLOBALS['_xh']['headers'][$header_name] .= ' '.trim($line);
2471 2471
 					}
2472 2472
 				}
2473 2473
 
2474 2474
 				$data = substr($data, $bd);
2475 2475
 
2476
-				if($this->debug && count($GLOBALS['_xh']['headers']))
2476
+				if ($this->debug && count($GLOBALS['_xh']['headers']))
2477 2477
 				{
2478 2478
 					print '<PRE>';
2479
-					foreach($GLOBALS['_xh']['headers'] as $header => $value)
2479
+					foreach ($GLOBALS['_xh']['headers'] as $header => $value)
2480 2480
 					{
2481 2481
 						print htmlentities("HEADER: $header: $value\n");
2482 2482
 					}
2483
-					foreach($GLOBALS['_xh']['cookies'] as $header => $value)
2483
+					foreach ($GLOBALS['_xh']['cookies'] as $header => $value)
2484 2484
 					{
2485 2485
 						print htmlentities("COOKIE: $header={$value['value']}\n");
2486 2486
 					}
@@ -2489,12 +2489,12 @@  discard block
 block discarded – undo
2489 2489
 
2490 2490
 				// if CURL was used for the call, http headers have been processed,
2491 2491
 				// and dechunking + reinflating have been carried out
2492
-				if(!$headers_processed)
2492
+				if (!$headers_processed)
2493 2493
 				{
2494 2494
 					// Decode chunked encoding sent by http 1.1 servers
2495
-					if(isset($GLOBALS['_xh']['headers']['transfer-encoding']) && $GLOBALS['_xh']['headers']['transfer-encoding'] == 'chunked')
2495
+					if (isset($GLOBALS['_xh']['headers']['transfer-encoding']) && $GLOBALS['_xh']['headers']['transfer-encoding'] == 'chunked')
2496 2496
 					{
2497
-						if(!$data = decode_chunked($data))
2497
+						if (!$data = decode_chunked($data))
2498 2498
 						{
2499 2499
 							error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to rebuild the chunked data received from server');
2500 2500
 							$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['dechunk_fail'], $GLOBALS['xmlrpcstr']['dechunk_fail']);
@@ -2504,25 +2504,25 @@  discard block
 block discarded – undo
2504 2504
 
2505 2505
 					// Decode gzip-compressed stuff
2506 2506
 					// code shamelessly inspired from nusoap library by Dietrich Ayala
2507
-					if(isset($GLOBALS['_xh']['headers']['content-encoding']))
2507
+					if (isset($GLOBALS['_xh']['headers']['content-encoding']))
2508 2508
 					{
2509 2509
 						$GLOBALS['_xh']['headers']['content-encoding'] = str_replace('x-', '', $GLOBALS['_xh']['headers']['content-encoding']);
2510
-						if($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' || $GLOBALS['_xh']['headers']['content-encoding'] == 'gzip')
2510
+						if ($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' || $GLOBALS['_xh']['headers']['content-encoding'] == 'gzip')
2511 2511
 						{
2512 2512
 							// if decoding works, use it. else assume data wasn't gzencoded
2513
-							if(function_exists('gzinflate'))
2513
+							if (function_exists('gzinflate'))
2514 2514
 							{
2515
-								if($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data))
2515
+								if ($GLOBALS['_xh']['headers']['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data))
2516 2516
 								{
2517 2517
 									$data = $degzdata;
2518
-									if($this->debug)
2519
-									print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n" . htmlentities($data) . "\n---END---</PRE>";
2518
+									if ($this->debug)
2519
+									print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n".htmlentities($data)."\n---END---</PRE>";
2520 2520
 								}
2521
-								elseif($GLOBALS['_xh']['headers']['content-encoding'] == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
2521
+								elseif ($GLOBALS['_xh']['headers']['content-encoding'] == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
2522 2522
 								{
2523 2523
 									$data = $degzdata;
2524
-									if($this->debug)
2525
-									print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n" . htmlentities($data) . "\n---END---</PRE>";
2524
+									if ($this->debug)
2525
+									print "<PRE>---INFLATED RESPONSE---[".strlen($data)." chars]---\n".htmlentities($data)."\n---END---</PRE>";
2526 2526
 								}
2527 2527
 								else
2528 2528
 								{
@@ -2543,7 +2543,7 @@  discard block
 block discarded – undo
2543 2543
 
2544 2544
 				// real stupid hack to avoid PHP complaining about returning NULL by ref
2545 2545
 				$r = null;
2546
-				$r =& $r;
2546
+				$r = & $r;
2547 2547
 				return $r;
2548 2548
 		}
2549 2549
 
@@ -2555,28 +2555,28 @@  discard block
 block discarded – undo
2555 2555
 		* @return xmlrpcresp
2556 2556
 		* @access public
2557 2557
 		*/
2558
-		function &parseResponse($data='', $headers_processed=false, $return_type='xmlrpcvals')
2558
+		function &parseResponse($data = '', $headers_processed = false, $return_type = 'xmlrpcvals')
2559 2559
 		{
2560
-			if($this->debug)
2560
+			if ($this->debug)
2561 2561
 			{
2562 2562
 				//by maHo, replaced htmlspecialchars with htmlentities
2563
-				print "<PRE>---GOT---\n" . htmlentities($data) . "\n---END---\n</PRE>";
2563
+				print "<PRE>---GOT---\n".htmlentities($data)."\n---END---\n</PRE>";
2564 2564
 			}
2565 2565
 
2566
-			if($data == '')
2566
+			if ($data == '')
2567 2567
 			{
2568 2568
 				error_log('XML-RPC: '.__METHOD__.': no response received from server.');
2569 2569
 				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_data'], $GLOBALS['xmlrpcstr']['no_data']);
2570 2570
 				return $r;
2571 2571
 			}
2572 2572
 
2573
-			$GLOBALS['_xh']=array();
2573
+			$GLOBALS['_xh'] = array();
2574 2574
 
2575 2575
 			$raw_data = $data;
2576 2576
 			// parse the HTTP headers of the response, if present, and separate them from data
2577
-			if(substr($data, 0, 4) == 'HTTP')
2577
+			if (substr($data, 0, 4) == 'HTTP')
2578 2578
 			{
2579
-				$r =& $this->parseResponseHeaders($data, $headers_processed);
2579
+				$r = & $this->parseResponseHeaders($data, $headers_processed);
2580 2580
 				if ($r)
2581 2581
 				{
2582 2582
 					// failed processing of HTTP response headers
@@ -2591,7 +2591,7 @@  discard block
 block discarded – undo
2591 2591
 				$GLOBALS['_xh']['cookies'] = array();
2592 2592
 			}
2593 2593
 
2594
-			if($this->debug)
2594
+			if ($this->debug)
2595 2595
 			{
2596 2596
 				$start = strpos($data, '<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
2597 2597
 				if ($start)
@@ -2611,7 +2611,7 @@  discard block
 block discarded – undo
2611 2611
 			// be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts)
2612 2612
 			// idea from Luca Mariano <[email protected]> originally in PEARified version of the lib
2613 2613
 			$pos = strrpos($data, '</methodResponse>');
2614
-			if($pos !== false)
2614
+			if ($pos !== false)
2615 2615
 			{
2616 2616
 				$data = substr($data, 0, $pos+17);
2617 2617
 			}
@@ -2629,13 +2629,13 @@  discard block
 block discarded – undo
2629 2629
 			// try to 'guestimate' the character encoding of the received response
2630 2630
 			$resp_encoding = guess_encoding(@$GLOBALS['_xh']['headers']['content-type'], $data);
2631 2631
 
2632
-			$GLOBALS['_xh']['ac']='';
2632
+			$GLOBALS['_xh']['ac'] = '';
2633 2633
 			//$GLOBALS['_xh']['qt']=''; //unused...
2634 2634
 			$GLOBALS['_xh']['stack'] = array();
2635 2635
 			$GLOBALS['_xh']['valuestack'] = array();
2636
-			$GLOBALS['_xh']['isf']=0; // 0 = OK, 1 for xmlrpc fault responses, 2 = invalid xmlrpc
2637
-			$GLOBALS['_xh']['isf_reason']='';
2638
-			$GLOBALS['_xh']['rt']=''; // 'methodcall or 'methodresponse'
2636
+			$GLOBALS['_xh']['isf'] = 0; // 0 = OK, 1 for xmlrpc fault responses, 2 = invalid xmlrpc
2637
+			$GLOBALS['_xh']['isf_reason'] = '';
2638
+			$GLOBALS['_xh']['rt'] = ''; // 'methodcall or 'methodresponse'
2639 2639
 
2640 2640
 			// Since parsing will fail if charset is not specified in the xml prologue,
2641 2641
 			// the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
@@ -2649,7 +2649,7 @@  discard block
 block discarded – undo
2649 2649
 					if (extension_loaded('mbstring')) {
2650 2650
 						$data = mb_convert_encoding($data, 'UTF-8', $resp_encoding);
2651 2651
 					} else {
2652
-						error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $resp_encoding);
2652
+						error_log('XML-RPC: '.__METHOD__.': invalid charset encoding of received request: '.$resp_encoding);
2653 2653
 					}
2654 2654
 				}
2655 2655
 			}
@@ -2684,10 +2684,10 @@  discard block
 block discarded – undo
2684 2684
 			xml_set_default_handler($parser, 'xmlrpc_dh');
2685 2685
 
2686 2686
 			// first error check: xml not well formed
2687
-			if(!xml_parse($parser, $data, 1))
2687
+			if (!xml_parse($parser, $data, 1))
2688 2688
 			{
2689 2689
 				// thanks to Peter Kocks <[email protected]>
2690
-				if((xml_get_current_line_number($parser)) == 1)
2690
+				if ((xml_get_current_line_number($parser)) == 1)
2691 2691
 				{
2692 2692
 					$errstr = 'XML error at line 1, check URL';
2693 2693
 				}
@@ -2698,9 +2698,9 @@  discard block
 block discarded – undo
2698 2698
 						xml_get_current_line_number($parser), xml_get_current_column_number($parser));
2699 2699
 				}
2700 2700
 				error_log($errstr);
2701
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcstr']['invalid_return'].' ('.$errstr.')');
2701
+				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcstr']['invalid_return'].' ('.$errstr.')');
2702 2702
 				xml_parser_free($parser);
2703
-				if($this->debug)
2703
+				if ($this->debug)
2704 2704
 				{
2705 2705
 					print $errstr;
2706 2706
 				}
@@ -2711,7 +2711,7 @@  discard block
 block discarded – undo
2711 2711
 			}
2712 2712
 			xml_parser_free($parser);
2713 2713
 			// second error check: xml well formed but not xml-rpc compliant
2714
-			if ($GLOBALS['_xh']['isf'] > 1)
2714
+			if ($GLOBALS['_xh']['isf']>1)
2715 2715
 			{
2716 2716
 				if ($this->debug)
2717 2717
 				{
@@ -2719,7 +2719,7 @@  discard block
 block discarded – undo
2719 2719
 				}
2720 2720
 
2721 2721
 				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2722
-				$GLOBALS['xmlrpcstr']['invalid_return'] . ' ' . $GLOBALS['_xh']['isf_reason']);
2722
+				$GLOBALS['xmlrpcstr']['invalid_return'].' '.$GLOBALS['_xh']['isf_reason']);
2723 2723
 			}
2724 2724
 			// third error check: parsing of the response has somehow gone boink.
2725 2725
 			// NB: shall we omit this check, since we trust the parsing code?
@@ -2728,7 +2728,7 @@  discard block
 block discarded – undo
2728 2728
 				// something odd has happened
2729 2729
 				// and it's time to generate a client side error
2730 2730
 				// indicating something odd went on
2731
-				$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2731
+				$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'],
2732 2732
 					$GLOBALS['xmlrpcstr']['invalid_return']);
2733 2733
 			}
2734 2734
 			else
@@ -2743,9 +2743,9 @@  discard block
 block discarded – undo
2743 2743
 				}
2744 2744
 
2745 2745
 				// note that using =& will raise an error if $GLOBALS['_xh']['st'] does not generate an object.
2746
-				$v =& $GLOBALS['_xh']['value'];
2746
+				$v = & $GLOBALS['_xh']['value'];
2747 2747
 
2748
-				if($GLOBALS['_xh']['isf'])
2748
+				if ($GLOBALS['_xh']['isf'])
2749 2749
 				{
2750 2750
 					/// @todo we should test here if server sent an int and a string,
2751 2751
 					/// and/or coerce them into such...
@@ -2762,7 +2762,7 @@  discard block
 block discarded – undo
2762 2762
 						$errstr = $v['faultString'];
2763 2763
 					}
2764 2764
 
2765
-					if($errno == 0)
2765
+					if ($errno == 0)
2766 2766
 					{
2767 2767
 						// FAULT returned, errno needs to reflect that
2768 2768
 						$errno = -1;
@@ -2772,7 +2772,7 @@  discard block
 block discarded – undo
2772 2772
 				}
2773 2773
 				else
2774 2774
 				{
2775
-					$r=new xmlrpcresp($v, 0, '', $return_type);
2775
+					$r = new xmlrpcresp($v, 0, '', $return_type);
2776 2776
 				}
2777 2777
 			}
2778 2778
 
@@ -2785,26 +2785,26 @@  discard block
 block discarded – undo
2785 2785
 
2786 2786
 	class xmlrpcval
2787 2787
 	{
2788
-		var $me=array();
2789
-		var $mytype=0;
2790
-		var $_php_class=null;
2788
+		var $me = array();
2789
+		var $mytype = 0;
2790
+		var $_php_class = null;
2791 2791
 
2792 2792
 		/**
2793 2793
 		* @param mixed $val
2794 2794
 		* @param string $type any valid xmlrpc type name (lowercase). If null, 'string' is assumed
2795 2795
 		*/
2796
-		function __construct($val=-1, $type='')
2796
+		function __construct($val = -1, $type = '')
2797 2797
 		{
2798 2798
 			/// @todo: optimization creep - do not call addXX, do it all inline.
2799 2799
 			/// downside: booleans will not be coerced anymore
2800
-			if($val!==-1 || $type!='')
2800
+			if ($val !== -1 || $type != '')
2801 2801
 			{
2802 2802
 				// optimization creep: inlined all work done by constructor
2803
-				switch($type)
2803
+				switch ($type)
2804 2804
 				{
2805 2805
 					case '':
2806
-						$this->mytype=1;
2807
-						$this->me['string']=$val;
2806
+						$this->mytype = 1;
2807
+						$this->me['string'] = $val;
2808 2808
 						break;
2809 2809
 					case 'i4':
2810 2810
 					case 'int':
@@ -2814,16 +2814,16 @@  discard block
 block discarded – undo
2814 2814
 					case 'dateTime.iso8601':
2815 2815
 					case 'base64':
2816 2816
 					case 'null':
2817
-						$this->mytype=1;
2818
-						$this->me[$type]=$val;
2817
+						$this->mytype = 1;
2818
+						$this->me[$type] = $val;
2819 2819
 						break;
2820 2820
 					case 'array':
2821
-						$this->mytype=2;
2822
-						$this->me['array']=$val;
2821
+						$this->mytype = 2;
2822
+						$this->me['array'] = $val;
2823 2823
 						break;
2824 2824
 					case 'struct':
2825
-						$this->mytype=3;
2826
-						$this->me['struct']=$val;
2825
+						$this->mytype = 3;
2826
+						$this->me['struct'] = $val;
2827 2827
 						break;
2828 2828
 					default:
2829 2829
 						error_log("XML-RPC: ".__METHOD__.": not a known type ($type)");
@@ -2850,7 +2850,7 @@  discard block
 block discarded – undo
2850 2850
 		/**
2851 2851
 		* @deprecated
2852 2852
 		*/
2853
-		function xmlrpcval($val=-1, $type='')
2853
+		function xmlrpcval($val = -1, $type = '')
2854 2854
 		{
2855 2855
 			self::__construct($val, $type);
2856 2856
 		}
@@ -2861,10 +2861,10 @@  discard block
 block discarded – undo
2861 2861
 		* @param string $type
2862 2862
 		* @return int 1 or 0 on failure
2863 2863
 		*/
2864
-		function addScalar($val, $type='string')
2864
+		function addScalar($val, $type = 'string')
2865 2865
 		{
2866
-			$typeof=@$GLOBALS['xmlrpcTypes'][$type];
2867
-			if($typeof!=1)
2866
+			$typeof = @$GLOBALS['xmlrpcTypes'][$type];
2867
+			if ($typeof != 1)
2868 2868
 			{
2869 2869
 				error_log("XML-RPC: ".__METHOD__.": not a scalar type ($type)");
2870 2870
 				return 0;
@@ -2873,19 +2873,19 @@  discard block
 block discarded – undo
2873 2873
 			// coerce booleans into correct values
2874 2874
 			// NB: we should either do it for datetimes, integers and doubles, too,
2875 2875
 			// or just plain remove this check, implemented on booleans only...
2876
-			if($type==$GLOBALS['xmlrpcBoolean'])
2876
+			if ($type == $GLOBALS['xmlrpcBoolean'])
2877 2877
 			{
2878
-				if(strcasecmp($val,'true')==0 || $val==1 || ($val==true && strcasecmp($val,'false')))
2878
+				if (strcasecmp($val, 'true') == 0 || $val == 1 || ($val == true && strcasecmp($val, 'false')))
2879 2879
 				{
2880
-					$val=true;
2880
+					$val = true;
2881 2881
 				}
2882 2882
 				else
2883 2883
 				{
2884
-					$val=false;
2884
+					$val = false;
2885 2885
 				}
2886 2886
 			}
2887 2887
 
2888
-			switch($this->mytype)
2888
+			switch ($this->mytype)
2889 2889
 			{
2890 2890
 				case 1:
2891 2891
 					error_log('XML-RPC: '.__METHOD__.': scalar xmlrpcval can have only one value');
@@ -2899,12 +2899,12 @@  discard block
 block discarded – undo
2899 2899
 					//$ar[]=new xmlrpcval($val, $type);
2900 2900
 					//$this->me['array']=$ar;
2901 2901
 					// Faster (?) avoid all the costly array-copy-by-val done here...
2902
-					$this->me['array'][]=new xmlrpcval($val, $type);
2902
+					$this->me['array'][] = new xmlrpcval($val, $type);
2903 2903
 					return 1;
2904 2904
 				default:
2905 2905
 					// a scalar, so set the value and remember we're scalar
2906
-					$this->me[$type]=$val;
2907
-					$this->mytype=$typeof;
2906
+					$this->me[$type] = $val;
2907
+					$this->mytype = $typeof;
2908 2908
 					return 1;
2909 2909
 			}
2910 2910
 		}
@@ -2919,13 +2919,13 @@  discard block
 block discarded – undo
2919 2919
 		*/
2920 2920
 		function addArray($vals)
2921 2921
 		{
2922
-			if($this->mytype==0)
2922
+			if ($this->mytype == 0)
2923 2923
 			{
2924
-				$this->mytype=$GLOBALS['xmlrpcTypes']['array'];
2925
-				$this->me['array']=$vals;
2924
+				$this->mytype = $GLOBALS['xmlrpcTypes']['array'];
2925
+				$this->me['array'] = $vals;
2926 2926
 				return 1;
2927 2927
 			}
2928
-			elseif($this->mytype==2)
2928
+			elseif ($this->mytype == 2)
2929 2929
 			{
2930 2930
 				// we're adding to an array here
2931 2931
 				$this->me['array'] = array_merge($this->me['array'], $vals);
@@ -2933,7 +2933,7 @@  discard block
 block discarded – undo
2933 2933
 			}
2934 2934
 			else
2935 2935
 			{
2936
-				error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');
2936
+				error_log('XML-RPC: '.__METHOD__.': already initialized as a ['.$this->kindOf().']');
2937 2937
 				return 0;
2938 2938
 			}
2939 2939
 		}
@@ -2948,13 +2948,13 @@  discard block
 block discarded – undo
2948 2948
 		*/
2949 2949
 		function addStruct($vals)
2950 2950
 		{
2951
-			if($this->mytype==0)
2951
+			if ($this->mytype == 0)
2952 2952
 			{
2953
-				$this->mytype=$GLOBALS['xmlrpcTypes']['struct'];
2954
-				$this->me['struct']=$vals;
2953
+				$this->mytype = $GLOBALS['xmlrpcTypes']['struct'];
2954
+				$this->me['struct'] = $vals;
2955 2955
 				return 1;
2956 2956
 			}
2957
-			elseif($this->mytype==3)
2957
+			elseif ($this->mytype == 3)
2958 2958
 			{
2959 2959
 				// we're adding to a struct here
2960 2960
 				$this->me['struct'] = array_merge($this->me['struct'], $vals);
@@ -2962,7 +2962,7 @@  discard block
 block discarded – undo
2962 2962
 			}
2963 2963
 			else
2964 2964
 			{
2965
-				error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');
2965
+				error_log('XML-RPC: '.__METHOD__.': already initialized as a ['.$this->kindOf().']');
2966 2966
 				return 0;
2967 2967
 			}
2968 2968
 		}
@@ -2971,12 +2971,12 @@  discard block
 block discarded – undo
2971 2971
 		// DEPRECATED!
2972 2972
 		function dump($ar)
2973 2973
 		{
2974
-			foreach($ar as $key => $val)
2974
+			foreach ($ar as $key => $val)
2975 2975
 			{
2976 2976
 				echo "$key => $val<br />";
2977
-				if($key == 'array')
2977
+				if ($key == 'array')
2978 2978
 				{
2979
-					while(list($key2, $val2) = each($val))
2979
+					while (list($key2, $val2) = each($val))
2980 2980
 					{
2981 2981
 						echo "-- $key2 => $val2<br />";
2982 2982
 					}
@@ -2991,7 +2991,7 @@  discard block
 block discarded – undo
2991 2991
 		*/
2992 2992
 		function kindOf()
2993 2993
 		{
2994
-			switch($this->mytype)
2994
+			switch ($this->mytype)
2995 2995
 			{
2996 2996
 				case 3:
2997 2997
 					return 'struct';
@@ -3010,28 +3010,28 @@  discard block
 block discarded – undo
3010 3010
 		/**
3011 3011
 		* @access private
3012 3012
 		*/
3013
-		function serializedata($typ, $val, $charset_encoding='')
3013
+		function serializedata($typ, $val, $charset_encoding = '')
3014 3014
 		{
3015
-			$rs='';
3016
-			switch(@$GLOBALS['xmlrpcTypes'][$typ])
3015
+			$rs = '';
3016
+			switch (@$GLOBALS['xmlrpcTypes'][$typ])
3017 3017
 			{
3018 3018
 				case 1:
3019
-					switch($typ)
3019
+					switch ($typ)
3020 3020
 					{
3021 3021
 						case $GLOBALS['xmlrpcBase64']:
3022
-							$rs.="<${typ}>" . base64_encode($val) . "</${typ}>";
3022
+							$rs .= "<${typ}>".base64_encode($val)."</${typ}>";
3023 3023
 							break;
3024 3024
 						case $GLOBALS['xmlrpcBoolean']:
3025
-							$rs.="<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
3025
+							$rs .= "<${typ}>".($val ? '1' : '0')."</${typ}>";
3026 3026
 							break;
3027 3027
 						case $GLOBALS['xmlrpcString']:
3028 3028
 							// G. Giunta 2005/2/13: do NOT use htmlentities, since
3029 3029
 							// it will produce named html entities, which are invalid xml
3030
-							$rs.="<${typ}>" . xmlrpc_encode_entitites($val, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding). "</${typ}>";
3030
+							$rs .= "<${typ}>".xmlrpc_encode_entitites($val, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</${typ}>";
3031 3031
 							break;
3032 3032
 						case $GLOBALS['xmlrpcInt']:
3033 3033
 						case $GLOBALS['xmlrpcI4']:
3034
-							$rs.="<${typ}>".(int)$val."</${typ}>";
3034
+							$rs .= "<${typ}>".(int) $val."</${typ}>";
3035 3035
 							break;
3036 3036
 						case $GLOBALS['xmlrpcDouble']:
3037 3037
 							// avoid using standard conversion of float to string because it is locale-dependent,
@@ -3039,71 +3039,71 @@  discard block
 block discarded – undo
3039 3039
 							// sprintf('%F') could be most likely ok but it fails eg. on 2e-14.
3040 3040
 							// The code below tries its best at keeping max precision while avoiding exp notation,
3041 3041
 							// but there is of course no limit in the number of decimal places to be used...
3042
-							$rs.="<${typ}>".preg_replace('/\\.?0+$/','',number_format((double)$val, 128, '.', ''))."</${typ}>";
3042
+							$rs .= "<${typ}>".preg_replace('/\\.?0+$/', '', number_format((double) $val, 128, '.', ''))."</${typ}>";
3043 3043
 							break;
3044 3044
 						case $GLOBALS['xmlrpcDateTime']:
3045 3045
 							if (is_string($val))
3046 3046
 							{
3047
-								$rs.="<${typ}>${val}</${typ}>";
3047
+								$rs .= "<${typ}>${val}</${typ}>";
3048 3048
 							}
3049
-							else if(is_a($val, 'DateTime'))
3049
+							else if (is_a($val, 'DateTime'))
3050 3050
 							{
3051
-								$rs.="<${typ}>".$val->format('Ymd\TH:i:s')."</${typ}>";
3051
+								$rs .= "<${typ}>".$val->format('Ymd\TH:i:s')."</${typ}>";
3052 3052
 							}
3053
-							else if(is_int($val))
3053
+							else if (is_int($val))
3054 3054
 							{
3055
-								$rs.="<${typ}>".strftime("%Y%m%dT%H:%M:%S", $val)."</${typ}>";
3055
+								$rs .= "<${typ}>".strftime("%Y%m%dT%H:%M:%S", $val)."</${typ}>";
3056 3056
 							}
3057 3057
 							else
3058 3058
 							{
3059 3059
 								// not really a good idea here: but what shall we output anyway? left for backward compat...
3060
-								$rs.="<${typ}>${val}</${typ}>";
3060
+								$rs .= "<${typ}>${val}</${typ}>";
3061 3061
 							}
3062 3062
 							break;
3063 3063
 						case $GLOBALS['xmlrpcNull']:
3064 3064
 							if ($GLOBALS['xmlrpc_null_apache_encoding'])
3065 3065
 							{
3066
-								$rs.="<ex:nil/>";
3066
+								$rs .= "<ex:nil/>";
3067 3067
 							}
3068 3068
 							else
3069 3069
 							{
3070
-								$rs.="<nil/>";
3070
+								$rs .= "<nil/>";
3071 3071
 							}
3072 3072
 							break;
3073 3073
 						default:
3074 3074
 							// no standard type value should arrive here, but provide a possibility
3075 3075
 							// for xmlrpcvals of unknown type...
3076
-							$rs.="<${typ}>${val}</${typ}>";
3076
+							$rs .= "<${typ}>${val}</${typ}>";
3077 3077
 					}
3078 3078
 					break;
3079 3079
 				case 3:
3080 3080
 					// struct
3081 3081
 					if ($this->_php_class)
3082 3082
 					{
3083
-						$rs.='<struct php_class="' . $this->_php_class . "\">\n";
3083
+						$rs .= '<struct php_class="'.$this->_php_class."\">\n";
3084 3084
 					}
3085 3085
 					else
3086 3086
 					{
3087
-						$rs.="<struct>\n";
3087
+						$rs .= "<struct>\n";
3088 3088
 					}
3089
-					foreach($val as $key2 => $val2)
3089
+					foreach ($val as $key2 => $val2)
3090 3090
 					{
3091
-						$rs.='<member><name>'.xmlrpc_encode_entitites($key2, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</name>\n";
3091
+						$rs .= '<member><name>'.xmlrpc_encode_entitites($key2, $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."</name>\n";
3092 3092
 						//$rs.=$this->serializeval($val2);
3093
-						$rs.=$val2->serialize($charset_encoding);
3094
-						$rs.="</member>\n";
3093
+						$rs .= $val2->serialize($charset_encoding);
3094
+						$rs .= "</member>\n";
3095 3095
 					}
3096
-					$rs.='</struct>';
3096
+					$rs .= '</struct>';
3097 3097
 					break;
3098 3098
 				case 2:
3099 3099
 					// array
3100
-					$rs.="<array>\n<data>\n";
3101
-					for($i=0; $i<count($val); $i++)
3100
+					$rs .= "<array>\n<data>\n";
3101
+					for ($i = 0; $i<count($val); $i++)
3102 3102
 					{
3103 3103
 						//$rs.=$this->serializeval($val[$i]);
3104
-						$rs.=$val[$i]->serialize($charset_encoding);
3104
+						$rs .= $val[$i]->serialize($charset_encoding);
3105 3105
 					}
3106
-					$rs.="</data>\n</array>";
3106
+					$rs .= "</data>\n</array>";
3107 3107
 					break;
3108 3108
 				default:
3109 3109
 					break;
@@ -3117,14 +3117,14 @@  discard block
 block discarded – undo
3117 3117
 		* @return string
3118 3118
 		* @access public
3119 3119
 		*/
3120
-		function serialize($charset_encoding='')
3120
+		function serialize($charset_encoding = '')
3121 3121
 		{
3122 3122
 			// add check? slower, but helps to avoid recursion in serializing broken xmlrpcvals...
3123 3123
 			//if (is_object($o) && (get_class($o) == 'xmlrpcval' || is_subclass_of($o, 'xmlrpcval')))
3124 3124
 			//{
3125 3125
 				$val = reset($this->me);
3126 3126
 				$typ = key($this->me);
3127
-				return '<value>' . $this->serializedata($typ, $val, $charset_encoding) . "</value>\n";
3127
+				return '<value>'.$this->serializedata($typ, $val, $charset_encoding)."</value>\n";
3128 3128
 			//}
3129 3129
 		}
3130 3130
 
@@ -3136,7 +3136,7 @@  discard block
 block discarded – undo
3136 3136
 			//{
3137 3137
 				$val = reset($o->me);
3138 3138
 				$typ = key($o->me);
3139
-				return '<value>' . $this->serializedata($typ, $val) . "</value>\n";
3139
+				return '<value>'.$this->serializedata($typ, $val)."</value>\n";
3140 3140
 			//}
3141 3141
 		}
3142 3142
 
@@ -3189,32 +3189,32 @@  discard block
 block discarded – undo
3189 3189
 		{
3190 3190
 			// UNSTABLE
3191 3191
 			reset($this->me);
3192
-			list($a,$b)=each($this->me);
3192
+			list($a, $b) = each($this->me);
3193 3193
 			// contributed by I Sofer, 2001-03-24
3194 3194
 			// add support for nested arrays to scalarval
3195 3195
 			// i've created a new method here, so as to
3196 3196
 			// preserve back compatibility
3197 3197
 
3198
-			if(is_array($b))
3198
+			if (is_array($b))
3199 3199
 			{
3200 3200
 				@reset($b);
3201
-				while(list($id,$cont) = @each($b))
3201
+				while (list($id, $cont) = @each($b))
3202 3202
 				{
3203 3203
 					$b[$id] = $cont->scalarval();
3204 3204
 				}
3205 3205
 			}
3206 3206
 
3207 3207
 			// add support for structures directly encoding php objects
3208
-			if(is_object($b))
3208
+			if (is_object($b))
3209 3209
 			{
3210 3210
 				$t = get_object_vars($b);
3211 3211
 				@reset($t);
3212
-				while(list($id,$cont) = @each($t))
3212
+				while (list($id, $cont) = @each($t))
3213 3213
 				{
3214 3214
 					$t[$id] = $cont->scalarval();
3215 3215
 				}
3216 3216
 				@reset($t);
3217
-				while(list($id,$cont) = @each($t))
3217
+				while (list($id, $cont) = @each($t))
3218 3218
 				{
3219 3219
 					@$b->$id = $cont;
3220 3220
 				}
@@ -3231,7 +3231,7 @@  discard block
 block discarded – undo
3231 3231
 		function scalarval()
3232 3232
 		{
3233 3233
 			reset($this->me);
3234
-			list(,$b)=each($this->me);
3234
+			list(,$b) = each($this->me);
3235 3235
 			return $b;
3236 3236
 		}
3237 3237
 
@@ -3244,10 +3244,10 @@  discard block
 block discarded – undo
3244 3244
 		function scalartyp()
3245 3245
 		{
3246 3246
 			reset($this->me);
3247
-			list($a,)=each($this->me);
3248
-			if($a==$GLOBALS['xmlrpcI4'])
3247
+			list($a,) = each($this->me);
3248
+			if ($a == $GLOBALS['xmlrpcI4'])
3249 3249
 			{
3250
-				$a=$GLOBALS['xmlrpcInt'];
3250
+				$a = $GLOBALS['xmlrpcInt'];
3251 3251
 			}
3252 3252
 			return $a;
3253 3253
 		}
@@ -3304,23 +3304,23 @@  discard block
 block discarded – undo
3304 3304
 	* @param int $utc (0 or 1)
3305 3305
 	* @return string
3306 3306
 	*/
3307
-	function iso8601_encode($timet, $utc=0)
3307
+	function iso8601_encode($timet, $utc = 0)
3308 3308
 	{
3309
-		if(!$utc)
3309
+		if (!$utc)
3310 3310
 		{
3311
-			$t=strftime("%Y%m%dT%H:%M:%S", $timet);
3311
+			$t = strftime("%Y%m%dT%H:%M:%S", $timet);
3312 3312
 		}
3313 3313
 		else
3314 3314
 		{
3315
-			if(function_exists('gmstrftime'))
3315
+			if (function_exists('gmstrftime'))
3316 3316
 			{
3317 3317
 				// gmstrftime doesn't exist in some versions
3318 3318
 				// of PHP
3319
-				$t=gmstrftime("%Y%m%dT%H:%M:%S", $timet);
3319
+				$t = gmstrftime("%Y%m%dT%H:%M:%S", $timet);
3320 3320
 			}
3321 3321
 			else
3322 3322
 			{
3323
-				$t=strftime("%Y%m%dT%H:%M:%S", $timet-date('Z'));
3323
+				$t = strftime("%Y%m%dT%H:%M:%S", $timet-date('Z'));
3324 3324
 			}
3325 3325
 		}
3326 3326
 		return $t;
@@ -3332,18 +3332,18 @@  discard block
 block discarded – undo
3332 3332
 	* @param int $utc either 0 or 1
3333 3333
 	* @return int (datetime)
3334 3334
 	*/
3335
-	function iso8601_decode($idate, $utc=0)
3335
+	function iso8601_decode($idate, $utc = 0)
3336 3336
 	{
3337
-		$t=0;
3338
-		if(preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $idate, $regs))
3337
+		$t = 0;
3338
+		if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $idate, $regs))
3339 3339
 		{
3340
-			if($utc)
3340
+			if ($utc)
3341 3341
 			{
3342
-				$t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3342
+				$t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3343 3343
 			}
3344 3344
 			else
3345 3345
 			{
3346
-				$t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3346
+				$t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
3347 3347
 			}
3348 3348
 		}
3349 3349
 		return $t;
@@ -3370,15 +3370,15 @@  discard block
 block discarded – undo
3370 3370
 	* @param array $options if 'decode_php_objs' is set in the options array, xmlrpc structs can be decoded into php objects; if 'dates_as_objects' is set xmlrpc datetimes are decoded as php DateTime objects (standard is
3371 3371
 	* @return mixed
3372 3372
 	*/
3373
-	function php_xmlrpc_decode($xmlrpc_val, $options=array())
3373
+	function php_xmlrpc_decode($xmlrpc_val, $options = array())
3374 3374
 	{
3375
-		switch($xmlrpc_val->kindOf())
3375
+		switch ($xmlrpc_val->kindOf())
3376 3376
 		{
3377 3377
 			case 'scalar':
3378 3378
 				if (in_array('extension_api', $options))
3379 3379
 				{
3380 3380
 					reset($xmlrpc_val->me);
3381
-					list($typ,$val) = each($xmlrpc_val->me);
3381
+					list($typ, $val) = each($xmlrpc_val->me);
3382 3382
 					switch ($typ)
3383 3383
 					{
3384 3384
 						case 'dateTime.iso8601':
@@ -3419,7 +3419,7 @@  discard block
 block discarded – undo
3419 3419
 			case 'array':
3420 3420
 				$size = $xmlrpc_val->arraysize();
3421 3421
 				$arr = array();
3422
-				for($i = 0; $i < $size; $i++)
3422
+				for ($i = 0; $i<$size; $i++)
3423 3423
 				{
3424 3424
 					$arr[] = php_xmlrpc_decode($xmlrpc_val->arraymem($i), $options);
3425 3425
 				}
@@ -3434,7 +3434,7 @@  discard block
 block discarded – undo
3434 3434
 					&& class_exists($xmlrpc_val->_php_class))
3435 3435
 				{
3436 3436
 					$obj = @new $xmlrpc_val->_php_class;
3437
-					while(list($key,$value)=$xmlrpc_val->structeach())
3437
+					while (list($key, $value) = $xmlrpc_val->structeach())
3438 3438
 					{
3439 3439
 						$obj->$key = php_xmlrpc_decode($value, $options);
3440 3440
 					}
@@ -3443,7 +3443,7 @@  discard block
 block discarded – undo
3443 3443
 				else
3444 3444
 				{
3445 3445
 					$arr = array();
3446
-					while(list($key,$value)=$xmlrpc_val->structeach())
3446
+					while (list($key, $value) = $xmlrpc_val->structeach())
3447 3447
 					{
3448 3448
 						$arr[$key] = php_xmlrpc_decode($value, $options);
3449 3449
 					}
@@ -3452,7 +3452,7 @@  discard block
 block discarded – undo
3452 3452
 			case 'msg':
3453 3453
 				$paramcount = $xmlrpc_val->getNumParams();
3454 3454
 				$arr = array();
3455
-				for($i = 0; $i < $paramcount; $i++)
3455
+				for ($i = 0; $i<$paramcount; $i++)
3456 3456
 				{
3457 3457
 					$arr[] = php_xmlrpc_decode($xmlrpc_val->getParam($i));
3458 3458
 				}
@@ -3463,13 +3463,13 @@  discard block
 block discarded – undo
3463 3463
 	// This constant left here only for historical reasons...
3464 3464
 	// it was used to decide if we have to define xmlrpc_encode on our own, but
3465 3465
 	// we do not do it anymore
3466
-	if(function_exists('xmlrpc_decode'))
3466
+	if (function_exists('xmlrpc_decode'))
3467 3467
 	{
3468
-		define('XMLRPC_EPI_ENABLED','1');
3468
+		define('XMLRPC_EPI_ENABLED', '1');
3469 3469
 	}
3470 3470
 	else
3471 3471
 	{
3472
-		define('XMLRPC_EPI_ENABLED','0');
3472
+		define('XMLRPC_EPI_ENABLED', '0');
3473 3473
 	}
3474 3474
 
3475 3475
 	/**
@@ -3489,10 +3489,10 @@  discard block
 block discarded – undo
3489 3489
 	* @param array $options	can include 'encode_php_objs', 'auto_dates', 'null_extension' or 'extension_api'
3490 3490
 	* @return xmlrpcval
3491 3491
 	*/
3492
-	function php_xmlrpc_encode($php_val, $options=array())
3492
+	function php_xmlrpc_encode($php_val, $options = array())
3493 3493
 	{
3494 3494
 		$type = gettype($php_val);
3495
-		switch($type)
3495
+		switch ($type)
3496 3496
 		{
3497 3497
 			case 'string':
3498 3498
 				if (in_array('auto_dates', $options) && preg_match('/^[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $php_val))
@@ -3521,16 +3521,16 @@  discard block
 block discarded – undo
3521 3521
 				$j = 0;
3522 3522
 				$arr = array();
3523 3523
 				$ko = false;
3524
-				foreach($php_val as $key => $val)
3524
+				foreach ($php_val as $key => $val)
3525 3525
 				{
3526 3526
 					$arr[$key] = php_xmlrpc_encode($val, $options);
3527
-					if(!$ko && $key !== $j)
3527
+					if (!$ko && $key !== $j)
3528 3528
 					{
3529 3529
 						$ko = true;
3530 3530
 					}
3531 3531
 					$j++;
3532 3532
 				}
3533
-				if($ko)
3533
+				if ($ko)
3534 3534
 				{
3535 3535
 					$xmlrpc_val = new xmlrpcval($arr, $GLOBALS['xmlrpcStruct']);
3536 3536
 				}
@@ -3540,11 +3540,11 @@  discard block
 block discarded – undo
3540 3540
 				}
3541 3541
 				break;
3542 3542
 			case 'object':
3543
-				if(is_a($php_val, 'xmlrpcval'))
3543
+				if (is_a($php_val, 'xmlrpcval'))
3544 3544
 				{
3545 3545
 					$xmlrpc_val = $php_val;
3546 3546
 				}
3547
-				else if(is_a($php_val, 'DateTime'))
3547
+				else if (is_a($php_val, 'DateTime'))
3548 3548
 				{
3549 3549
 					$xmlrpc_val = new xmlrpcval($php_val->format('Ymd\TH:i:s'), $GLOBALS['xmlrpcStruct']);
3550 3550
 				}
@@ -3552,7 +3552,7 @@  discard block
 block discarded – undo
3552 3552
 				{
3553 3553
 					$arr = array();
3554 3554
 					reset($php_val);
3555
-					while(list($k,$v) = each($php_val))
3555
+					while (list($k, $v) = each($php_val))
3556 3556
 					{
3557 3557
 						$arr[$k] = php_xmlrpc_encode($v, $options);
3558 3558
 					}
@@ -3582,7 +3582,7 @@  discard block
 block discarded – undo
3582 3582
 			case 'resource':
3583 3583
 				if (in_array('extension_api', $options))
3584 3584
 				{
3585
-					$xmlrpc_val = new xmlrpcval((int)$php_val, $GLOBALS['xmlrpcInt']);
3585
+					$xmlrpc_val = new xmlrpcval((int) $php_val, $GLOBALS['xmlrpcInt']);
3586 3586
 				}
3587 3587
 				else
3588 3588
 				{
@@ -3606,7 +3606,7 @@  discard block
 block discarded – undo
3606 3606
 	* @param array $options
3607 3607
 	* @return mixed false on error, or an instance of either xmlrpcval, xmlrpcmsg or xmlrpcresp
3608 3608
 	*/
3609
-	function php_xmlrpc_decode_xml($xml_val, $options=array())
3609
+	function php_xmlrpc_decode_xml($xml_val, $options = array())
3610 3610
 	{
3611 3611
 		$GLOBALS['_xh'] = array();
3612 3612
 		$GLOBALS['_xh']['ac'] = '';
@@ -3634,7 +3634,7 @@  discard block
 block discarded – undo
3634 3634
 				if (extension_loaded('mbstring')) {
3635 3635
 					$xml_val = mb_convert_encoding($xml_val, 'UTF-8', $val_encoding);
3636 3636
 				} else {
3637
-					error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $val_encoding);
3637
+					error_log('XML-RPC: '.__METHOD__.': invalid charset encoding of received request: '.$val_encoding);
3638 3638
 				}
3639 3639
 			}
3640 3640
 		}
@@ -3654,7 +3654,7 @@  discard block
 block discarded – undo
3654 3654
 		xml_set_element_handler($parser, 'xmlrpc_se_any', 'xmlrpc_ee');
3655 3655
 		xml_set_character_data_handler($parser, 'xmlrpc_cd');
3656 3656
 		xml_set_default_handler($parser, 'xmlrpc_dh');
3657
-		if(!xml_parse($parser, $xml_val, 1))
3657
+		if (!xml_parse($parser, $xml_val, 1))
3658 3658
 		{
3659 3659
 			$errstr = sprintf('XML error: %s at line %d, column %d',
3660 3660
 						xml_error_string(xml_get_error_code($parser)),
@@ -3664,7 +3664,7 @@  discard block
 block discarded – undo
3664 3664
 			return false;
3665 3665
 		}
3666 3666
 		xml_parser_free($parser);
3667
-		if ($GLOBALS['_xh']['isf'] > 1) // test that $GLOBALS['_xh']['value'] is an obj, too???
3667
+		if ($GLOBALS['_xh']['isf']>1) // test that $GLOBALS['_xh']['value'] is an obj, too???
3668 3668
 		{
3669 3669
 			error_log($GLOBALS['_xh']['isf_reason']);
3670 3670
 			return false;
@@ -3672,7 +3672,7 @@  discard block
 block discarded – undo
3672 3672
 		switch ($GLOBALS['_xh']['rt'])
3673 3673
 		{
3674 3674
 			case 'methodresponse':
3675
-				$v =& $GLOBALS['_xh']['value'];
3675
+				$v = & $GLOBALS['_xh']['value'];
3676 3676
 				if ($GLOBALS['_xh']['isf'] == 1)
3677 3677
 				{
3678 3678
 					$vc = $v->structmem('faultCode');
@@ -3686,7 +3686,7 @@  discard block
 block discarded – undo
3686 3686
 				return $r;
3687 3687
 			case 'methodcall':
3688 3688
 				$m = new xmlrpcmsg($GLOBALS['_xh']['method']);
3689
-				for($i=0; $i < count($GLOBALS['_xh']['params']); $i++)
3689
+				for ($i = 0; $i<count($GLOBALS['_xh']['params']); $i++)
3690 3690
 				{
3691 3691
 					$m->addParam($GLOBALS['_xh']['params'][$i]);
3692 3692
 				}
@@ -3714,18 +3714,18 @@  discard block
 block discarded – undo
3714 3714
 
3715 3715
 		// read chunk-size, chunk-extension (if any) and crlf
3716 3716
 		// get the position of the linebreak
3717
-		$chunkend = strpos($buffer,"\r\n") + 2;
3718
-		$temp = substr($buffer,0,$chunkend);
3719
-		$chunk_size = hexdec( trim($temp) );
3717
+		$chunkend = strpos($buffer, "\r\n")+2;
3718
+		$temp = substr($buffer, 0, $chunkend);
3719
+		$chunk_size = hexdec(trim($temp));
3720 3720
 		$chunkstart = $chunkend;
3721
-		while($chunk_size > 0)
3721
+		while ($chunk_size>0)
3722 3722
 		{
3723
-			$chunkend = strpos($buffer, "\r\n", $chunkstart + $chunk_size);
3723
+			$chunkend = strpos($buffer, "\r\n", $chunkstart+$chunk_size);
3724 3724
 
3725 3725
 			// just in case we got a broken connection
3726
-			if($chunkend == false)
3726
+			if ($chunkend == false)
3727 3727
 			{
3728
-				$chunk = substr($buffer,$chunkstart);
3728
+				$chunk = substr($buffer, $chunkstart);
3729 3729
 				// append chunk-data to entity-body
3730 3730
 				$new .= $chunk;
3731 3731
 				$length += strlen($chunk);
@@ -3733,21 +3733,21 @@  discard block
 block discarded – undo
3733 3733
 			}
3734 3734
 
3735 3735
 			// read chunk-data and crlf
3736
-			$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
3736
+			$chunk = substr($buffer, $chunkstart, $chunkend-$chunkstart);
3737 3737
 			// append chunk-data to entity-body
3738 3738
 			$new .= $chunk;
3739 3739
 			// length := length + chunk-size
3740 3740
 			$length += strlen($chunk);
3741 3741
 			// read chunk-size and crlf
3742
-			$chunkstart = $chunkend + 2;
3742
+			$chunkstart = $chunkend+2;
3743 3743
 
3744
-			$chunkend = strpos($buffer,"\r\n",$chunkstart)+2;
3745
-			if($chunkend == false)
3744
+			$chunkend = strpos($buffer, "\r\n", $chunkstart)+2;
3745
+			if ($chunkend == false)
3746 3746
 			{
3747 3747
 				break; //just in case we got a broken connection
3748 3748
 			}
3749
-			$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
3750
-			$chunk_size = hexdec( trim($temp) );
3749
+			$temp = substr($buffer, $chunkstart, $chunkend-$chunkstart);
3750
+			$chunk_size = hexdec(trim($temp));
3751 3751
 			$chunkstart = $chunkend;
3752 3752
 		}
3753 3753
 		return $new;
@@ -3767,7 +3767,7 @@  discard block
 block discarded – undo
3767 3767
 	*
3768 3768
 	* @todo explore usage of mb_http_input(): does it detect http headers + post data? if so, use it instead of hand-detection!!!
3769 3769
 	*/
3770
-	function guess_encoding($httpheader='', $xmlchunk='', $encoding_prefs=null)
3770
+	function guess_encoding($httpheader = '', $xmlchunk = '', $encoding_prefs = null)
3771 3771
 	{
3772 3772
 		// discussion: see http://www.yale.edu/pclt/encoding/
3773 3773
 		// 1 - test if encoding is specified in HTTP HEADERS
@@ -3785,7 +3785,7 @@  discard block
 block discarded – undo
3785 3785
 
3786 3786
 		/// @todo this test will pass if ANY header has charset specification, not only Content-Type. Fix it?
3787 3787
 		$matches = array();
3788
-		if(preg_match('/;\s*charset\s*=([^;]+)/i', $httpheader, $matches))
3788
+		if (preg_match('/;\s*charset\s*=([^;]+)/i', $httpheader, $matches))
3789 3789
 		{
3790 3790
 			return strtoupper(trim($matches[1], " \t\""));
3791 3791
 		}
@@ -3797,15 +3797,15 @@  discard block
 block discarded – undo
3797 3797
 		//     in the xml declaration, and verify if they match.
3798 3798
 		/// @todo implement check as described above?
3799 3799
 		/// @todo implement check for first bytes of string even without a BOM? (It sure looks harder than for cases WITH a BOM)
3800
-		if(preg_match('/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x00\x00\xFF\xFE|\xFE\xFF\x00\x00)/', $xmlchunk))
3800
+		if (preg_match('/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x00\x00\xFF\xFE|\xFE\xFF\x00\x00)/', $xmlchunk))
3801 3801
 		{
3802 3802
 			return 'UCS-4';
3803 3803
 		}
3804
-		elseif(preg_match('/^(\xFE\xFF|\xFF\xFE)/', $xmlchunk))
3804
+		elseif (preg_match('/^(\xFE\xFF|\xFF\xFE)/', $xmlchunk))
3805 3805
 		{
3806 3806
 			return 'UTF-16';
3807 3807
 		}
3808
-		elseif(preg_match('/^(\xEF\xBB\xBF)/', $xmlchunk))
3808
+		elseif (preg_match('/^(\xEF\xBB\xBF)/', $xmlchunk))
3809 3809
 		{
3810 3810
 			return 'UTF-8';
3811 3811
 		}
@@ -3814,8 +3814,8 @@  discard block
 block discarded – undo
3814 3814
 		// Details:
3815 3815
 		// SPACE:         (#x20 | #x9 | #xD | #xA)+ === [ \x9\xD\xA]+
3816 3816
 		// EQ:            SPACE?=SPACE? === [ \x9\xD\xA]*=[ \x9\xD\xA]*
3817
-		if (preg_match('/^<\?xml\s+version\s*=\s*'. "((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))".
3818
-			'\s+encoding\s*=\s*' . "((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3817
+		if (preg_match('/^<\?xml\s+version\s*=\s*'."((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))".
3818
+			'\s+encoding\s*=\s*'."((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3819 3819
 			$xmlchunk, $matches))
3820 3820
 		{
3821 3821
 			return strtoupper(substr($matches[2], 1, -1));
@@ -3823,9 +3823,9 @@  discard block
 block discarded – undo
3823 3823
 
3824 3824
 		// 4 - if mbstring is available, let it do the guesswork
3825 3825
 		// NB: we favour finding an encoding that is compatible with what we can process
3826
-		if(extension_loaded('mbstring'))
3826
+		if (extension_loaded('mbstring'))
3827 3827
 		{
3828
-			if($encoding_prefs)
3828
+			if ($encoding_prefs)
3829 3829
 			{
3830 3830
 				$enc = mb_detect_encoding($xmlchunk, $encoding_prefs);
3831 3831
 			}
@@ -3835,7 +3835,7 @@  discard block
 block discarded – undo
3835 3835
 			}
3836 3836
 			// NB: mb_detect likes to call it ascii, xml parser likes to call it US_ASCII...
3837 3837
 			// IANA also likes better US-ASCII, so go with it
3838
-			if($enc == 'ASCII')
3838
+			if ($enc == 'ASCII')
3839 3839
 			{
3840 3840
 				$enc = 'US-'.$enc;
3841 3841
 			}
@@ -3878,8 +3878,8 @@  discard block
 block discarded – undo
3878 3878
 		// Details:
3879 3879
 		// SPACE:		(#x20 | #x9 | #xD | #xA)+ === [ \x9\xD\xA]+
3880 3880
 		// EQ:			SPACE?=SPACE? === [ \x9\xD\xA]*=[ \x9\xD\xA]*
3881
-		if (preg_match('/^<\?xml\s+version\s*=\s*' . "((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))" .
3882
-			'\s+encoding\s*=\s*' . "((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3881
+		if (preg_match('/^<\?xml\s+version\s*=\s*'."((?:\"[a-zA-Z0-9_.:-]+\")|(?:'[a-zA-Z0-9_.:-]+'))".
3882
+			'\s+encoding\s*=\s*'."((?:\"[A-Za-z][A-Za-z0-9._-]*\")|(?:'[A-Za-z][A-Za-z0-9._-]*'))/",
3883 3883
 			$xmlChunk, $matches))
3884 3884
 		{
3885 3885
 			return true;
@@ -3898,7 +3898,7 @@  discard block
 block discarded – undo
3898 3898
 	function is_valid_charset($encoding, $validlist)
3899 3899
 	{
3900 3900
 		$charset_supersets = array(
3901
-			'US-ASCII' => array ('ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
3901
+			'US-ASCII' => array('ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
3902 3902
 				'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8',
3903 3903
 				'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-12',
3904 3904
 				'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'UTF-8',
Please login to merge, or discard this patch.