diff --git a/docs/hooks.md b/docs/hooks.md index f8414e4ad..9f71b9acb 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -93,7 +93,7 @@ Available Hooks Alter the raw HTTP response before returning for parsing. - Parameters: `string &$headers`, `[array &$info]` + Parameters: `string &$headers`, `[array &$info]`, `[int|string $id]` The optional `$info` parameter contains the associated array as defined in the return value for [curl_getinfo()](https://www.php.net/curl-getinfo#refsect1-function.curl-getinfo-returnvalues). diff --git a/src/Transport/Curl.php b/src/Transport/Curl.php index 7316987b5..953de618e 100644 --- a/src/Transport/Curl.php +++ b/src/Transport/Curl.php @@ -300,7 +300,7 @@ public function request_multiple($requests, $options) { $responses[$key] = $exception; $options['hooks']->dispatch('transport.internal.parse_error', [&$responses[$key], $requests[$key]]); } else { - $responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options); + $responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options, $key); $options['hooks']->dispatch('transport.internal.parse_response', [&$responses[$key], $requests[$key]]); } @@ -464,13 +464,14 @@ private function setup_handle($url, $headers, $data, $options) { * * @param string $response Response data from the body * @param array $options Request options + * @param int|string|null $id ID of a multi-request * @return string|false HTTP response data including headers. False if non-blocking. * @throws \WpOrg\Requests\Exception If the request resulted in a cURL error. */ - public function process_response($response, $options) { + public function process_response($response, $options, $id = null) { if ($options['blocking'] === false) { $fake_headers = ''; - $options['hooks']->dispatch('curl.after_request', [&$fake_headers]); + $options['hooks']->dispatch('curl.after_request', [&$fake_headers, null, $id]); return false; } @@ -492,7 +493,7 @@ public function process_response($response, $options) { $this->info = curl_getinfo($this->handle); - $options['hooks']->dispatch('curl.after_request', [&$this->headers, &$this->info]); + $options['hooks']->dispatch('curl.after_request', [&$this->headers, &$this->info, $id]); return $this->headers; } diff --git a/tests/Transport/CurlTest.php b/tests/Transport/CurlTest.php index a96401038..0c3211e6d 100644 --- a/tests/Transport/CurlTest.php +++ b/tests/Transport/CurlTest.php @@ -3,6 +3,7 @@ namespace WpOrg\Requests\Tests\Transport; use WpOrg\Requests\Exception; +use WpOrg\Requests\Hooks; use WpOrg\Requests\Requests; use WpOrg\Requests\Tests\Transport\BaseTestCase; use WpOrg\Requests\Transport\Curl; @@ -136,4 +137,38 @@ public function testSetsEmptyExpectHeaderIfBodySmallerThan1Mb() { $this->assertFalse(isset($result['headers']['Expect'])); } + + public function testMultipleTriggersCurlAfterRequestHookWithId() { + $requests = [ + 'get' => [ + 'url' => $this->httpbin('/get', true), + ], + 'post' => [ + 'url' => $this->httpbin('/post', true), + 'type' => Requests::POST, + 'data' => 'test', + ], + ]; + + $mock = $this->getMockBuilder(stdClass::class) + ->setMethods(['after_request']) + ->getMock(); + + $mock->expects($this->atLeast(2)) + ->method('after_request') + ->with( + $this->isType('string'), + $this->logicalAnd($this->isType('array'), $this->logicalNot($this->isEmpty())), + $this->isType('string') + ); + $hooks = new Hooks(); + $hooks->register('curl.after_request', [$mock, 'after_request']); + + $options = [ + 'hooks' => $hooks, + ]; + + Requests::request_multiple($requests, $this->getOptions($options)); + } + }