Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Foundation\Console;
4
 
5
use Illuminate\Console\Command;
6
use Illuminate\Filesystem\Filesystem;
7
use Illuminate\Foundation\Events\VendorTagPublished;
8
use Illuminate\Support\Arr;
9
use Illuminate\Support\ServiceProvider;
10
use Illuminate\Support\Str;
11
use League\Flysystem\Filesystem as Flysystem;
12
use League\Flysystem\Local\LocalFilesystemAdapter as LocalAdapter;
13
use League\Flysystem\MountManager;
14
use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
15
use League\Flysystem\Visibility;
16
use Symfony\Component\Console\Attribute\AsCommand;
17
 
18
#[AsCommand(name: 'vendor:publish')]
19
class VendorPublishCommand extends Command
20
{
21
    /**
22
     * The filesystem instance.
23
     *
24
     * @var \Illuminate\Filesystem\Filesystem
25
     */
26
    protected $files;
27
 
28
    /**
29
     * The provider to publish.
30
     *
31
     * @var string
32
     */
33
    protected $provider = null;
34
 
35
    /**
36
     * The tags to publish.
37
     *
38
     * @var array
39
     */
40
    protected $tags = [];
41
 
42
    /**
43
     * The console command signature.
44
     *
45
     * @var string
46
     */
47
    protected $signature = 'vendor:publish
48
                    {--existing : Publish and overwrite only the files that have already been published}
49
                    {--force : Overwrite any existing files}
50
                    {--all : Publish assets for all service providers without prompt}
51
                    {--provider= : The service provider that has assets you want to publish}
52
                    {--tag=* : One or many tags that have assets you want to publish}';
53
 
54
    /**
55
     * The name of the console command.
56
     *
57
     * This name is used to identify the command during lazy loading.
58
     *
59
     * @var string|null
60
     *
61
     * @deprecated
62
     */
63
    protected static $defaultName = 'vendor:publish';
64
 
65
    /**
66
     * The console command description.
67
     *
68
     * @var string
69
     */
70
    protected $description = 'Publish any publishable assets from vendor packages';
71
 
72
    /**
73
     * Create a new command instance.
74
     *
75
     * @param  \Illuminate\Filesystem\Filesystem  $files
76
     * @return void
77
     */
78
    public function __construct(Filesystem $files)
79
    {
80
        parent::__construct();
81
 
82
        $this->files = $files;
83
    }
84
 
85
    /**
86
     * Execute the console command.
87
     *
88
     * @return void
89
     */
90
    public function handle()
91
    {
92
        $this->determineWhatShouldBePublished();
93
 
94
        foreach ($this->tags ?: [null] as $tag) {
95
            $this->publishTag($tag);
96
        }
97
    }
98
 
99
    /**
100
     * Determine the provider or tag(s) to publish.
101
     *
102
     * @return void
103
     */
104
    protected function determineWhatShouldBePublished()
105
    {
106
        if ($this->option('all')) {
107
            return;
108
        }
109
 
110
        [$this->provider, $this->tags] = [
111
            $this->option('provider'), (array) $this->option('tag'),
112
        ];
113
 
114
        if (! $this->provider && ! $this->tags) {
115
            $this->promptForProviderOrTag();
116
        }
117
    }
118
 
119
    /**
120
     * Prompt for which provider or tag to publish.
121
     *
122
     * @return void
123
     */
124
    protected function promptForProviderOrTag()
125
    {
126
        $choice = $this->components->choice(
127
            "Which provider or tag's files would you like to publish?",
128
            $choices = $this->publishableChoices()
129
        );
130
 
131
        if ($choice == $choices[0] || is_null($choice)) {
132
            return;
133
        }
134
 
135
        $this->parseChoice($choice);
136
    }
137
 
138
    /**
139
     * The choices available via the prompt.
140
     *
141
     * @return array
142
     */
143
    protected function publishableChoices()
144
    {
145
        return array_merge(
146
            ['<comment>Publish files from all providers and tags listed below</comment>'],
147
            preg_filter('/^/', '<fg=gray>Provider:</> ', Arr::sort(ServiceProvider::publishableProviders())),
148
            preg_filter('/^/', '<fg=gray>Tag:</> ', Arr::sort(ServiceProvider::publishableGroups()))
149
        );
150
    }
151
 
152
    /**
153
     * Parse the answer that was given via the prompt.
154
     *
155
     * @param  string  $choice
156
     * @return void
157
     */
158
    protected function parseChoice($choice)
159
    {
160
        [$type, $value] = explode(': ', strip_tags($choice));
161
 
162
        if ($type === 'Provider') {
163
            $this->provider = $value;
164
        } elseif ($type === 'Tag') {
165
            $this->tags = [$value];
166
        }
167
    }
168
 
169
    /**
170
     * Publishes the assets for a tag.
171
     *
172
     * @param  string  $tag
173
     * @return mixed
174
     */
175
    protected function publishTag($tag)
176
    {
177
        $published = false;
178
 
179
        $pathsToPublish = $this->pathsToPublish($tag);
180
 
181
        if ($publishing = count($pathsToPublish) > 0) {
182
            $this->components->info(sprintf(
183
                'Publishing %sassets',
184
                $tag ? "[$tag] " : '',
185
            ));
186
        }
187
 
188
        foreach ($pathsToPublish as $from => $to) {
189
            $this->publishItem($from, $to);
190
        }
191
 
192
        if ($publishing === false) {
193
            $this->components->info('No publishable resources for tag ['.$tag.'].');
194
        } else {
195
            $this->laravel['events']->dispatch(new VendorTagPublished($tag, $pathsToPublish));
196
 
197
            $this->newLine();
198
        }
199
    }
200
 
201
    /**
202
     * Get all of the paths to publish.
203
     *
204
     * @param  string  $tag
205
     * @return array
206
     */
207
    protected function pathsToPublish($tag)
208
    {
209
        return ServiceProvider::pathsToPublish(
210
            $this->provider, $tag
211
        );
212
    }
213
 
214
    /**
215
     * Publish the given item from and to the given location.
216
     *
217
     * @param  string  $from
218
     * @param  string  $to
219
     * @return void
220
     */
221
    protected function publishItem($from, $to)
222
    {
223
        if ($this->files->isFile($from)) {
224
            return $this->publishFile($from, $to);
225
        } elseif ($this->files->isDirectory($from)) {
226
            return $this->publishDirectory($from, $to);
227
        }
228
 
229
        $this->components->error("Can't locate path: <{$from}>");
230
    }
231
 
232
    /**
233
     * Publish the file to the given path.
234
     *
235
     * @param  string  $from
236
     * @param  string  $to
237
     * @return void
238
     */
239
    protected function publishFile($from, $to)
240
    {
241
        if ((! $this->option('existing') && (! $this->files->exists($to) || $this->option('force')))
242
            || ($this->option('existing') && $this->files->exists($to))) {
243
            $this->createParentDirectory(dirname($to));
244
 
245
            $this->files->copy($from, $to);
246
 
247
            $this->status($from, $to, 'file');
248
        } else {
249
            if ($this->option('existing')) {
250
                $this->components->twoColumnDetail(sprintf(
251
                    'File [%s] does not exist',
252
                    str_replace(base_path().'/', '', $to),
253
                ), '<fg=yellow;options=bold>SKIPPED</>');
254
            } else {
255
                $this->components->twoColumnDetail(sprintf(
256
                    'File [%s] already exists',
257
                    str_replace(base_path().'/', '', realpath($to)),
258
                ), '<fg=yellow;options=bold>SKIPPED</>');
259
            }
260
        }
261
    }
262
 
263
    /**
264
     * Publish the directory to the given directory.
265
     *
266
     * @param  string  $from
267
     * @param  string  $to
268
     * @return void
269
     */
270
    protected function publishDirectory($from, $to)
271
    {
272
        $visibility = PortableVisibilityConverter::fromArray([], Visibility::PUBLIC);
273
 
274
        $this->moveManagedFiles(new MountManager([
275
            'from' => new Flysystem(new LocalAdapter($from)),
276
            'to' => new Flysystem(new LocalAdapter($to, $visibility)),
277
        ]));
278
 
279
        $this->status($from, $to, 'directory');
280
    }
281
 
282
    /**
283
     * Move all the files in the given MountManager.
284
     *
285
     * @param  \League\Flysystem\MountManager  $manager
286
     * @return void
287
     */
288
    protected function moveManagedFiles($manager)
289
    {
290
        foreach ($manager->listContents('from://', true) as $file) {
291
            $path = Str::after($file['path'], 'from://');
292
 
293
            if (
294
                $file['type'] === 'file'
295
                && (
296
                    (! $this->option('existing') && (! $manager->fileExists('to://'.$path) || $this->option('force')))
297
                    || ($this->option('existing') && $manager->fileExists('to://'.$path))
298
                )
299
            ) {
300
                $manager->write('to://'.$path, $manager->read($file['path']));
301
            }
302
        }
303
    }
304
 
305
    /**
306
     * Create the directory to house the published files if needed.
307
     *
308
     * @param  string  $directory
309
     * @return void
310
     */
311
    protected function createParentDirectory($directory)
312
    {
313
        if (! $this->files->isDirectory($directory)) {
314
            $this->files->makeDirectory($directory, 0755, true);
315
        }
316
    }
317
 
318
    /**
319
     * Write a status message to the console.
320
     *
321
     * @param  string  $from
322
     * @param  string  $to
323
     * @param  string  $type
324
     * @return void
325
     */
326
    protected function status($from, $to, $type)
327
    {
328
        $from = str_replace(base_path().'/', '', realpath($from));
329
 
330
        $to = str_replace(base_path().'/', '', realpath($to));
331
 
332
        $this->components->task(sprintf(
333
            'Copying %s [%s] to [%s]',
334
            $type,
335
            $from,
336
            $to,
337
        ));
338
    }
339
}