diff --git a/src/Illuminate/Contracts/Database/Events/Migration.php b/src/Illuminate/Contracts/Database/Events/Migration.php new file mode 100644 index 000000000000..e8becbbbca3d --- /dev/null +++ b/src/Illuminate/Contracts/Database/Events/Migration.php @@ -0,0 +1,8 @@ +migration = $migration; + $this->direction = $direction; + } +} diff --git a/src/Illuminate/Database/Events/MigrationStarted.php b/src/Illuminate/Database/Events/MigrationStarted.php new file mode 100644 index 000000000000..3f206b4c826a --- /dev/null +++ b/src/Illuminate/Database/Events/MigrationStarted.php @@ -0,0 +1,8 @@ +app->singleton('migrator', function ($app) { $repository = $app['migration.repository']; - return new Migrator($repository, $app['db'], $app['files']); + return new Migrator($repository, $app['db'], $app['files'], $app['events']); }); } diff --git a/src/Illuminate/Database/Migrations/Migrator.php b/src/Illuminate/Database/Migrations/Migrator.php index 9689da90ee36..181e154994df 100755 --- a/src/Illuminate/Database/Migrations/Migrator.php +++ b/src/Illuminate/Database/Migrations/Migrator.php @@ -7,10 +7,22 @@ use Illuminate\Support\Collection; use Illuminate\Console\OutputStyle; use Illuminate\Filesystem\Filesystem; +use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Database\Events\MigrationEnded; +use Illuminate\Database\Events\MigrationsEnded; +use Illuminate\Database\Events\MigrationStarted; +use Illuminate\Database\Events\MigrationsStarted; use Illuminate\Database\ConnectionResolverInterface as Resolver; class Migrator { + /** + * The event dispatcher instance. + * + * @var \Illuminate\Contracts\Events\Dispatcher + */ + protected $events; + /** * The migration repository implementation. * @@ -59,13 +71,16 @@ class Migrator * @param \Illuminate\Database\Migrations\MigrationRepositoryInterface $repository * @param \Illuminate\Database\ConnectionResolverInterface $resolver * @param \Illuminate\Filesystem\Filesystem $files + * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher * @return void */ public function __construct(MigrationRepositoryInterface $repository, Resolver $resolver, - Filesystem $files) + Filesystem $files, + Dispatcher $dispatcher = null) { $this->files = $files; + $this->events = $dispatcher; $this->resolver = $resolver; $this->repository = $repository; } @@ -140,6 +155,8 @@ public function runPending(array $migrations, array $options = []) $step = $options['step'] ?? false; + $this->fireMigrationEvent(new MigrationsStarted); + // Once we have the array of migrations, we will spin through them and run the // migrations "up" so the changes are made to the databases. We'll then log // that the migration was run so we don't repeat it next time we execute. @@ -150,6 +167,8 @@ public function runPending(array $migrations, array $options = []) $batch++; } } + + $this->fireMigrationEvent(new MigrationsEnded); } /** @@ -239,6 +258,8 @@ protected function rollbackMigrations(array $migrations, $paths, array $options) $this->requireFiles($files = $this->getMigrationFiles($paths)); + $this->fireMigrationEvent(new MigrationsStarted); + // Next we will run through all of the migrations and call the "down" method // which will reverse each migration in order. This getLast method on the // repository already returns these migration's names in reverse order. @@ -259,6 +280,8 @@ protected function rollbackMigrations(array $migrations, $paths, array $options) ); } + $this->fireMigrationEvent(new MigrationsEnded); + return $rolledBack; } @@ -357,7 +380,11 @@ protected function runMigration($migration, $method) $callback = function () use ($migration, $method) { if (method_exists($migration, $method)) { + $this->fireMigrationEvent(new MigrationStarted($migration, $method)); + $migration->{$method}(); + + $this->fireMigrationEvent(new MigrationEnded($migration, $method)); } }; @@ -591,4 +618,17 @@ protected function note($message) $this->output->writeln($message); } } + + /** + * Fire the given event for the migration. + * + * @param \Illuminate\Contracts\Database\Events\Migration $event + * @return void + */ + public function fireMigrationEvent($event) + { + if ($this->events) { + $this->events->dispatch($event); + } + } } diff --git a/tests/Integration/Database/MigrateWithRealpathTest.php b/tests/Integration/Database/MigrateWithRealpathTest.php index bb117d452f26..00a031f131e8 100644 --- a/tests/Integration/Database/MigrateWithRealpathTest.php +++ b/tests/Integration/Database/MigrateWithRealpathTest.php @@ -2,7 +2,12 @@ namespace Illuminate\Tests\Integration\Database; +use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Events\MigrationEnded; +use Illuminate\Database\Events\MigrationsEnded; +use Illuminate\Database\Events\MigrationStarted; +use Illuminate\Database\Events\MigrationsStarted; class MigrateWithRealpathTest extends DatabaseTestCase { @@ -35,4 +40,27 @@ public function test_migrations_has_the_migrated_table() 'batch' => 1, ]); } + + public function test_migration_events_are_fired() + { + Event::fake(); + + Event::listen(MigrationsStarted::class, function ($event) { + return $this->assertInstanceOf(MigrationsStarted::class, $event); + }); + + Event::listen(MigrationsEnded::class, function ($event) { + return $this->assertInstanceOf(MigrationsEnded::class, $event); + }); + + Event::listen(MigrationStarted::class, function ($event) { + return $this->assertInstanceOf(MigrationStarted::class, $event); + }); + + Event::listen(MigrationEnded::class, function ($event) { + return $this->assertInstanceOf(MigrationEnded::class, $event); + }); + + $this->artisan('migrate'); + } }