diff --git a/src/Curl/Curl.php b/src/Curl/Curl.php index b8c17dd..67435f3 100644 --- a/src/Curl/Curl.php +++ b/src/Curl/Curl.php @@ -55,6 +55,7 @@ class Curl private $jsonDecoderArgs = array(); private $jsonPattern = '/^(?:application|text)\/(?:[a-z]+(?:[\.-][0-9a-z]+){0,}[\+\.]|x-)?json(?:-[a-z]+)?/i'; + private $xmlDecoderArgs = array(); private $xmlPattern = '~^(?:text/|application/(?:atom\+|rss\+|soap\+)?)xml~i'; private $defaultDecoder = null; @@ -206,6 +207,7 @@ class Curl $this->jsonDecoder = null; $this->jsonDecoderArgs = null; $this->xmlDecoder = null; + $this->xmlDecoderArgs = null; $this->defaultDecoder = null; } @@ -855,10 +857,15 @@ class Curl * Set Default XML Decoder * * @access public + * @param $class_name + * @param $options + * @param $ns + * @param $is_prefix */ public function setDefaultXmlDecoder() { $this->xmlDecoder = '\Curl\Decoder::decodeXml'; + $this->xmlDecoderArgs = func_get_args(); } /** @@ -954,10 +961,7 @@ class Curl */ public function setJsonDecoder($mixed) { - if ($mixed === false) { - $this->jsonDecoder = false; - $this->jsonDecoderArgs = array(); - } elseif (is_callable($mixed)) { + if ($mixed === false || is_callable($mixed)) { $this->jsonDecoder = $mixed; $this->jsonDecoderArgs = array(); } @@ -971,10 +975,9 @@ class Curl */ public function setXmlDecoder($mixed) { - if ($mixed === false) { - $this->xmlDecoder = false; - } elseif (is_callable($mixed)) { + if ($mixed === false || is_callable($mixed)) { $this->xmlDecoder = $mixed; + $this->xmlDecoderArgs = array(); } } @@ -1418,7 +1421,9 @@ class Curl } } elseif (preg_match($this->xmlPattern, $response_headers['Content-Type'])) { if ($this->xmlDecoder) { - $response = call_user_func($this->xmlDecoder, $response); + $args = $this->xmlDecoderArgs; + array_unshift($args, $response); + $response = call_user_func_array($this->xmlDecoder, $args); } } else { if ($this->defaultDecoder) { diff --git a/src/Curl/Decoder.php b/src/Curl/Decoder.php index f12fcce..236cf54 100644 --- a/src/Curl/Decoder.php +++ b/src/Curl/Decoder.php @@ -35,11 +35,16 @@ class Decoder * Decode XML * * @access public - * @param $response + * @param $data + * @param $class_name + * @param $options + * @param $ns + * @param $is_prefix */ - public static function decodeXml($response) + public static function decodeXml() { - $xml_obj = @simplexml_load_string($response); + $args = func_get_args(); + $xml_obj = @call_user_func_array('simplexml_load_string', $args); if (!($xml_obj === false)) { $response = $xml_obj; } diff --git a/tests/PHPCurlClass/PHPCurlClassTest.php b/tests/PHPCurlClass/PHPCurlClassTest.php index 2bbb672..3d3cc90 100644 --- a/tests/PHPCurlClass/PHPCurlClassTest.php +++ b/tests/PHPCurlClass/PHPCurlClassTest.php @@ -1406,13 +1406,8 @@ class CurlTest extends \PHPUnit\Framework\TestCase public function testJsonDecoder() { - $data = array( - 'key' => 'Content-Type', - 'value' => 'application/json', - ); - $test = new Test(); - $test->server('json_response', 'POST', $data); + $test->server('json_response', 'GET'); $this->assertTrue(is_object($test->curl->response)); $this->assertFalse(is_array($test->curl->response)); @@ -1420,13 +1415,13 @@ class CurlTest extends \PHPUnit\Framework\TestCase $test->curl->setJsonDecoder(function ($response) { return json_decode($response, true); }); - $test->server('json_response', 'POST', $data); + $test->server('json_response', 'GET'); $this->assertFalse(is_object($test->curl->response)); $this->assertTrue(is_array($test->curl->response)); $test = new Test(); $test->curl->setJsonDecoder(false); - $test->server('json_response', 'POST', $data); + $test->server('json_response', 'GET'); $this->assertTrue(is_string($test->curl->response)); } @@ -2574,6 +2569,54 @@ class CurlTest extends \PHPUnit\Framework\TestCase } } + public function testXmlDecoderOptions() + { + // Implicit default xml decoder should return object. + $test = new Test(); + $test->server('xml_with_cdata_response', 'GET'); + $this->assertTrue(is_object($test->curl->response)); + $this->assertFalse(strpos($test->curl->response->saveXML(), 'curl->setDefaultXmlDecoder(); + $test->server('xml_with_cdata_response', 'GET'); + $this->assertTrue(is_object($test->curl->response)); + $this->assertFalse(strpos($test->curl->response->saveXML(), 'curl->setDefaultXmlDecoder($class_name, $options); + $test->server('xml_with_cdata_response', 'GET'); + $this->assertTrue(is_object($test->curl->response)); + $this->assertTrue(strpos($test->curl->response->saveXML(), 'server('xml_with_cdata_response', 'POST'); + $this->assertTrue(is_object($test->curl->response)); + $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); + $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'); + $this->assertTrue(is_object($test->curl->response)); + $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); + $this->assertTrue(strpos($test->curl->response->saveXML(), 'curl->setXmlDecoder(false); + $test->server('xml_with_cdata_response', 'POST'); + $this->assertTrue(is_string($test->curl->response)); + } + public function testXmlContentTypeDetection() { $xml_content_types = array( @@ -2595,7 +2638,7 @@ class CurlTest extends \PHPUnit\Framework\TestCase } } - public function testXMLResponse() + public function testXmlResponse() { foreach (array( 'Content-Type', @@ -2646,6 +2689,51 @@ class CurlTest extends \PHPUnit\Framework\TestCase } } + public function testDefaultDecoder() + { + // Default. + $test = new Test(); + $test->server('download_file_size', 'GET'); + $this->assertTrue(is_string($test->curl->response)); + + // Callable. + $test = new Test(); + $test->curl->setDefaultDecoder(function ($response) { + return '123'; + }); + $test->server('download_file_size', 'GET'); + $this->assertEquals('123', $test->curl->response); + + // "json". + $test = new Test(); + $test->curl->setDefaultDecoder('json'); + $test->server('json_response', 'POST', array( + 'key' => 'Content-Type', + 'value' => 'application/but-not-json', + )); + $this->assertInstanceOf('stdClass', $test->curl->response); + + // "xml". + $test = new Test(); + $test->curl->setDefaultDecoder('xml'); + $test->server('xml_response', 'POST', array( + 'key' => 'Content-Type', + 'value' => 'text/but-not-xml', + )); + $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); + + // False. + $test = new Test(); + $test->curl->setDefaultDecoder('json'); + $test->curl->setDefaultDecoder(false); + $test->server('json_response', 'POST', array( + 'key' => 'Content-Type', + 'value' => 'application/but-not-json', + )); + $this->assertTrue(is_string($test->curl->response)); + } + + public function testEmptyResponse() { $response = "\r\n\r\n"; @@ -3069,73 +3157,6 @@ class CurlTest extends \PHPUnit\Framework\TestCase $this->assertNotEmpty($stderr); } - public function testXMLDecoder() - { - $test = new Test(); - $test->server('xml_with_cdata_response', 'POST'); - $this->assertTrue(is_object($test->curl->response)); - $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); - $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'); - $this->assertTrue(is_object($test->curl->response)); - $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); - $this->assertTrue(strpos($test->curl->response->saveXML(), 'curl->setXmlDecoder(false); - $test->server('xml_with_cdata_response', 'POST'); - $this->assertTrue(is_string($test->curl->response)); - } - - public function testDefaultDecoder() - { - // Default. - $test = new Test(); - $test->server('download_file_size', 'GET'); - $this->assertTrue(is_string($test->curl->response)); - - // Callable. - $test = new Test(); - $test->curl->setDefaultDecoder(function ($response) { - return '123'; - }); - $test->server('download_file_size', 'GET'); - $this->assertEquals('123', $test->curl->response); - - // "json". - $test = new Test(); - $test->curl->setDefaultDecoder('json'); - $test->server('json_response', 'POST', array( - 'key' => 'Content-Type', - 'value' => 'application/but-not-json', - )); - $this->assertInstanceOf('stdClass', $test->curl->response); - - // "xml". - $test = new Test(); - $test->curl->setDefaultDecoder('xml'); - $test->server('xml_response', 'POST', array( - 'key' => 'Content-Type', - 'value' => 'text/but-not-xml', - )); - $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); - - // False. - $test = new Test(); - $test->curl->setDefaultDecoder('json'); - $test->curl->setDefaultDecoder(false); - $test->server('json_response', 'POST', array( - 'key' => 'Content-Type', - 'value' => 'application/but-not-json', - )); - $this->assertTrue(is_string($test->curl->response)); - } - public function testTotalTime() { $test = new Test();