1<?php
2
3namespace Illuminate\Database;
4
5use Illuminate\Contracts\Events\Dispatcher;
6use Illuminate\Contracts\Support\DeferrableProvider;
7use Illuminate\Database\Console\Migrations\FreshCommand;
8use Illuminate\Database\Console\Migrations\InstallCommand;
9use Illuminate\Database\Console\Migrations\MigrateCommand;
10use Illuminate\Database\Console\Migrations\MigrateMakeCommand;
11use Illuminate\Database\Console\Migrations\RefreshCommand;
12use Illuminate\Database\Console\Migrations\ResetCommand;
13use Illuminate\Database\Console\Migrations\RollbackCommand;
14use Illuminate\Database\Console\Migrations\StatusCommand;
15use Illuminate\Database\Migrations\DatabaseMigrationRepository;
16use Illuminate\Database\Migrations\MigrationCreator;
17use Illuminate\Database\Migrations\Migrator;
18use Illuminate\Support\ServiceProvider;
19
20class MigrationServiceProvider extends ServiceProvider implements DeferrableProvider
21{
22    /**
23     * The commands to be registered.
24     *
25     * @var array
26     */
27    protected $commands = [
28        'Migrate' => 'command.migrate',
29        'MigrateFresh' => 'command.migrate.fresh',
30        'MigrateInstall' => 'command.migrate.install',
31        'MigrateRefresh' => 'command.migrate.refresh',
32        'MigrateReset' => 'command.migrate.reset',
33        'MigrateRollback' => 'command.migrate.rollback',
34        'MigrateStatus' => 'command.migrate.status',
35        'MigrateMake' => 'command.migrate.make',
36    ];
37
38    /**
39     * Register the service provider.
40     *
41     * @return void
42     */
43    public function register()
44    {
45        $this->registerRepository();
46
47        $this->registerMigrator();
48
49        $this->registerCreator();
50
51        $this->registerCommands($this->commands);
52    }
53
54    /**
55     * Register the migration repository service.
56     *
57     * @return void
58     */
59    protected function registerRepository()
60    {
61        $this->app->singleton('migration.repository', function ($app) {
62            $table = $app['config']['database.migrations'];
63
64            return new DatabaseMigrationRepository($app['db'], $table);
65        });
66    }
67
68    /**
69     * Register the migrator service.
70     *
71     * @return void
72     */
73    protected function registerMigrator()
74    {
75        // The migrator is responsible for actually running and rollback the migration
76        // files in the application. We'll pass in our database connection resolver
77        // so the migrator can resolve any of these connections when it needs to.
78        $this->app->singleton('migrator', function ($app) {
79            $repository = $app['migration.repository'];
80
81            return new Migrator($repository, $app['db'], $app['files'], $app['events']);
82        });
83    }
84
85    /**
86     * Register the migration creator.
87     *
88     * @return void
89     */
90    protected function registerCreator()
91    {
92        $this->app->singleton('migration.creator', function ($app) {
93            return new MigrationCreator($app['files'], $app->basePath('stubs'));
94        });
95    }
96
97    /**
98     * Register the given commands.
99     *
100     * @param  array  $commands
101     * @return void
102     */
103    protected function registerCommands(array $commands)
104    {
105        foreach (array_keys($commands) as $command) {
106            $this->{"register{$command}Command"}();
107        }
108
109        $this->commands(array_values($commands));
110    }
111
112    /**
113     * Register the command.
114     *
115     * @return void
116     */
117    protected function registerMigrateCommand()
118    {
119        $this->app->singleton('command.migrate', function ($app) {
120            return new MigrateCommand($app['migrator'], $app[Dispatcher::class]);
121        });
122    }
123
124    /**
125     * Register the command.
126     *
127     * @return void
128     */
129    protected function registerMigrateFreshCommand()
130    {
131        $this->app->singleton('command.migrate.fresh', function () {
132            return new FreshCommand;
133        });
134    }
135
136    /**
137     * Register the command.
138     *
139     * @return void
140     */
141    protected function registerMigrateInstallCommand()
142    {
143        $this->app->singleton('command.migrate.install', function ($app) {
144            return new InstallCommand($app['migration.repository']);
145        });
146    }
147
148    /**
149     * Register the command.
150     *
151     * @return void
152     */
153    protected function registerMigrateMakeCommand()
154    {
155        $this->app->singleton('command.migrate.make', function ($app) {
156            // Once we have the migration creator registered, we will create the command
157            // and inject the creator. The creator is responsible for the actual file
158            // creation of the migrations, and may be extended by these developers.
159            $creator = $app['migration.creator'];
160
161            $composer = $app['composer'];
162
163            return new MigrateMakeCommand($creator, $composer);
164        });
165    }
166
167    /**
168     * Register the command.
169     *
170     * @return void
171     */
172    protected function registerMigrateRefreshCommand()
173    {
174        $this->app->singleton('command.migrate.refresh', function () {
175            return new RefreshCommand;
176        });
177    }
178
179    /**
180     * Register the command.
181     *
182     * @return void
183     */
184    protected function registerMigrateResetCommand()
185    {
186        $this->app->singleton('command.migrate.reset', function ($app) {
187            return new ResetCommand($app['migrator']);
188        });
189    }
190
191    /**
192     * Register the command.
193     *
194     * @return void
195     */
196    protected function registerMigrateRollbackCommand()
197    {
198        $this->app->singleton('command.migrate.rollback', function ($app) {
199            return new RollbackCommand($app['migrator']);
200        });
201    }
202
203    /**
204     * Register the command.
205     *
206     * @return void
207     */
208    protected function registerMigrateStatusCommand()
209    {
210        $this->app->singleton('command.migrate.status', function ($app) {
211            return new StatusCommand($app['migrator']);
212        });
213    }
214
215    /**
216     * Get the services provided by the provider.
217     *
218     * @return array
219     */
220    public function provides()
221    {
222        return array_merge([
223            'migrator', 'migration.repository', 'migration.creator',
224        ], array_values($this->commands));
225    }
226}
227