Laravel intercept multi-parameter Artisan event

Viewed 258

When running php artisan migrate --seed, I would like to intercept the moment between migration finish and seeding start.

It seems that attaching listeners on Artisan command events catches only "top level" command:

Event::listen(CommandStarting::class, function (CommandStarting $event) use ($path) {
    echo "Start\n";
    echo $event->input;
});

Event::listen(CommandFinished::class, function (CommandFinished $event) use ($path) {
    echo "Finish\n";
    echo $event->input;
});

This will output only migrate --seed command, independently of the fact that --seed flag actually calls the db:seed command:

if ($this->option('seed') && ! $this->option('pretend')) {
    $this->call('db:seed', ['--force' => true]);
}

Is it possible to somehow catch that event in-between?

1 Answers

I was able to figure out something for this.

I created a new service provider and added to the config/app.php list.

The MigrationCommand and the Migrator emits various events one of them is MigrationsEnded, so in conjunction with the CommandStarting to get the argv to see whether --seed was given.

<?php

namespace App\Providers;

use Event;
use Illuminate\Console\Events\CommandFinished;
use Illuminate\Console\Events\CommandStarting;
use Illuminate\Database\Events\MigrationsEnded;
use Illuminate\Support\ServiceProvider;

class CommandListenerProvider extends ServiceProvider
{
    public $isPretend = true;
    public $hasSeed = false;

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    public function boot()
    {
        Event::listen(CommandStarting::class, function (CommandStarting $event) {
            if ($event->input->hasParameterOption('migrate')
                && !$event->input->hasParameterOption('--pretend')
            ) {
                $this->isPretend = false;

                if ($event->input->hasParameterOption('--seed')) {
                    $this->hasSeed = true;
                }
            }
        });

        Event::listen(MigrationsEnded::class, function (MigrationsEnded $event) {
            // migration was successful and there was something done, i.e add or remove
            if ($this->hasSeed && !$this->isPretend) {
                dump('Finished migrating and --seed was requested, so do what you want here');
            }
        });
    }
}

Example:

$ php artisan migrate --seed  
"artisan started"
Migrating: 2021_06_17_191423_create_so_answer_table
Migrated:  2021_06_17_191423_create_so_answer_table (0.03 seconds)
Illuminate\Database\Events\MigrationsEnded {#1964}
"Finished migrating and --seed was requested, so do what you want here"
Database seeding completed successfully.
Related