files = $files; } /** * Execute the console command. * * @return void */ public function handle() { $this->determineWhatShouldBePublished(); foreach ($this->tags ?: [null] as $tag) { $this->publishTag($tag); } $this->info('Publishing complete.'); } /** * Determine the provider or tag(s) to publish. * * @return void */ protected function determineWhatShouldBePublished() { if ($this->option('all')) { return; } list($this->provider, $this->tags) = [ $this->option('provider'), (array) $this->option('tag'), ]; if (! $this->provider && ! $this->tags) { $this->promptForProviderOrTag(); } } /** * Prompt for which provider or tag to publish. * * @return void */ protected function promptForProviderOrTag() { $choice = $this->choice( "Which provider or tag's files would you like to publish?", $choices = $this->publishableChoices() ); if ($choice == $choices[0] || is_null($choice)) { return; } $this->parseChoice($choice); } /** * The choices available via the prompt. * * @return array */ protected function publishableChoices() { return array_merge( ['Publish files from all providers and tags listed below'], preg_filter('/^/', 'Provider: ', Arr::sort(ServiceProvider::publishableProviders())), preg_filter('/^/', 'Tag: ', Arr::sort(ServiceProvider::publishableGroups())) ); } /** * Parse the answer that was given via the prompt. * * @param string $choice * @return void */ protected function parseChoice($choice) { list($type, $value) = explode(': ', strip_tags($choice)); if ($type == 'Provider') { $this->provider = $value; } elseif ($type == 'Tag') { $this->tags = [$value]; } } /** * Publishes the assets for a tag. * * @param string $tag * @return mixed */ protected function publishTag($tag) { foreach ($this->pathsToPublish($tag) as $from => $to) { $this->publishItem($from, $to); } } /** * Get all of the paths to publish. * * @param string $tag * @return array */ protected function pathsToPublish($tag) { return ServiceProvider::pathsToPublish( $this->provider, $tag ); } /** * Publish the given item from and to the given location. * * @param string $from * @param string $to * @return void */ protected function publishItem($from, $to) { if ($this->files->isFile($from)) { return $this->publishFile($from, $to); } elseif ($this->files->isDirectory($from)) { return $this->publishDirectory($from, $to); } $this->error("Can't locate path: <{$from}>"); } /** * Publish the file to the given path. * * @param string $from * @param string $to * @return void */ protected function publishFile($from, $to) { if (! $this->files->exists($to) || $this->option('force')) { $this->createParentDirectory(dirname($to)); $this->files->copy($from, $to); $this->status($from, $to, 'File'); } } /** * Publish the directory to the given directory. * * @param string $from * @param string $to * @return void */ protected function publishDirectory($from, $to) { $this->moveManagedFiles(new MountManager([ 'from' => new Flysystem(new LocalAdapter($from)), 'to' => new Flysystem(new LocalAdapter($to)), ])); $this->status($from, $to, 'Directory'); } /** * Move all the files in the given MountManager. * * @param \League\Flysystem\MountManager $manager * @return void */ protected function moveManagedFiles($manager) { foreach ($manager->listContents('from://', true) as $file) { if ($file['type'] === 'file' && (! $manager->has('to://'.$file['path']) || $this->option('force'))) { $manager->put('to://'.$file['path'], $manager->read('from://'.$file['path'])); } } } /** * Create the directory to house the published files if needed. * * @param string $directory * @return void */ protected function createParentDirectory($directory) { if (! $this->files->isDirectory($directory)) { $this->files->makeDirectory($directory, 0755, true); } } /** * Write a status message to the console. * * @param string $from * @param string $to * @param string $type * @return void */ protected function status($from, $to, $type) { $from = str_replace(base_path(), '', realpath($from)); $to = str_replace(base_path(), '', realpath($to)); $this->line('Copied '.$type.' ['.$from.'] To ['.$to.']'); } }