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\Filesystem;
4
 
5
use Aws\S3\S3Client;
6
use Closure;
7
use Illuminate\Contracts\Filesystem\Factory as FactoryContract;
8
use Illuminate\Support\Arr;
9
use InvalidArgumentException;
10
use League\Flysystem\AwsS3V3\AwsS3V3Adapter as S3Adapter;
11
use League\Flysystem\AwsS3V3\PortableVisibilityConverter as AwsS3PortableVisibilityConverter;
12
use League\Flysystem\Filesystem as Flysystem;
13
use League\Flysystem\FilesystemAdapter as FlysystemAdapter;
14
use League\Flysystem\Ftp\FtpAdapter;
15
use League\Flysystem\Ftp\FtpConnectionOptions;
16
use League\Flysystem\Local\LocalFilesystemAdapter as LocalAdapter;
17
use League\Flysystem\PathPrefixing\PathPrefixedAdapter;
18
use League\Flysystem\PhpseclibV3\SftpAdapter;
19
use League\Flysystem\PhpseclibV3\SftpConnectionProvider;
20
use League\Flysystem\ReadOnly\ReadOnlyFilesystemAdapter;
21
use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
22
use League\Flysystem\Visibility;
23
 
24
/**
25
 * @mixin \Illuminate\Contracts\Filesystem\Filesystem
26
 * @mixin \Illuminate\Filesystem\FilesystemAdapter
27
 */
28
class FilesystemManager implements FactoryContract
29
{
30
    /**
31
     * The application instance.
32
     *
33
     * @var \Illuminate\Contracts\Foundation\Application
34
     */
35
    protected $app;
36
 
37
    /**
38
     * The array of resolved filesystem drivers.
39
     *
40
     * @var array
41
     */
42
    protected $disks = [];
43
 
44
    /**
45
     * The registered custom driver creators.
46
     *
47
     * @var array
48
     */
49
    protected $customCreators = [];
50
 
51
    /**
52
     * Create a new filesystem manager instance.
53
     *
54
     * @param  \Illuminate\Contracts\Foundation\Application  $app
55
     * @return void
56
     */
57
    public function __construct($app)
58
    {
59
        $this->app = $app;
60
    }
61
 
62
    /**
63
     * Get a filesystem instance.
64
     *
65
     * @param  string|null  $name
66
     * @return \Illuminate\Contracts\Filesystem\Filesystem
67
     */
68
    public function drive($name = null)
69
    {
70
        return $this->disk($name);
71
    }
72
 
73
    /**
74
     * Get a filesystem instance.
75
     *
76
     * @param  string|null  $name
77
     * @return \Illuminate\Contracts\Filesystem\Filesystem
78
     */
79
    public function disk($name = null)
80
    {
81
        $name = $name ?: $this->getDefaultDriver();
82
 
83
        return $this->disks[$name] = $this->get($name);
84
    }
85
 
86
    /**
87
     * Get a default cloud filesystem instance.
88
     *
89
     * @return \Illuminate\Contracts\Filesystem\Filesystem
90
     */
91
    public function cloud()
92
    {
93
        $name = $this->getDefaultCloudDriver();
94
 
95
        return $this->disks[$name] = $this->get($name);
96
    }
97
 
98
    /**
99
     * Build an on-demand disk.
100
     *
101
     * @param  string|array  $config
102
     * @return \Illuminate\Contracts\Filesystem\Filesystem
103
     */
104
    public function build($config)
105
    {
106
        return $this->resolve('ondemand', is_array($config) ? $config : [
107
            'driver' => 'local',
108
            'root' => $config,
109
        ]);
110
    }
111
 
112
    /**
113
     * Attempt to get the disk from the local cache.
114
     *
115
     * @param  string  $name
116
     * @return \Illuminate\Contracts\Filesystem\Filesystem
117
     */
118
    protected function get($name)
119
    {
120
        return $this->disks[$name] ?? $this->resolve($name);
121
    }
122
 
123
    /**
124
     * Resolve the given disk.
125
     *
126
     * @param  string  $name
127
     * @param  array|null  $config
128
     * @return \Illuminate\Contracts\Filesystem\Filesystem
129
     *
130
     * @throws \InvalidArgumentException
131
     */
132
    protected function resolve($name, $config = null)
133
    {
134
        $config ??= $this->getConfig($name);
135
 
136
        if (empty($config['driver'])) {
137
            throw new InvalidArgumentException("Disk [{$name}] does not have a configured driver.");
138
        }
139
 
140
        $name = $config['driver'];
141
 
142
        if (isset($this->customCreators[$name])) {
143
            return $this->callCustomCreator($config);
144
        }
145
 
146
        $driverMethod = 'create'.ucfirst($name).'Driver';
147
 
148
        if (! method_exists($this, $driverMethod)) {
149
            throw new InvalidArgumentException("Driver [{$name}] is not supported.");
150
        }
151
 
152
        return $this->{$driverMethod}($config);
153
    }
154
 
155
    /**
156
     * Call a custom driver creator.
157
     *
158
     * @param  array  $config
159
     * @return \Illuminate\Contracts\Filesystem\Filesystem
160
     */
161
    protected function callCustomCreator(array $config)
162
    {
163
        return $this->customCreators[$config['driver']]($this->app, $config);
164
    }
165
 
166
    /**
167
     * Create an instance of the local driver.
168
     *
169
     * @param  array  $config
170
     * @return \Illuminate\Contracts\Filesystem\Filesystem
171
     */
172
    public function createLocalDriver(array $config)
173
    {
174
        $visibility = PortableVisibilityConverter::fromArray(
175
            $config['permissions'] ?? [],
176
            $config['directory_visibility'] ?? $config['visibility'] ?? Visibility::PRIVATE
177
        );
178
 
179
        $links = ($config['links'] ?? null) === 'skip'
180
            ? LocalAdapter::SKIP_LINKS
181
            : LocalAdapter::DISALLOW_LINKS;
182
 
183
        $adapter = new LocalAdapter(
184
            $config['root'], $visibility, $config['lock'] ?? LOCK_EX, $links
185
        );
186
 
187
        return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config);
188
    }
189
 
190
    /**
191
     * Create an instance of the ftp driver.
192
     *
193
     * @param  array  $config
194
     * @return \Illuminate\Contracts\Filesystem\Filesystem
195
     */
196
    public function createFtpDriver(array $config)
197
    {
198
        if (! isset($config['root'])) {
199
            $config['root'] = '';
200
        }
201
 
202
        $adapter = new FtpAdapter(FtpConnectionOptions::fromArray($config));
203
 
204
        return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config);
205
    }
206
 
207
    /**
208
     * Create an instance of the sftp driver.
209
     *
210
     * @param  array  $config
211
     * @return \Illuminate\Contracts\Filesystem\Filesystem
212
     */
213
    public function createSftpDriver(array $config)
214
    {
215
        $provider = SftpConnectionProvider::fromArray($config);
216
 
217
        $root = $config['root'] ?? '/';
218
 
219
        $visibility = PortableVisibilityConverter::fromArray(
220
            $config['permissions'] ?? []
221
        );
222
 
223
        $adapter = new SftpAdapter($provider, $root, $visibility);
224
 
225
        return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config);
226
    }
227
 
228
    /**
229
     * Create an instance of the Amazon S3 driver.
230
     *
231
     * @param  array  $config
232
     * @return \Illuminate\Contracts\Filesystem\Cloud
233
     */
234
    public function createS3Driver(array $config)
235
    {
236
        $s3Config = $this->formatS3Config($config);
237
 
238
        $root = (string) ($s3Config['root'] ?? '');
239
 
240
        $visibility = new AwsS3PortableVisibilityConverter(
241
            $config['visibility'] ?? Visibility::PUBLIC
242
        );
243
 
244
        $streamReads = $s3Config['stream_reads'] ?? false;
245
 
246
        $client = new S3Client($s3Config);
247
 
248
        $adapter = new S3Adapter($client, $s3Config['bucket'], $root, $visibility, null, $config['options'] ?? [], $streamReads);
249
 
250
        return new AwsS3V3Adapter(
251
            $this->createFlysystem($adapter, $config), $adapter, $s3Config, $client
252
        );
253
    }
254
 
255
    /**
256
     * Format the given S3 configuration with the default options.
257
     *
258
     * @param  array  $config
259
     * @return array
260
     */
261
    protected function formatS3Config(array $config)
262
    {
263
        $config += ['version' => 'latest'];
264
 
265
        if (! empty($config['key']) && ! empty($config['secret'])) {
266
            $config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
267
        }
268
 
269
        return Arr::except($config, ['token']);
270
    }
271
 
272
    /**
273
     * Create a scoped driver.
274
     *
275
     * @param  array  $config
276
     * @return \Illuminate\Contracts\Filesystem\Filesystem
277
     */
278
    public function createScopedDriver(array $config)
279
    {
280
        if (empty($config['disk'])) {
281
            throw new InvalidArgumentException('Scoped disk is missing "disk" configuration option.');
282
        } elseif (empty($config['prefix'])) {
283
            throw new InvalidArgumentException('Scoped disk is missing "prefix" configuration option.');
284
        }
285
 
286
        return $this->build(tap(
287
            $this->getConfig($config['disk']),
288
            fn (&$parent) => $parent['prefix'] = $config['prefix']
289
        ));
290
    }
291
 
292
    /**
293
     * Create a Flysystem instance with the given adapter.
294
     *
295
     * @param  \League\Flysystem\FilesystemAdapter  $adapter
296
     * @param  array  $config
297
     * @return \League\Flysystem\FilesystemOperator
298
     */
299
    protected function createFlysystem(FlysystemAdapter $adapter, array $config)
300
    {
301
        if ($config['read-only'] ?? false === true) {
302
            $adapter = new ReadOnlyFilesystemAdapter($adapter);
303
        }
304
 
305
        if (! empty($config['prefix'])) {
306
            $adapter = new PathPrefixedAdapter($adapter, $config['prefix']);
307
        }
308
 
309
        return new Flysystem($adapter, Arr::only($config, [
310
            'directory_visibility',
311
            'disable_asserts',
312
            'temporary_url',
313
            'url',
314
            'visibility',
315
        ]));
316
    }
317
 
318
    /**
319
     * Set the given disk instance.
320
     *
321
     * @param  string  $name
322
     * @param  mixed  $disk
323
     * @return $this
324
     */
325
    public function set($name, $disk)
326
    {
327
        $this->disks[$name] = $disk;
328
 
329
        return $this;
330
    }
331
 
332
    /**
333
     * Get the filesystem connection configuration.
334
     *
335
     * @param  string  $name
336
     * @return array
337
     */
338
    protected function getConfig($name)
339
    {
340
        return $this->app['config']["filesystems.disks.{$name}"] ?: [];
341
    }
342
 
343
    /**
344
     * Get the default driver name.
345
     *
346
     * @return string
347
     */
348
    public function getDefaultDriver()
349
    {
350
        return $this->app['config']['filesystems.default'];
351
    }
352
 
353
    /**
354
     * Get the default cloud driver name.
355
     *
356
     * @return string
357
     */
358
    public function getDefaultCloudDriver()
359
    {
360
        return $this->app['config']['filesystems.cloud'] ?? 's3';
361
    }
362
 
363
    /**
364
     * Unset the given disk instances.
365
     *
366
     * @param  array|string  $disk
367
     * @return $this
368
     */
369
    public function forgetDisk($disk)
370
    {
371
        foreach ((array) $disk as $diskName) {
372
            unset($this->disks[$diskName]);
373
        }
374
 
375
        return $this;
376
    }
377
 
378
    /**
379
     * Disconnect the given disk and remove from local cache.
380
     *
381
     * @param  string|null  $name
382
     * @return void
383
     */
384
    public function purge($name = null)
385
    {
386
        $name ??= $this->getDefaultDriver();
387
 
388
        unset($this->disks[$name]);
389
    }
390
 
391
    /**
392
     * Register a custom driver creator Closure.
393
     *
394
     * @param  string  $driver
395
     * @param  \Closure  $callback
396
     * @return $this
397
     */
398
    public function extend($driver, Closure $callback)
399
    {
400
        $this->customCreators[$driver] = $callback;
401
 
402
        return $this;
403
    }
404
 
405
    /**
406
     * Set the application instance used by the manager.
407
     *
408
     * @param  \Illuminate\Contracts\Foundation\Application  $app
409
     * @return $this
410
     */
411
    public function setApplication($app)
412
    {
413
        $this->app = $app;
414
 
415
        return $this;
416
    }
417
 
418
    /**
419
     * Dynamically call the default driver instance.
420
     *
421
     * @param  string  $method
422
     * @param  array  $parameters
423
     * @return mixed
424
     */
425
    public function __call($method, $parameters)
426
    {
427
        return $this->disk()->$method(...$parameters);
428
    }
429
}