From 8cf2631c540f791168ebb2392a6f4e628bbb581a Mon Sep 17 00:00:00 2001 From: Zach Borboa Date: Sun, 31 Jan 2016 04:20:26 -0800 Subject: [PATCH] Fix #295: Allow setting a custom XML decoder --- README.md | 2 ++ src/Curl/Curl.php | 38 +++++++++++++++++++++++-- tests/PHPCurlClass/PHPCurlClassTest.php | 19 +++++++++++++ tests/PHPCurlClass/server.php | 22 ++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6052ee4..4454e9d 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,7 @@ Curl::setCookieJar($cookie_jar) Curl::setDefaultJsonDecoder() Curl::setDefaultTimeout() Curl::setDefaultUserAgent() +Curl::setDefaultXmlDecoder() Curl::setDigestAuthentication($username, $password = '') Curl::setHeader($key, $value) Curl::setJsonDecoder($function) @@ -212,6 +213,7 @@ Curl::setReferrer($referrer) Curl::setTimeout($seconds) Curl::setURL($url, $data = array()) Curl::setUserAgent($user_agent) +Curl::setXmlDecoder($function) Curl::success($callback) Curl::unsetHeader($key) Curl::verbose($on = true, $output=STDERR) diff --git a/src/Curl/Curl.php b/src/Curl/Curl.php index d89bcff..3bf56d4 100644 --- a/src/Curl/Curl.php +++ b/src/Curl/Curl.php @@ -78,6 +78,7 @@ class Curl private $jsonDecoder = null; private $jsonPattern = '/^(?:application|text)\/(?:[a-z]+(?:[\.-][0-9a-z]+){0,}[\+\.]|x-)?json(?:-[a-z]+)?/i'; + private $xmlDecoder = null; private $xmlPattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i'; /** @@ -97,6 +98,7 @@ class Curl $this->id = 1; $this->setDefaultUserAgent(); $this->setDefaultJsonDecoder(); + $this->setDefaultXmlDecoder(); $this->setDefaultTimeout(); $this->setOpt(CURLINFO_HEADER_OUT, true); $this->setOpt(CURLOPT_HEADERFUNCTION, array($this, 'headerCallback')); @@ -202,6 +204,7 @@ class Curl } $this->options = null; $this->jsonDecoder = null; + $this->xmlDecoder = null; } /** @@ -689,6 +692,22 @@ class Curl }; } + /** + * Set Default XML Decoder + * + * @access public + */ + public function setDefaultXmlDecoder() + { + $this->xmlDecoder = function($response) { + $xml_obj = @simplexml_load_string($response); + if (!($xml_obj === false)) { + $response = $xml_obj; + } + return $response; + }; + } + /** * Set Default Timeout * @@ -745,6 +764,19 @@ class Curl } } + /** + * Set XML Decoder + * + * @access public + * @param $function + */ + public function setXmlDecoder($function) + { + if (is_callable($function)) { + $this->xmlDecoder = $function; + } + } + /** * Set Opt * @@ -958,9 +990,9 @@ class Curl $response = $json_decoder($response); } } elseif (preg_match($this->xmlPattern, $response_headers['Content-Type'])) { - $xml_obj = @simplexml_load_string($response); - if (!($xml_obj === false)) { - $response = $xml_obj; + $xml_decoder = $this->xmlDecoder; + if (is_callable($xml_decoder)) { + $response = $xml_decoder($response); } } } diff --git a/tests/PHPCurlClass/PHPCurlClassTest.php b/tests/PHPCurlClass/PHPCurlClassTest.php index ff36d2b..137383c 100644 --- a/tests/PHPCurlClass/PHPCurlClassTest.php +++ b/tests/PHPCurlClass/PHPCurlClassTest.php @@ -2585,4 +2585,23 @@ class CurlTest extends PHPUnit_Framework_TestCase $this->assertNotEmpty($stderr); } + + public function testXMLDecoder() + { + $data = array( + 'key' => 'Content-Type', + 'value' => 'text/xml', + ); + + $test = new Test(); + $test->server('xml_with_cdata_response', 'POST', $data); + $this->assertFalse(strpos($test->curl->response->saveXML(), 'curl->setXmlDecoder(function($response) { + return simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA); + }); + $test->server('xml_with_cdata_response', 'POST', $data); + $this->assertTrue(strpos($test->curl->response->saveXML(), 'appendChild($channel); echo $doc->saveXML(); exit; +} elseif ($test === 'xml_with_cdata_response') { + header('Content-Type: text/xml'); + echo ' + + + + 1 + 33ee7e1eb504b6619c1b445ca1442c21 + <![CDATA[The Title]]> + + + + + 2 + b5c0b187fe309af0f4d35982fd961d7e + <![CDATA[Another Title]]> + + + + +'; + exit; } elseif ($test === 'upload_response') { $tmp_filename = tempnam('/tmp', 'php-curl-class.'); move_uploaded_file($_FILES['image']['tmp_name'], $tmp_filename);