Reputation: 170
I'm creating a custom command which will truncate a table every thirty minutes in the console kernel (for development purposes). I want to run another right after the previous command.
P.S: I have an if statement which prevents running these commands on the production server.
$schedule->command('db:seed')->after(function () use ($schedule) : void {
$schedule->command('my-command:remove-users-from-tables')
->everyThirtyMinutes()
->environments(['demo', 'local']);
});
I expect to run the seeder right after "my-command" runs successfully every thirty minutes. However, in this way, only db:seed
runs.
Upvotes: 4
Views: 5153
Reputation: 132
The OP approach doesn't run the second command even in laravel 11, I'll try to explain why.
The whole class \Illuminate\Console\Scheduling\Schedule
(which is, btw, referenced in \App\Console\Kernel::schedule
as the parameter) is dedicated to only put the commands into \Illuminate\Console\Scheduling\Schedule::events
property, and not more.
Commands like schedule:run
(\Illuminate\Console\Scheduling\ScheduleRunCommand::handle
) or schedule:list
fetch the "events" only once,
so, when one add an event to Schedule::events
after the fetch, the "events" aren't queried after that at all, alone to say run.
It is suggested to make a job, consisting of the only Artisan::call
command and run it with dispatch
in the after
method parameter closure of the schedule builder.
Upvotes: 0
Reputation: 1810
If you want to run B after A you need to schedule A and AFTER that run B:
$schedule->command('my-command:remove-users-from-tables')
->everyThirtyMinutes()
->after(function() {
$this->artisan->call('db:seed');
});
Upvotes: 2
Reputation: 1998
An alternative that may be relevant in some cases (but I can imagine would also be a bad idea in others) is to run shell_exec
: https://www.php.net/manual/en/function.shell-exec.php
If you want to chain two artisan commands together as you would on the cli using &&
you can simply shell_exec('php artisan command:first && php artisan command:second')
.
shell_exec
returns the console output so if your commands print anything (ie, via $this->info
) then you can print that to console like so: $this->info(shell_exec('php artisan command:first && php artisan command:second'))
I'm probably going to get a lot of hate for this answer...
Upvotes: 1
Reputation: 3045
I have checked the source code for Illuminate\Console\Scheduling\Schedule class.
I think when we say:
$schedule->command(...);
The artisan command will be scheduled, not run straightaway.
So when you write like this:
$schedule->command('first-command')->after(function () use ($schedule) {
$schedule->command('second-command');
});
The second command will be registered, not run right after the first command.
So the best approach that I can think of is run the second command inside the first command according to this link
You might try something like this:
namespace App\Console\Commands;
use Illuminate\Console\Command;
class RemoveUsersFromTable extends Command
{
public function handle()
{
// Do something to remove users from table.
$this->call('db:seed');
}
}
Upvotes: 3