MigrationCreator.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?php
  2. namespace Illuminate\Database\Migrations;
  3. use Closure;
  4. use Illuminate\Filesystem\Filesystem;
  5. use Illuminate\Support\Str;
  6. use InvalidArgumentException;
  7. class MigrationCreator
  8. {
  9. /**
  10. * The filesystem instance.
  11. *
  12. * @var \Illuminate\Filesystem\Filesystem
  13. */
  14. protected $files;
  15. /**
  16. * The custom app stubs directory.
  17. *
  18. * @var string
  19. */
  20. protected $customStubPath;
  21. /**
  22. * The registered post create hooks.
  23. *
  24. * @var array
  25. */
  26. protected $postCreate = [];
  27. /**
  28. * Create a new migration creator instance.
  29. *
  30. * @param \Illuminate\Filesystem\Filesystem $files
  31. * @param string $customStubPath
  32. * @return void
  33. */
  34. public function __construct(Filesystem $files, $customStubPath)
  35. {
  36. $this->files = $files;
  37. $this->customStubPath = $customStubPath;
  38. }
  39. /**
  40. * Create a new migration at the given path.
  41. *
  42. * @param string $name
  43. * @param string $path
  44. * @param string|null $table
  45. * @param bool $create
  46. * @return string
  47. *
  48. * @throws \Exception
  49. */
  50. public function create($name, $path, $table = null, $create = false)
  51. {
  52. $this->ensureMigrationDoesntAlreadyExist($name, $path);
  53. // First we will get the stub file for the migration, which serves as a type
  54. // of template for the migration. Once we have those we will populate the
  55. // various place-holders, save the file, and run the post create event.
  56. $stub = $this->getStub($table, $create);
  57. $path = $this->getPath($name, $path);
  58. $this->files->ensureDirectoryExists(dirname($path));
  59. $this->files->put(
  60. $path, $this->populateStub($stub, $table)
  61. );
  62. // Next, we will fire any hooks that are supposed to fire after a migration is
  63. // created. Once that is done we'll be ready to return the full path to the
  64. // migration file so it can be used however it's needed by the developer.
  65. $this->firePostCreateHooks($table, $path);
  66. return $path;
  67. }
  68. /**
  69. * Ensure that a migration with the given name doesn't already exist.
  70. *
  71. * @param string $name
  72. * @param string $migrationPath
  73. * @return void
  74. *
  75. * @throws \InvalidArgumentException
  76. */
  77. protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = null)
  78. {
  79. if (! empty($migrationPath)) {
  80. $migrationFiles = $this->files->glob($migrationPath.'/*.php');
  81. foreach ($migrationFiles as $migrationFile) {
  82. $this->files->requireOnce($migrationFile);
  83. }
  84. }
  85. if (class_exists($className = $this->getClassName($name))) {
  86. throw new InvalidArgumentException("A {$className} class already exists.");
  87. }
  88. }
  89. /**
  90. * Get the migration stub file.
  91. *
  92. * @param string|null $table
  93. * @param bool $create
  94. * @return string
  95. */
  96. protected function getStub($table, $create)
  97. {
  98. if (is_null($table)) {
  99. $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub')
  100. ? $customPath
  101. : $this->stubPath().'/migration.stub';
  102. } elseif ($create) {
  103. $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub')
  104. ? $customPath
  105. : $this->stubPath().'/migration.create.stub';
  106. } else {
  107. $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.update.stub')
  108. ? $customPath
  109. : $this->stubPath().'/migration.update.stub';
  110. }
  111. return $this->files->get($stub);
  112. }
  113. /**
  114. * Populate the place-holders in the migration stub.
  115. *
  116. * @param string $stub
  117. * @param string|null $table
  118. * @return string
  119. */
  120. protected function populateStub($stub, $table)
  121. {
  122. // Here we will replace the table place-holders with the table specified by
  123. // the developer, which is useful for quickly creating a tables creation
  124. // or update migration from the console instead of typing it manually.
  125. if (! is_null($table)) {
  126. $stub = str_replace(
  127. ['DummyTable', '{{ table }}', '{{table}}'],
  128. $table, $stub
  129. );
  130. }
  131. return $stub;
  132. }
  133. /**
  134. * Get the class name of a migration name.
  135. *
  136. * @param string $name
  137. * @return string
  138. */
  139. protected function getClassName($name)
  140. {
  141. return Str::studly($name);
  142. }
  143. /**
  144. * Get the full path to the migration.
  145. *
  146. * @param string $name
  147. * @param string $path
  148. * @return string
  149. */
  150. protected function getPath($name, $path)
  151. {
  152. return $path.'/'.$this->getDatePrefix().'_'.$name.'.php';
  153. }
  154. /**
  155. * Fire the registered post create hooks.
  156. *
  157. * @param string|null $table
  158. * @param string $path
  159. * @return void
  160. */
  161. protected function firePostCreateHooks($table, $path)
  162. {
  163. foreach ($this->postCreate as $callback) {
  164. $callback($table, $path);
  165. }
  166. }
  167. /**
  168. * Register a post migration create hook.
  169. *
  170. * @param \Closure $callback
  171. * @return void
  172. */
  173. public function afterCreate(Closure $callback)
  174. {
  175. $this->postCreate[] = $callback;
  176. }
  177. /**
  178. * Get the date prefix for the migration.
  179. *
  180. * @return string
  181. */
  182. protected function getDatePrefix()
  183. {
  184. return date('Y_m_d_His');
  185. }
  186. /**
  187. * Get the path to the stubs.
  188. *
  189. * @return string
  190. */
  191. public function stubPath()
  192. {
  193. return __DIR__.'/stubs';
  194. }
  195. /**
  196. * Get the filesystem instance.
  197. *
  198. * @return \Illuminate\Filesystem\Filesystem
  199. */
  200. public function getFilesystem()
  201. {
  202. return $this->files;
  203. }
  204. }