Conditions | 27 |
Paths | 8188 |
Total Lines | 189 |
Code Lines | 104 |
Lines | 28 |
Ratio | 14.81 % |
Changes | 10 | ||
Bugs | 1 | Features | 1 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
180 | public function parseResponse($data = '', $headersProcessed = false, $returnType = 'xmlrpcvals') |
||
181 | { |
||
182 | if ($this->debug) { |
||
183 | Logger::instance()->debugMessage("---GOT---\n$data\n---END---"); |
||
184 | } |
||
185 | |||
186 | $this->httpResponse = array('raw_data' => $data, 'headers' => array(), 'cookies' => array()); |
||
187 | |||
188 | View Code Duplication | if ($data == '') { |
|
|
|||
189 | error_log('XML-RPC: ' . __METHOD__ . ': no response received from server.'); |
||
190 | return new Response(0, PhpXmlRpc::$xmlrpcerr['no_data'], PhpXmlRpc::$xmlrpcstr['no_data']); |
||
191 | } |
||
192 | |||
193 | // parse the HTTP headers of the response, if present, and separate them from data |
||
194 | if (substr($data, 0, 4) == 'HTTP') { |
||
195 | $httpParser = new Http(); |
||
196 | try { |
||
197 | $this->httpResponse = $httpParser->parseResponseHeaders($data, $headersProcessed, $this->debug); |
||
198 | } catch(\Exception $e) { |
||
199 | $r = new Response(0, $e->getCode(), $e->getMessage()); |
||
200 | // failed processing of HTTP response headers |
||
201 | // save into response obj the full payload received, for debugging |
||
202 | $r->raw_data = $data; |
||
203 | |||
204 | return $r; |
||
205 | } |
||
206 | } |
||
207 | |||
208 | // be tolerant of extra whitespace in response body |
||
209 | $data = trim($data); |
||
210 | |||
211 | /// @todo return an error msg if $data=='' ? |
||
212 | |||
213 | // be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts) |
||
214 | // idea from Luca Mariano <[email protected]> originally in PEARified version of the lib |
||
215 | $pos = strrpos($data, '</methodResponse>'); |
||
216 | if ($pos !== false) { |
||
217 | $data = substr($data, 0, $pos + 17); |
||
218 | } |
||
219 | |||
220 | // try to 'guestimate' the character encoding of the received response |
||
221 | $respEncoding = XMLParser::guessEncoding(@$this->httpResponse['headers']['content-type'], $data); |
||
222 | |||
223 | if ($this->debug) { |
||
224 | $start = strpos($data, '<!-- SERVER DEBUG INFO (BASE64 ENCODED):'); |
||
225 | if ($start) { |
||
226 | $start += strlen('<!-- SERVER DEBUG INFO (BASE64 ENCODED):'); |
||
227 | $end = strpos($data, '-->', $start); |
||
228 | $comments = substr($data, $start, $end - $start); |
||
229 | Logger::instance()->debugMessage("---SERVER DEBUG INFO (DECODED) ---\n\t" . |
||
230 | str_replace("\n", "\n\t", base64_decode($comments)) . "\n---END---", $respEncoding); |
||
231 | } |
||
232 | } |
||
233 | |||
234 | // if user wants back raw xml, give it to him |
||
235 | if ($returnType == 'xml') { |
||
236 | $r = new Response($data, 0, '', 'xml'); |
||
237 | $r->hdrs = $this->httpResponse['headers']; |
||
238 | $r->_cookies = $this->httpResponse['cookies']; |
||
239 | $r->raw_data = $this->httpResponse['raw_data']; |
||
240 | |||
241 | return $r; |
||
242 | } |
||
243 | |||
244 | View Code Duplication | if ($respEncoding != '') { |
|
245 | |||
246 | // Since parsing will fail if charset is not specified in the xml prologue, |
||
247 | // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that... |
||
248 | // The following code might be better for mb_string enabled installs, but |
||
249 | // makes the lib about 200% slower... |
||
250 | //if (!is_valid_charset($respEncoding, array('UTF-8'))) |
||
251 | if (!in_array($respEncoding, array('UTF-8', 'US-ASCII')) && !XMLParser::hasEncoding($data)) { |
||
252 | if ($respEncoding == 'ISO-8859-1') { |
||
253 | $data = utf8_encode($data); |
||
254 | } else { |
||
255 | if (extension_loaded('mbstring')) { |
||
256 | $data = mb_convert_encoding($data, 'UTF-8', $respEncoding); |
||
257 | } else { |
||
258 | error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received response: ' . $respEncoding); |
||
259 | } |
||
260 | } |
||
261 | } |
||
262 | } |
||
263 | |||
264 | $parser = xml_parser_create(); |
||
265 | xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); |
||
266 | // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell |
||
267 | // the xml parser to give us back data in the expected charset. |
||
268 | // What if internal encoding is not in one of the 3 allowed? |
||
269 | // we use the broadest one, ie. utf8 |
||
270 | // This allows to send data which is native in various charset, |
||
271 | // by extending xmlrpc_encode_entities() and setting xmlrpc_internalencoding |
||
272 | View Code Duplication | if (!in_array(PhpXmlRpc::$xmlrpc_internalencoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII'))) { |
|
273 | xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8'); |
||
274 | } else { |
||
275 | xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, PhpXmlRpc::$xmlrpc_internalencoding); |
||
276 | } |
||
277 | |||
278 | $xmlRpcParser = new XMLParser(); |
||
279 | xml_set_object($parser, $xmlRpcParser); |
||
280 | |||
281 | if ($returnType == 'phpvals') { |
||
282 | xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast'); |
||
283 | } else { |
||
284 | xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); |
||
285 | } |
||
286 | |||
287 | xml_set_character_data_handler($parser, 'xmlrpc_cd'); |
||
288 | xml_set_default_handler($parser, 'xmlrpc_dh'); |
||
289 | |||
290 | // first error check: xml not well formed |
||
291 | if (!xml_parse($parser, $data, count($data))) { |
||
292 | // thanks to Peter Kocks <[email protected]> |
||
293 | if ((xml_get_current_line_number($parser)) == 1) { |
||
294 | $errStr = 'XML error at line 1, check URL'; |
||
295 | } else { |
||
296 | $errStr = sprintf('XML error: %s at line %d, column %d', |
||
297 | xml_error_string(xml_get_error_code($parser)), |
||
298 | xml_get_current_line_number($parser), xml_get_current_column_number($parser)); |
||
299 | } |
||
300 | error_log($errStr); |
||
301 | $r = new Response(0, PhpXmlRpc::$xmlrpcerr['invalid_return'], PhpXmlRpc::$xmlrpcstr['invalid_return'] . ' (' . $errStr . ')'); |
||
302 | xml_parser_free($parser); |
||
303 | if ($this->debug) { |
||
304 | print $errStr; |
||
305 | } |
||
306 | $r->hdrs = $this->httpResponse['headers']; |
||
307 | $r->_cookies = $this->httpResponse['cookies']; |
||
308 | $r->raw_data = $this->httpResponse['raw_data']; |
||
309 | |||
310 | return $r; |
||
311 | } |
||
312 | xml_parser_free($parser); |
||
313 | // second error check: xml well formed but not xml-rpc compliant |
||
314 | if ($xmlRpcParser->_xh['isf'] > 1) { |
||
315 | if ($this->debug) { |
||
316 | /// @todo echo something for user? |
||
317 | } |
||
318 | |||
319 | $r = new Response(0, PhpXmlRpc::$xmlrpcerr['invalid_return'], |
||
320 | PhpXmlRpc::$xmlrpcstr['invalid_return'] . ' ' . $xmlRpcParser->_xh['isf_reason']); |
||
321 | } |
||
322 | // third error check: parsing of the response has somehow gone boink. |
||
323 | // NB: shall we omit this check, since we trust the parsing code? |
||
324 | elseif ($returnType == 'xmlrpcvals' && !is_object($xmlRpcParser->_xh['value'])) { |
||
325 | // something odd has happened |
||
326 | // and it's time to generate a client side error |
||
327 | // indicating something odd went on |
||
328 | $r = new Response(0, PhpXmlRpc::$xmlrpcerr['invalid_return'], |
||
329 | PhpXmlRpc::$xmlrpcstr['invalid_return']); |
||
330 | } else { |
||
331 | if ($this->debug > 1) { |
||
332 | Logger::instance()->debugMessage( |
||
333 | "---PARSED---\n".var_export($xmlRpcParser->_xh['value'], true)."\n---END---" |
||
334 | ); |
||
335 | } |
||
336 | |||
337 | // note that using =& will raise an error if $xmlRpcParser->_xh['st'] does not generate an object. |
||
338 | $v = &$xmlRpcParser->_xh['value']; |
||
339 | |||
340 | if ($xmlRpcParser->_xh['isf']) { |
||
341 | /// @todo we should test here if server sent an int and a string, and/or coerce them into such... |
||
342 | if ($returnType == 'xmlrpcvals') { |
||
343 | $errNo_v = $v['faultCode']; |
||
344 | $errStr_v = $v['faultString']; |
||
345 | $errNo = $errNo_v->scalarval(); |
||
346 | $errStr = $errStr_v->scalarval(); |
||
347 | } else { |
||
348 | $errNo = $v['faultCode']; |
||
349 | $errStr = $v['faultString']; |
||
350 | } |
||
351 | |||
352 | if ($errNo == 0) { |
||
353 | // FAULT returned, errno needs to reflect that |
||
354 | $errNo = -1; |
||
355 | } |
||
356 | |||
357 | $r = new Response(0, $errNo, $errStr); |
||
358 | } else { |
||
359 | $r = new Response($v, 0, '', $returnType); |
||
360 | } |
||
361 | } |
||
362 | |||
363 | $r->hdrs = $this->httpResponse['headers']; |
||
364 | $r->_cookies = $this->httpResponse['cookies']; |
||
365 | $r->raw_data = $this->httpResponse['raw_data']; |
||
366 | |||
367 | return $r; |
||
368 | } |
||
369 | |||
390 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.