Skip to content

Commit 925c28c

Browse files
committed
Events EVENT_BEFORE_SEND and EVENT_AFTER_SEND added to Request and Client
1 parent e1448d4 commit 925c28c

File tree

8 files changed

+232
-5
lines changed

8 files changed

+232
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Yii Framework 2 HTTP client extension Change Log
66

77
- Bug #44: Fixed exception name collision at `Response` and `Transport` (cebe)
88
- Bug #45: Fixed `XmlFormatter` unable to handle array with numeric keys (klimov-paul)
9+
- Enh #43: Events `EVENT_BEFORE_SEND` and `EVENT_AFTER_SEND` added to `Request` and `Client` (klimov-paul)
910
- Enh #46: Added `Request::getFullUrl()` allowing getting the full actual request URL (klimov-paul)
1011
- Enh #47: Added `Message::addData()` allowing addition of the content data to already existing one (klimov-paul)
1112
- Enh: Added `XmlFormatter::useTraversableAsArray` allowing processing `\Traversable` as array (klimov-paul)

Client.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
*/
2424
class Client extends Component
2525
{
26+
/**
27+
* @event RequestEvent an event raised right before sending request.
28+
*/
29+
const EVENT_BEFORE_SEND = 'beforeSend';
30+
/**
31+
* @event RequestEvent an event raised right after request has been sent.
32+
*/
33+
const EVENT_AFTER_SEND = 'afterSend';
34+
2635
/**
2736
* JSON format
2837
*/
@@ -348,6 +357,34 @@ public function options($url, $options = [])
348357
return $this->createRequestShortcut('options', $url, null, [], $options);
349358
}
350359

360+
/**
361+
* This method is invoked right before request is sent.
362+
* The method will trigger the [[EVENT_BEFORE_SEND]] event.
363+
* @param Request $request request instance.
364+
* @since 2.0.1
365+
*/
366+
public function beforeSend($request)
367+
{
368+
$event = new RequestEvent();
369+
$event->request = $request;
370+
$this->trigger(self::EVENT_BEFORE_SEND, $event);
371+
}
372+
373+
/**
374+
* This method is invoked right after request is sent.
375+
* The method will trigger the [[EVENT_AFTER_SEND]] event.
376+
* @param Request $request request instance.
377+
* @param Response $response received response instance.
378+
* @since 2.0.1
379+
*/
380+
public function afterSend($request, $response)
381+
{
382+
$event = new RequestEvent();
383+
$event->request = $request;
384+
$event->response = $response;
385+
$this->trigger(self::EVENT_AFTER_SEND, $event);
386+
}
387+
351388
/**
352389
* @param string $method
353390
* @param string $url

CurlTransport.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class CurlTransport extends Transport
2626
*/
2727
public function send($request)
2828
{
29+
$request->beforeSend();
30+
2931
$curlOptions = $this->prepare($request);
3032
$curlResource = $this->initCurl($curlOptions);
3133

@@ -55,7 +57,11 @@ public function send($request)
5557
throw new Exception('Curl error: #' . $errorNumber . ' - ' . $errorMessage);
5658
}
5759

58-
return $request->client->createResponse($responseContent, $responseHeaders);
60+
$response = $request->client->createResponse($responseContent, $responseHeaders);
61+
62+
$request->afterSend($response);
63+
64+
return $response;
5965
}
6066

6167
/**
@@ -70,6 +76,8 @@ public function batchSend(array $requests)
7076
$responseHeaders = [];
7177
foreach ($requests as $key => $request) {
7278
/* @var $request Request */
79+
$request->beforeSend();
80+
7381
$curlOptions = $this->prepare($request);
7482
$curlResource = $this->initCurl($curlOptions);
7583

@@ -112,7 +120,9 @@ public function batchSend(array $requests)
112120

113121
$responses = [];
114122
foreach ($requests as $key => $request) {
115-
$responses[$key] = $request->client->createResponse($responseContents[$key], $responseHeaders[$key]);
123+
$response = $request->client->createResponse($responseContents[$key], $responseHeaders[$key]);
124+
$request->afterSend($response);
125+
$responses[$key] = $response;
116126
}
117127
return $responses;
118128
}

Message.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
namespace yii\httpclient;
99

10+
use yii\base\Component;
1011
use yii\base\ErrorHandler;
11-
use yii\base\Object;
1212
use yii\web\Cookie;
1313
use yii\web\CookieCollection;
1414
use yii\web\HeaderCollection;
@@ -28,7 +28,7 @@
2828
* @author Paul Klimov <klimov.paul@gmail.com>
2929
* @since 2.0
3030
*/
31-
class Message extends Object
31+
class Message extends Component
3232
{
3333
/**
3434
* @var Client owner client instance.

Request.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
*/
2424
class Request extends Message
2525
{
26+
/**
27+
* @event RequestEvent an event raised right before sending request.
28+
*/
29+
const EVENT_BEFORE_SEND = 'beforeSend';
30+
/**
31+
* @event RequestEvent an event raised right after request has been sent.
32+
*/
33+
const EVENT_AFTER_SEND = 'afterSend';
34+
2635
/**
2736
* @var string|array target URL.
2837
*/
@@ -351,6 +360,36 @@ public function send()
351360
return $this->client->send($this);
352361
}
353362

363+
/**
364+
* This method is invoked right before this request is sent.
365+
* The method will invoke [[Client::beforeSend()]] and trigger the [[EVENT_BEFORE_SEND]] event.
366+
* @since 2.0.1
367+
*/
368+
public function beforeSend()
369+
{
370+
$this->client->beforeSend($this);
371+
372+
$event = new RequestEvent();
373+
$event->request = $this;
374+
$this->trigger(self::EVENT_BEFORE_SEND, $event);
375+
}
376+
377+
/**
378+
* This method is invoked right after this request is sent.
379+
* The method will invoke [[Client::afterSend()]] and trigger the [[EVENT_AFTER_SEND]] event.
380+
* @param Response $response received response instance.
381+
* @since 2.0.1
382+
*/
383+
public function afterSend($response)
384+
{
385+
$this->client->afterSend($this, $response);
386+
387+
$event = new RequestEvent();
388+
$event->request = $this;
389+
$event->response = $response;
390+
$this->trigger(self::EVENT_AFTER_SEND, $event);
391+
}
392+
354393
/**
355394
* @inheritdoc
356395
*/

RequestEvent.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* @link http://www.yiiframework.com/
4+
* @copyright Copyright (c) 2008 Yii Software LLC
5+
* @license http://www.yiiframework.com/license/
6+
*/
7+
8+
namespace yii\httpclient;
9+
10+
use yii\base\Event;
11+
12+
/**
13+
* RequestEvent represents the event parameter used for an request events.
14+
*
15+
* @author Paul Klimov <klimov.paul@gmail.com>
16+
* @since 2.0.1
17+
*/
18+
class RequestEvent extends Event
19+
{
20+
/**
21+
* @var Request related HTTP request instance.
22+
*/
23+
public $request;
24+
/**
25+
* @var Response|null related HTTP response.
26+
* This field will be filled only in case some response is already received, e.g. after request is sent.
27+
*/
28+
public $response;
29+
}

StreamTransport.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class StreamTransport extends Transport
2626
*/
2727
public function send($request)
2828
{
29+
$request->beforeSend();
30+
2931
$request->prepare();
3032

3133
$url = $request->getFullUrl();
@@ -69,7 +71,11 @@ public function send($request)
6971

7072
$responseHeaders = isset($metaData['wrapper_data']) ? $metaData['wrapper_data'] : [];
7173

72-
return $request->client->createResponse($responseContent, $responseHeaders);
74+
$response = $request->client->createResponse($responseContent, $responseHeaders);
75+
76+
$request->afterSend($response);
77+
78+
return $response;
7379
}
7480

7581
/**

tests/TransportTestCase.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace yiiunit\extensions\httpclient;
44

55
use yii\httpclient\Client;
6+
use yii\httpclient\Request;
7+
use yii\httpclient\RequestEvent;
68
use yii\httpclient\Response;
79

810
/**
@@ -131,4 +133,107 @@ public function testSendError()
131133

132134
$request->send();
133135
}
136+
137+
/**
138+
* @depends testSend
139+
*/
140+
public function testSendEvents()
141+
{
142+
$client = $this->createClient();
143+
$client->baseUrl = 'http://us.php.net';
144+
145+
$request = $client->createRequest()
146+
->setMethod('get')
147+
->setUrl('docs.php');
148+
149+
$beforeSendEvent = null;
150+
$request->on(Request::EVENT_BEFORE_SEND, function(RequestEvent $event) use (&$beforeSendEvent) {
151+
$beforeSendEvent = $event;
152+
});
153+
154+
$afterSendEvent = null;
155+
$request->on(Request::EVENT_AFTER_SEND, function(RequestEvent $event) use (&$afterSendEvent) {
156+
$afterSendEvent = $event;
157+
});
158+
159+
$response = $request->send();
160+
161+
$this->assertTrue($beforeSendEvent instanceof RequestEvent);
162+
$this->assertSame($request, $beforeSendEvent->request);
163+
$this->assertNull($beforeSendEvent->response);
164+
165+
$this->assertTrue($afterSendEvent instanceof RequestEvent);
166+
$this->assertSame($request, $afterSendEvent->request);
167+
$this->assertSame($response, $afterSendEvent->response);
168+
}
169+
170+
/**
171+
* @depends testSendEvents
172+
*/
173+
public function testClientSendEvents()
174+
{
175+
$client = $this->createClient();
176+
$client->baseUrl = 'http://us.php.net';
177+
178+
$request = $client->createRequest()
179+
->setMethod('get')
180+
->setUrl('docs.php');
181+
182+
$beforeSendEvent = null;
183+
$client->on(Client::EVENT_BEFORE_SEND, function(RequestEvent $event) use (&$beforeSendEvent) {
184+
$beforeSendEvent = $event;
185+
});
186+
187+
$afterSendEvent = null;
188+
$client->on(Client::EVENT_AFTER_SEND, function(RequestEvent $event) use (&$afterSendEvent) {
189+
$afterSendEvent = $event;
190+
});
191+
192+
$response = $request->send();
193+
194+
$this->assertTrue($beforeSendEvent instanceof RequestEvent);
195+
$this->assertSame($request, $beforeSendEvent->request);
196+
$this->assertNull($beforeSendEvent->response);
197+
198+
$this->assertTrue($afterSendEvent instanceof RequestEvent);
199+
$this->assertSame($request, $afterSendEvent->request);
200+
$this->assertSame($response, $afterSendEvent->response);
201+
}
202+
203+
/**
204+
* @depends testBatchSend
205+
* @depends testClientSendEvents
206+
*/
207+
public function testBatchSendEvents()
208+
{
209+
$client = $this->createClient();
210+
$client->baseUrl = 'http://us.php.net';
211+
212+
$beforeSendUrls = [];
213+
$client->on(Client::EVENT_BEFORE_SEND, function(RequestEvent $event) use (&$beforeSendUrls) {
214+
$beforeSendUrls[] = $event->request->getFullUrl();
215+
});
216+
217+
$afterSendUrls = [];
218+
$client->on(Client::EVENT_AFTER_SEND, function(RequestEvent $event) use (&$afterSendUrls) {
219+
$afterSendUrls[] = $event->request->getFullUrl();
220+
});
221+
222+
$requests = [];
223+
$requests['docs'] = $client->createRequest()
224+
->setMethod('get')
225+
->setUrl('docs.php');
226+
$requests['support'] = $client->createRequest()
227+
->setMethod('get')
228+
->setUrl('support.php');
229+
230+
$responses = $client->batchSend($requests);
231+
232+
$expectedUrls = [
233+
$client->baseUrl . '/docs.php',
234+
$client->baseUrl . '/support.php',
235+
];
236+
$this->assertEquals($expectedUrls, $beforeSendUrls);
237+
$this->assertEquals($expectedUrls, $afterSendUrls);
238+
}
134239
}

0 commit comments

Comments
 (0)