Christopher
Christopher

Reputation: 3469

Laravel 5 Commands - Execute one after other

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).

Upvotes: 3

Views: 2110

Answers (3)

Daniel Antos
Daniel Antos

Reputation: 1216

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;
    }
}

Upvotes: 0

Martin Bean
Martin Bean

Reputation: 39389

What is stopping you from doing the following?

$this->dispatch(new CustomCommand_1);
$this->dispatch(new CustomCommand_2);
// And so on

Upvotes: 0

Gaurav Dave
Gaurav Dave

Reputation: 7474

You can use a callback to decide when something will or won't run, using when() or skip():

$schedule
    ->call('Mailer@BusinessDayMailer')
    ->weekdays()
    ->skip(function(TypeHintedDeciderClass $decider)
    {
        return $decider->isHoliday();
    }
);

Referred: Event Scheduling and Commands & Handlers

You can also read how to add commands in queue here. See, if that helps.

Upvotes: 1

Related Questions