diff --git a/src/Illuminate/Bus/Dispatcher.php b/src/Illuminate/Bus/Dispatcher.php index 9e0e7016976e..9dbd68ab3b2d 100644 --- a/src/Illuminate/Bus/Dispatcher.php +++ b/src/Illuminate/Bus/Dispatcher.php @@ -4,6 +4,7 @@ use ArrayAccess; use ReflectionClass; use ReflectionParameter; +use Illuminate\Pipeline\Pipeline; use Illuminate\Support\Collection; use Illuminate\Contracts\Queue\Queue; use Illuminate\Contracts\Bus\SelfHandling; @@ -12,6 +13,7 @@ use Illuminate\Contracts\Queue\ShouldBeQueued; use Illuminate\Contracts\Bus\QueueingDispatcher; use Illuminate\Contracts\Bus\Dispatcher as DispatcherContract; +use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract; class Dispatcher implements DispatcherContract, QueueingDispatcher, HandlerResolver { @@ -43,16 +45,32 @@ class Dispatcher implements DispatcherContract, QueueingDispatcher, HandlerResol */ protected $mapper; + /** + * The pipeline implementation. + * + * @var Pipeline + */ + protected $pipeline; + + /** + * The pipes which the pipeline will send commands through. + * + * @var array + */ + protected $pipes = []; + /** * Create a new command dispatcher instance. * * @param \Illuminate\Contracts\Container\Container $container + * @param \Illuminate\Contracts\Pipeline\Pipeline $pipeline * @param \Closure|null $queueResolver * @return void */ - public function __construct(Container $container, Closure $queueResolver = null) + public function __construct(Container $container, PipelineContract $pipeline, Closure $queueResolver = null) { $this->container = $container; + $this->pipeline = $pipeline; $this->queueResolver = $queueResolver; } @@ -160,6 +178,7 @@ public function dispatch($command, Closure $afterResolving = null) { if ($this->queueResolver && $this->commandShouldBeQueued($command)) { + $this->dispatchThroughPipeline($command); return $this->dispatchToQueue($command); } else @@ -178,16 +197,24 @@ public function dispatch($command, Closure $afterResolving = null) public function dispatchNow($command, Closure $afterResolving = null) { if ($command instanceof SelfHandling) - return $this->container->call([$command, 'handle']); - - $handler = $this->resolveHandler($command); + { + $handler = $command; + } + else + { + $handler = $this->resolveHandler($command); + } if ($afterResolving) call_user_func($afterResolving, $handler); - return call_user_func( - [$handler, $this->getHandlerMethod($command)], $command - ); + $handle = function ($command) use ($handler) { + return call_user_func( + [$handler, $this->getHandlerMethod($command)], $command + ); + }; + + return $this->dispatchThroughPipeline($command, $handle); } /** @@ -355,4 +382,31 @@ public static function simpleMapping($command, $commandNamespace, $handlerNamesp return $handlerNamespace.'\\'.trim($command, '\\').'Handler@handle'; } + /** + * Set the pipes which the pipeline will use when dispatching commands. + * + * @param array $pipes + * @return void + */ + public function setPipes(array $pipes) + { + $this->pipes = $pipes; + } + + /** + * Dispatch the command through the pipeline + * + * @param mixed $command + * @param Closure|null $after + * @return mixed + */ + protected function dispatchThroughPipeline($command, \Closure $after = null) + { + $result = $this->pipeline->send($command) + ->through($this->pipes) + ->via('dispatch'); + + return $after ? $result->then($after) : $result; + } + } diff --git a/tests/Bus/BusDispatcherTest.php b/tests/Bus/BusDispatcherTest.php index 40de8f4738af..ea1662c2ba1f 100644 --- a/tests/Bus/BusDispatcherTest.php +++ b/tests/Bus/BusDispatcherTest.php @@ -1,5 +1,6 @@ shouldReceive('handle')->once()->andReturn('foo'); $container->instance('Handler', $handler); - $dispatcher = new Dispatcher($container); + $dispatcher = new Dispatcher($container, $pipeline); $dispatcher->mapUsing(function() { return 'Handler@handle'; }); $result = $dispatcher->dispatch(new BusDispatcherTestBasicCommand); @@ -29,7 +31,8 @@ public function testBasicDispatchingOfCommandsToHandlers() public function testCommandsThatShouldBeQueuedAreQueued() { $container = new Container; - $dispatcher = new Dispatcher($container, function() { + $pipeline = new Pipeline($container); + $dispatcher = new Dispatcher($container, $pipeline, function() { $mock = m::mock('Illuminate\Contracts\Queue\Queue'); $mock->shouldReceive('push')->once(); return $mock; @@ -42,7 +45,8 @@ public function testCommandsThatShouldBeQueuedAreQueued() public function testCommandsThatShouldBeQueuedAreQueuedUsingCustomHandler() { $container = new Container; - $dispatcher = new Dispatcher($container, function() { + $pipeline = new Pipeline($container); + $dispatcher = new Dispatcher($container, $pipeline, function() { $mock = m::mock('Illuminate\Contracts\Queue\Queue'); $mock->shouldReceive('push')->once(); return $mock; @@ -55,7 +59,8 @@ public function testCommandsThatShouldBeQueuedAreQueuedUsingCustomHandler() public function testHandlersThatShouldBeQueuedAreQueued() { $container = new Container; - $dispatcher = new Dispatcher($container, function() { + $pipeline = new Pipeline($container); + $dispatcher = new Dispatcher($container, $pipeline, function() { $mock = m::mock('Illuminate\Contracts\Queue\Queue'); $mock->shouldReceive('push')->once(); return $mock; @@ -69,10 +74,11 @@ public function testHandlersThatShouldBeQueuedAreQueued() public function testDispatchNowShouldNeverQueue() { $container = new Container; + $pipeline = new Pipeline($container); $handler = m::mock('StdClass'); $handler->shouldReceive('handle')->once()->andReturn('foo'); $container->instance('Handler', $handler); - $dispatcher = new Dispatcher($container); + $dispatcher = new Dispatcher($container, $pipeline); $dispatcher->mapUsing(function() { return 'Handler@handle'; }); $result = $dispatcher->dispatch(m::mock('Illuminate\Contracts\Queue\ShouldBeQueued')); @@ -83,10 +89,11 @@ public function testDispatchNowShouldNeverQueue() public function testDispatchShouldCallAfterResolvingIfCommandNotQueued() { $container = new Container; + $pipeline = new Pipeline($container); $handler = m::mock('StdClass')->shouldIgnoreMissing(); $handler->shouldReceive('after')->once(); $container->instance('Handler', $handler); - $dispatcher = new Dispatcher($container); + $dispatcher = new Dispatcher($container, $pipeline); $dispatcher->mapUsing(function() { return 'Handler@handle'; }); $dispatcher->dispatch(new BusDispatcherTestBasicCommand, function($handler) { $handler->after(); }); @@ -95,7 +102,9 @@ public function testDispatchShouldCallAfterResolvingIfCommandNotQueued() public function testDispatchingFromArray() { - $instance = new Dispatcher(new Container); + $container = new Container(); + $pipeline = new Pipeline($container); + $instance = new Dispatcher($container, $pipeline); $result = $instance->dispatchFromArray('BusDispatcherTestSelfHandlingCommand', ['firstName' => 'taylor', 'lastName' => 'otwell']); $this->assertEquals('taylor otwell', $result); } @@ -103,10 +112,32 @@ public function testDispatchingFromArray() public function testMarshallArguments() { - $instance = new Dispatcher(new Container); + $container = new Container(); + $pipeline = new Pipeline($container); + $instance = new Dispatcher($container, $pipeline); $result = $instance->dispatchFromArray('BusDispatcherTestArgumentMapping', ['flag' => false, 'emptyString' => '']); $this->assertTrue($result); } + + + public function testDispatchingSentThroughPipes() + { + $container = new Container(); + $pipeline = new Pipeline($container); + + $pipeDispatcher = m::mock('BusDispatcherPipelineDispatcher'); + $pipeDispatcher->shouldReceive('dispatch')->once(); + $container->instance('BusDispatcherPipelineDispatcher', $pipeDispatcher); + + $handler = m::mock('StdClass')->shouldIgnoreMissing(); + $container->instance('Handler', $handler); + + $dispatcher = new Dispatcher($container, $pipeline); + $dispatcher->mapUsing(function() { return 'Handler@handle'; }); + $dispatcher->setPipes(['BusDispatcherPipelineDispatcher']); + $dispatcher->dispatch(new BusDispatcherTestBasicCommand); + } + } class BusDispatcherTestBasicCommand { @@ -157,3 +188,9 @@ public function queue($queue, $command) $queue->push($command); } } + + +class BusDispatcherPipelineDispatcher { + public function dispatch($command) {} +} +