I have a CustomCommand_1
and a CustomCommand_2
.
Any way to create a pipeline of commands and executing CustomCommand_2
right after CustomCommand_1
execution? (without call a command inside the other one).
I could not find any way to do this, so I came up workaround (tested on laravel sync
driver).
First, you have to create/adjust base command:
namespace App\Commands;
use Illuminate\Foundation\Bus\DispatchesCommands;
abstract class Command {
use DispatchesCommands;
/**
* @var Command[]
*/
protected $commands = [];
/**
* @param Command|Command[] $command
*/
public function addNextCommand($command) {
if (is_array($command)) {
foreach ($command as $item) {
$this->commands[] = $item;
}
} else {
$this->commands[] = $command;
}
}
public function handlingCommandFinished() {
if (!$this->commands)
return;
$command = array_shift($this->commands);
$command->addNextCommand($this->commands);
$this->dispatch($command);
}
}
Every command has to call $this->handlingCommandFinished();
when they finish execution.
With this, you can chain your commands:
$command = new FirstCommand();
$command->addNextCommand(new SecondCommand());
$command->addNextCommand(new ThirdCommand());
$this->dispatch($command);
Pipeline
Instead of calling handlingCommandFinished
in each command, you can use command pipeline!
In App\Providers\BusServiceProvider::boot
add:
$dispatcher->pipeThrough([
'App\Commands\Pipeline\ChainCommands'
]);
Add create App\Commands\Pipeline\ChainCommands
:
class ChainCommands {
public function handle(Command $command, $next) {
$result = $next($command);
$command->handlingCommandFinished();
return $result;
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments