/vendor/laravel/framework/src/Illuminate/Foundation/Console/VendorPublishCommand.php

https://gitlab.com/jjpa2018/dashboard · PHP · 288 lines · 182 code · 26 blank · 80 comment · 10 complexity · af4c38a6b6d9556b739fa7d28b485c8a MD5 · raw file

  1. <?php
  2. namespace Illuminate\Foundation\Console;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Filesystem\Filesystem;
  5. use Illuminate\Foundation\Events\VendorTagPublished;
  6. use Illuminate\Support\Arr;
  7. use Illuminate\Support\ServiceProvider;
  8. use League\Flysystem\Adapter\Local as LocalAdapter;
  9. use League\Flysystem\Filesystem as Flysystem;
  10. use League\Flysystem\MountManager;
  11. class VendorPublishCommand extends Command
  12. {
  13. /**
  14. * The filesystem instance.
  15. *
  16. * @var \Illuminate\Filesystem\Filesystem
  17. */
  18. protected $files;
  19. /**
  20. * The provider to publish.
  21. *
  22. * @var string
  23. */
  24. protected $provider = null;
  25. /**
  26. * The tags to publish.
  27. *
  28. * @var array
  29. */
  30. protected $tags = [];
  31. /**
  32. * The console command signature.
  33. *
  34. * @var string
  35. */
  36. protected $signature = 'vendor:publish {--force : Overwrite any existing files}
  37. {--all : Publish assets for all service providers without prompt}
  38. {--provider= : The service provider that has assets you want to publish}
  39. {--tag=* : One or many tags that have assets you want to publish}';
  40. /**
  41. * The console command description.
  42. *
  43. * @var string
  44. */
  45. protected $description = 'Publish any publishable assets from vendor packages';
  46. /**
  47. * Create a new command instance.
  48. *
  49. * @param \Illuminate\Filesystem\Filesystem $files
  50. * @return void
  51. */
  52. public function __construct(Filesystem $files)
  53. {
  54. parent::__construct();
  55. $this->files = $files;
  56. }
  57. /**
  58. * Execute the console command.
  59. *
  60. * @return void
  61. */
  62. public function handle()
  63. {
  64. $this->determineWhatShouldBePublished();
  65. foreach ($this->tags ?: [null] as $tag) {
  66. $this->publishTag($tag);
  67. }
  68. $this->info('Publishing complete.');
  69. }
  70. /**
  71. * Determine the provider or tag(s) to publish.
  72. *
  73. * @return void
  74. */
  75. protected function determineWhatShouldBePublished()
  76. {
  77. if ($this->option('all')) {
  78. return;
  79. }
  80. [$this->provider, $this->tags] = [
  81. $this->option('provider'), (array) $this->option('tag'),
  82. ];
  83. if (! $this->provider && ! $this->tags) {
  84. $this->promptForProviderOrTag();
  85. }
  86. }
  87. /**
  88. * Prompt for which provider or tag to publish.
  89. *
  90. * @return void
  91. */
  92. protected function promptForProviderOrTag()
  93. {
  94. $choice = $this->choice(
  95. "Which provider or tag's files would you like to publish?",
  96. $choices = $this->publishableChoices()
  97. );
  98. if ($choice == $choices[0] || is_null($choice)) {
  99. return;
  100. }
  101. $this->parseChoice($choice);
  102. }
  103. /**
  104. * The choices available via the prompt.
  105. *
  106. * @return array
  107. */
  108. protected function publishableChoices()
  109. {
  110. return array_merge(
  111. ['<comment>Publish files from all providers and tags listed below</comment>'],
  112. preg_filter('/^/', '<comment>Provider: </comment>', Arr::sort(ServiceProvider::publishableProviders())),
  113. preg_filter('/^/', '<comment>Tag: </comment>', Arr::sort(ServiceProvider::publishableGroups()))
  114. );
  115. }
  116. /**
  117. * Parse the answer that was given via the prompt.
  118. *
  119. * @param string $choice
  120. * @return void
  121. */
  122. protected function parseChoice($choice)
  123. {
  124. [$type, $value] = explode(': ', strip_tags($choice));
  125. if ($type === 'Provider') {
  126. $this->provider = $value;
  127. } elseif ($type === 'Tag') {
  128. $this->tags = [$value];
  129. }
  130. }
  131. /**
  132. * Publishes the assets for a tag.
  133. *
  134. * @param string $tag
  135. * @return mixed
  136. */
  137. protected function publishTag($tag)
  138. {
  139. $published = false;
  140. $pathsToPublish = $this->pathsToPublish($tag);
  141. foreach ($pathsToPublish as $from => $to) {
  142. $this->publishItem($from, $to);
  143. $published = true;
  144. }
  145. if ($published === false) {
  146. $this->comment('No publishable resources for tag ['.$tag.'].');
  147. } else {
  148. $this->laravel['events']->dispatch(new VendorTagPublished($tag, $pathsToPublish));
  149. }
  150. }
  151. /**
  152. * Get all of the paths to publish.
  153. *
  154. * @param string $tag
  155. * @return array
  156. */
  157. protected function pathsToPublish($tag)
  158. {
  159. return ServiceProvider::pathsToPublish(
  160. $this->provider, $tag
  161. );
  162. }
  163. /**
  164. * Publish the given item from and to the given location.
  165. *
  166. * @param string $from
  167. * @param string $to
  168. * @return void
  169. */
  170. protected function publishItem($from, $to)
  171. {
  172. if ($this->files->isFile($from)) {
  173. return $this->publishFile($from, $to);
  174. } elseif ($this->files->isDirectory($from)) {
  175. return $this->publishDirectory($from, $to);
  176. }
  177. $this->error("Can't locate path: <{$from}>");
  178. }
  179. /**
  180. * Publish the file to the given path.
  181. *
  182. * @param string $from
  183. * @param string $to
  184. * @return void
  185. */
  186. protected function publishFile($from, $to)
  187. {
  188. if (! $this->files->exists($to) || $this->option('force')) {
  189. $this->createParentDirectory(dirname($to));
  190. $this->files->copy($from, $to);
  191. $this->status($from, $to, 'File');
  192. }
  193. }
  194. /**
  195. * Publish the directory to the given directory.
  196. *
  197. * @param string $from
  198. * @param string $to
  199. * @return void
  200. */
  201. protected function publishDirectory($from, $to)
  202. {
  203. $this->moveManagedFiles(new MountManager([
  204. 'from' => new Flysystem(new LocalAdapter($from)),
  205. 'to' => new Flysystem(new LocalAdapter($to)),
  206. ]));
  207. $this->status($from, $to, 'Directory');
  208. }
  209. /**
  210. * Move all the files in the given MountManager.
  211. *
  212. * @param \League\Flysystem\MountManager $manager
  213. * @return void
  214. */
  215. protected function moveManagedFiles($manager)
  216. {
  217. foreach ($manager->listContents('from://', true) as $file) {
  218. if ($file['type'] === 'file' && (! $manager->has('to://'.$file['path']) || $this->option('force'))) {
  219. $manager->put('to://'.$file['path'], $manager->read('from://'.$file['path']));
  220. }
  221. }
  222. }
  223. /**
  224. * Create the directory to house the published files if needed.
  225. *
  226. * @param string $directory
  227. * @return void
  228. */
  229. protected function createParentDirectory($directory)
  230. {
  231. if (! $this->files->isDirectory($directory)) {
  232. $this->files->makeDirectory($directory, 0755, true);
  233. }
  234. }
  235. /**
  236. * Write a status message to the console.
  237. *
  238. * @param string $from
  239. * @param string $to
  240. * @param string $type
  241. * @return void
  242. */
  243. protected function status($from, $to, $type)
  244. {
  245. $from = str_replace(base_path(), '', realpath($from));
  246. $to = str_replace(base_path(), '', realpath($to));
  247. $this->line('<info>Copied '.$type.'</info> <comment>['.$from.']</comment> <info>To</info> <comment>['.$to.']</comment>');
  248. }
  249. }