files = $files; $this->customStubPath = $customStubPath; } /** * Create a new migration at the given path. * * @param string $name * @param string $path * @param string|null $table * @param bool $create * @return string * * @throws \Exception */ public function create($name, $path, $table = null, $create = false) { $this->ensureMigrationDoesntAlreadyExist($name, $path); // First we will get the stub file for the migration, which serves as a type // of template for the migration. Once we have those we will populate the // various place-holders, save the file, and run the post create event. $stub = $this->getStub($table, $create); $path = $this->getPath($name, $path); $this->files->ensureDirectoryExists(dirname($path)); $this->files->put( $path, $this->populateStub($stub, $table) ); // Next, we will fire any hooks that are supposed to fire after a migration is // created. Once that is done we'll be ready to return the full path to the // migration file so it can be used however it's needed by the developer. $this->firePostCreateHooks($table, $path); return $path; } /** * Ensure that a migration with the given name doesn't already exist. * * @param string $name * @param string $migrationPath * @return void * * @throws \InvalidArgumentException */ protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = null) { if (! empty($migrationPath)) { $migrationFiles = $this->files->glob($migrationPath.'/*.php'); foreach ($migrationFiles as $migrationFile) { $this->files->requireOnce($migrationFile); } } if (class_exists($className = $this->getClassName($name))) { throw new InvalidArgumentException("A {$className} class already exists."); } } /** * Get the migration stub file. * * @param string|null $table * @param bool $create * @return string */ protected function getStub($table, $create) { if (is_null($table)) { $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub') ? $customPath : $this->stubPath().'/migration.stub'; } elseif ($create) { $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub') ? $customPath : $this->stubPath().'/migration.create.stub'; } else { $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.update.stub') ? $customPath : $this->stubPath().'/migration.update.stub'; } return $this->files->get($stub); } /** * Populate the place-holders in the migration stub. * * @param string $stub * @param string|null $table * @return string */ protected function populateStub($stub, $table) { // Here we will replace the table place-holders with the table specified by // the developer, which is useful for quickly creating a tables creation // or update migration from the console instead of typing it manually. if (! is_null($table)) { $stub = str_replace( ['DummyTable', '{{ table }}', '{{table}}'], $table, $stub ); } return $stub; } /** * Get the class name of a migration name. * * @param string $name * @return string */ protected function getClassName($name) { return Str::studly($name); } /** * Get the full path to the migration. * * @param string $name * @param string $path * @return string */ protected function getPath($name, $path) { return $path.'/'.$this->getDatePrefix().'_'.$name.'.php'; } /** * Fire the registered post create hooks. * * @param string|null $table * @param string $path * @return void */ protected function firePostCreateHooks($table, $path) { foreach ($this->postCreate as $callback) { $callback($table, $path); } } /** * Register a post migration create hook. * * @param \Closure $callback * @return void */ public function afterCreate(Closure $callback) { $this->postCreate[] = $callback; } /** * Get the date prefix for the migration. * * @return string */ protected function getDatePrefix() { return date('Y_m_d_His'); } /** * Get the path to the stubs. * * @return string */ public function stubPath() { return __DIR__.'/stubs'; } /** * Get the filesystem instance. * * @return \Illuminate\Filesystem\Filesystem */ public function getFilesystem() { return $this->files; } }