Skip to content

Commit fbd4b1f

Browse files
committed
Use events instead of callbacks.
Signed-off-by: Jason Lewis <[email protected]>
1 parent 67e0b5b commit fbd4b1f

File tree

5 files changed

+86
-69
lines changed

5 files changed

+86
-69
lines changed

src/Event/ResponseIsMorphing.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Dingo\Api\Event;
4+
5+
use Dingo\Api\Http\Response;
6+
7+
class ResponseIsMorphing
8+
{
9+
/**
10+
* Response instance.
11+
*
12+
* @var \Dingo\Api\Http\Response
13+
*/
14+
public $response;
15+
16+
/**
17+
* Response content.
18+
*
19+
* @var string
20+
*/
21+
public $content;
22+
23+
/**
24+
* Create a new response is morphing event. Content is passed by reference
25+
* so that multiple listeners can modify content.
26+
*
27+
* @param \Dingo\Api\Http\Response $response
28+
* @param string $content
29+
*
30+
* @return void
31+
*/
32+
public function __construct(Response $response, &$content)
33+
{
34+
$this->response = $response;
35+
$this->content = &$content;
36+
}
37+
}

src/Event/ResponseWasMorphed.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Dingo\Api\Event;
4+
5+
use Dingo\Api\Http\Response;
6+
7+
class ResponseWasMorphed extends ResponseIsMorphing
8+
{
9+
}

src/Http/Response.php

Lines changed: 23 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
namespace Dingo\Api\Http;
44

5-
use Closure;
65
use ArrayObject;
6+
use Dingo\Api\Event;
77
use UnexpectedValueException;
88
use Dingo\Api\Transformer\Binding;
99
use Illuminate\Contracts\Support\Arrayable;
1010
use Symfony\Component\HttpFoundation\Cookie;
1111
use Illuminate\Http\Response as IlluminateResponse;
12+
use Illuminate\Events\Dispatcher as EventDispatcher;
1213
use Illuminate\Database\Eloquent\Model as EloquentModel;
1314
use Dingo\Api\Transformer\Factory as TransformerFactory;
1415
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
@@ -38,18 +39,11 @@ class Response extends IlluminateResponse
3839
protected static $transformer;
3940

4041
/**
41-
* Array of user-defined morphing callbacks.
42+
* Event dispatcher instance.
4243
*
43-
* @var array
44-
*/
45-
protected static $morphingCallbacks = [];
46-
47-
/**
48-
* Array of user-defined morphed callbacks.
49-
*
50-
* @var array
44+
* @var \Illuminate\Events\Dispatcher
5145
*/
52-
protected static $morphedCallbacks = [];
46+
protected static $events;
5347

5448
/**
5549
* Create a new response instance.
@@ -95,7 +89,7 @@ public function morph($format = 'json')
9589
{
9690
$this->content = $this->getOriginalContent();
9791

98-
$this->fireMorphingCallbacks();
92+
$this->fireMorphingEvent();
9993

10094
if (isset(static::$transformer) && static::$transformer->transformableResponse($this->content)) {
10195
$this->content = static::$transformer->transform($this->content);
@@ -107,7 +101,7 @@ public function morph($format = 'json')
107101

108102
$this->headers->set('content-type', $formatter->getContentType());
109103

110-
$this->fireMorphedCallbacks();
104+
$this->fireMorphedEvent();
111105

112106
if ($this->content instanceof EloquentModel) {
113107
$this->content = $formatter->formatEloquentModel($this->content);
@@ -123,39 +117,31 @@ public function morph($format = 'json')
123117
}
124118

125119
/**
126-
* Fire the morphed callbacks.
120+
* Fire the morphed event.
127121
*
128122
* @return void
129123
*/
130-
protected function fireMorphedCallbacks()
124+
protected function fireMorphedEvent()
131125
{
132-
$this->fireCallbacks(static::$morphedCallbacks);
133-
}
126+
if (! static::$events) {
127+
return;
128+
}
134129

135-
/**
136-
* Fire the morphing callbacks.
137-
*
138-
* @return void
139-
*/
140-
protected function fireMorphingCallbacks()
141-
{
142-
$this->fireCallbacks(static::$morphingCallbacks);
130+
static::$events->fire(new Event\ResponseWasMorphed($this, $this->content));
143131
}
144132

145133
/**
146-
* Fire the callbacks with the content and response instance as parameters.
147-
*
148-
* @param array $callbacks
134+
* Fire the morphing event.
149135
*
150136
* @return void
151137
*/
152-
protected function fireCallbacks(array $callbacks)
138+
protected function fireMorphingEvent()
153139
{
154-
foreach ($callbacks as $callback) {
155-
if ($response = call_user_func($callback, $this->content, $this)) {
156-
$this->content = $response;
157-
}
140+
if (! static::$events) {
141+
return;
158142
}
143+
144+
static::$events->fire(new Event\ResponseIsMorphing($this, $this->content));
159145
}
160146

161147
/**
@@ -177,27 +163,15 @@ public function setContent($content)
177163
}
178164

179165
/**
180-
* Add a callback for when the response is about to be morphed.
181-
*
182-
* @param \Closure $callback
183-
*
184-
* @return void
185-
*/
186-
public static function morphing(Closure $callback)
187-
{
188-
static::$morphingCallbacks[] = $callback;
189-
}
190-
191-
/**
192-
* Add a callback for when the response has been morphed.
166+
* Set the event dispatcher instance.
193167
*
194-
* @param \Closure $callback
168+
* @param \Illuminate\Events\Dispatcher $events
195169
*
196170
* @return void
197171
*/
198-
public static function morphed(Closure $callback)
172+
public static function setEventDispatcher(EventDispatcher $events)
199173
{
200-
static::$morphedCallbacks[] = $callback;
174+
static::$events = $events;
201175
}
202176

203177
/**

src/Provider/ApiServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function boot()
3131

3232
Http\Response::setFormatters($this->prepareConfigValues($this->app['config']['api.formats']));
3333
Http\Response::setTransformer($this->app['api.transformer']);
34+
Http\Response::setEventDispatcher($this->app['events']);
3435

3536
$this->app->rebinding('api.routes', function ($app, $routes) {
3637
$app['api.url']->setRouteCollections($routes);

tests/Http/ResponseTest.php

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,18 @@
99
use PHPUnit_Framework_TestCase;
1010
use Dingo\Api\Transformer\Binding;
1111
use Dingo\Api\Http\Response\Format\Json;
12+
use Illuminate\Events\Dispatcher as EventDispatcher;
1213

1314
class ResponseTest extends PHPUnit_Framework_TestCase
1415
{
16+
public function setUp()
17+
{
18+
Response::setEventDispatcher($this->events = new EventDispatcher);
19+
}
20+
1521
public function tearDown()
1622
{
1723
m::close();
18-
19-
$reflection = new ReflectionClass('Dingo\Api\Http\Response');
20-
21-
$property = $reflection->getProperty('morphedCallbacks');
22-
23-
$property->setAccessible(true);
24-
$property->setValue([]);
25-
26-
$property = $reflection->getProperty('morphingCallbacks');
27-
28-
$property->setAccessible(true);
29-
$property->setValue([]);
3024
}
3125

3226
/**
@@ -70,31 +64,33 @@ public function testBuildingWithCustomStatusCodeAndHeaders()
7064
$this->assertEquals(302, $response->getStatusCode());
7165
}
7266

73-
public function testChangingContentWithCallbacks()
67+
public function testChangingContentWithEvents()
7468
{
75-
Response::morphed(function ($content, Response $response) {
76-
$content['foo'] = 'bam!';
77-
78-
return $content;
69+
$this->events->listen('Dingo\Api\Event\ResponseWasMorphed', function ($event) {
70+
$event->content['foo'] = 'bam!';
7971
});
8072

8173
Response::addFormatter('json', new Json);
8274

8375
$response = new Response(['foo' => 'bar']);
8476

8577
$this->assertEquals('{"foo":"bam!"}', $response->morph('json')->getContent());
78+
79+
$this->events->forget('Dingo\Api\Event\ResponseWasMorphed');
8680
}
8781

88-
public function testChangingResponseHeadersWithCallbacks()
82+
public function testChangingResponseHeadersWithEvents()
8983
{
90-
Response::morphing(function ($content, Response $response) {
91-
$response->headers->set('x-foo', 'bar');
84+
$this->events->listen('Dingo\Api\Event\ResponseIsMorphing', function ($event) {
85+
$event->response->headers->set('x-foo', 'bar');
9286
});
9387

9488
Response::addFormatter('json', new Json);
9589

9690
$response = new Response(['foo' => 'bar']);
9791

9892
$this->assertEquals('bar', $response->morph('json')->headers->get('x-foo'));
93+
94+
$this->events->forget('Dingo\Api\Event\ResponseIsMorphing');
9995
}
10096
}

0 commit comments

Comments
 (0)