Vous êtes connecté en tant que anonymous Se Deconnecter
Browse code

Application modulaire fonctionnelle !

Emmanuel ROY authored on 12/08/2019 15:10:25
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,744 +0,0 @@
1
-<?php
2
-
3
-namespace Illuminate\Filesystem;
4
-
5
-use RuntimeException;
6
-use Illuminate\Http\File;
7
-use Illuminate\Support\Arr;
8
-use Illuminate\Support\Str;
9
-use InvalidArgumentException;
10
-use Illuminate\Support\Carbon;
11
-use Illuminate\Http\UploadedFile;
12
-use Illuminate\Support\Collection;
13
-use League\Flysystem\AdapterInterface;
14
-use PHPUnit\Framework\Assert as PHPUnit;
15
-use League\Flysystem\FileExistsException;
16
-use League\Flysystem\FilesystemInterface;
17
-use League\Flysystem\AwsS3v3\AwsS3Adapter;
18
-use League\Flysystem\Cached\CachedAdapter;
19
-use League\Flysystem\FileNotFoundException;
20
-use League\Flysystem\Rackspace\RackspaceAdapter;
21
-use League\Flysystem\Adapter\Local as LocalAdapter;
22
-use Symfony\Component\HttpFoundation\StreamedResponse;
23
-use Illuminate\Contracts\Filesystem\Cloud as CloudFilesystemContract;
24
-use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract;
25
-use Illuminate\Contracts\Filesystem\FileExistsException as ContractFileExistsException;
26
-use Illuminate\Contracts\Filesystem\FileNotFoundException as ContractFileNotFoundException;
27
-
28
-/**
29
- * @mixin \League\Flysystem\FilesystemInterface
30
- */
31
-class FilesystemAdapter implements FilesystemContract, CloudFilesystemContract
32
-{
33
-    /**
34
-     * The Flysystem filesystem implementation.
35
-     *
36
-     * @var \League\Flysystem\FilesystemInterface
37
-     */
38
-    protected $driver;
39
-
40
-    /**
41
-     * Create a new filesystem adapter instance.
42
-     *
43
-     * @param  \League\Flysystem\FilesystemInterface  $driver
44
-     * @return void
45
-     */
46
-    public function __construct(FilesystemInterface $driver)
47
-    {
48
-        $this->driver = $driver;
49
-    }
50
-
51
-    /**
52
-     * Assert that the given file exists.
53
-     *
54
-     * @param  string|array  $path
55
-     * @return $this
56
-     */
57
-    public function assertExists($path)
58
-    {
59
-        $paths = Arr::wrap($path);
60
-
61
-        foreach ($paths as $path) {
62
-            PHPUnit::assertTrue(
63
-                $this->exists($path), "Unable to find a file at path [{$path}]."
64
-            );
65
-        }
66
-
67
-        return $this;
68
-    }
69
-
70
-    /**
71
-     * Assert that the given file does not exist.
72
-     *
73
-     * @param  string|array  $path
74
-     * @return $this
75
-     */
76
-    public function assertMissing($path)
77
-    {
78
-        $paths = Arr::wrap($path);
79
-
80
-        foreach ($paths as $path) {
81
-            PHPUnit::assertFalse(
82
-                $this->exists($path), "Found unexpected file at path [{$path}]."
83
-            );
84
-        }
85
-
86
-        return $this;
87
-    }
88
-
89
-    /**
90
-     * Determine if a file exists.
91
-     *
92
-     * @param  string  $path
93
-     * @return bool
94
-     */
95
-    public function exists($path)
96
-    {
97
-        return $this->driver->has($path);
98
-    }
99
-
100
-    /**
101
-     * Get the full path for the file at the given "short" path.
102
-     *
103
-     * @param  string  $path
104
-     * @return string
105
-     */
106
-    public function path($path)
107
-    {
108
-        return $this->driver->getAdapter()->getPathPrefix().$path;
109
-    }
110
-
111
-    /**
112
-     * Get the contents of a file.
113
-     *
114
-     * @param  string  $path
115
-     * @return string
116
-     *
117
-     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
118
-     */
119
-    public function get($path)
120
-    {
121
-        try {
122
-            return $this->driver->read($path);
123
-        } catch (FileNotFoundException $e) {
124
-            throw new ContractFileNotFoundException($path, $e->getCode(), $e);
125
-        }
126
-    }
127
-
128
-    /**
129
-     * Create a streamed response for a given file.
130
-     *
131
-     * @param  string  $path
132
-     * @param  string|null  $name
133
-     * @param  array|null  $headers
134
-     * @param  string|null  $disposition
135
-     * @return \Symfony\Component\HttpFoundation\StreamedResponse
136
-     */
137
-    public function response($path, $name = null, array $headers = [], $disposition = 'inline')
138
-    {
139
-        $response = new StreamedResponse;
140
-
141
-        $filename = $name ?? basename($path);
142
-
143
-        $disposition = $response->headers->makeDisposition(
144
-            $disposition, $filename, $this->fallbackName($filename)
145
-        );
146
-
147
-        $response->headers->replace($headers + [
148
-            'Content-Type' => $this->mimeType($path),
149
-            'Content-Length' => $this->size($path),
150
-            'Content-Disposition' => $disposition,
151
-        ]);
152
-
153
-        $response->setCallback(function () use ($path) {
154
-            $stream = $this->readStream($path);
155
-            fpassthru($stream);
156
-            fclose($stream);
157
-        });
158
-
159
-        return $response;
160
-    }
161
-
162
-    /**
163
-     * Create a streamed download response for a given file.
164
-     *
165
-     * @param  string  $path
166
-     * @param  string|null  $name
167
-     * @param  array|null  $headers
168
-     * @return \Symfony\Component\HttpFoundation\StreamedResponse
169
-     */
170
-    public function download($path, $name = null, array $headers = [])
171
-    {
172
-        return $this->response($path, $name, $headers, 'attachment');
173
-    }
174
-
175
-    /**
176
-     * Convert the string to ASCII characters that are equivalent to the given name.
177
-     *
178
-     * @param  string  $name
179
-     * @return string
180
-     */
181
-    protected function fallbackName($name)
182
-    {
183
-        return str_replace('%', '', Str::ascii($name));
184
-    }
185
-
186
-    /**
187
-     * Write the contents of a file.
188
-     *
189
-     * @param  string  $path
190
-     * @param  string|resource  $contents
191
-     * @param  mixed  $options
192
-     * @return bool
193
-     */
194
-    public function put($path, $contents, $options = [])
195
-    {
196
-        $options = is_string($options)
197
-                     ? ['visibility' => $options]
198
-                     : (array) $options;
199
-
200
-        // If the given contents is actually a file or uploaded file instance than we will
201
-        // automatically store the file using a stream. This provides a convenient path
202
-        // for the developer to store streams without managing them manually in code.
203
-        if ($contents instanceof File ||
204
-            $contents instanceof UploadedFile) {
205
-            return $this->putFile($path, $contents, $options);
206
-        }
207
-
208
-        return is_resource($contents)
209
-                ? $this->driver->putStream($path, $contents, $options)
210
-                : $this->driver->put($path, $contents, $options);
211
-    }
212
-
213
-    /**
214
-     * Store the uploaded file on the disk.
215
-     *
216
-     * @param  string  $path
217
-     * @param  \Illuminate\Http\File|\Illuminate\Http\UploadedFile  $file
218
-     * @param  array  $options
219
-     * @return string|false
220
-     */
221
-    public function putFile($path, $file, $options = [])
222
-    {
223
-        return $this->putFileAs($path, $file, $file->hashName(), $options);
224
-    }
225
-
226
-    /**
227
-     * Store the uploaded file on the disk with a given name.
228
-     *
229
-     * @param  string  $path
230
-     * @param  \Illuminate\Http\File|\Illuminate\Http\UploadedFile  $file
231
-     * @param  string  $name
232
-     * @param  array  $options
233
-     * @return string|false
234
-     */
235
-    public function putFileAs($path, $file, $name, $options = [])
236
-    {
237
-        $stream = fopen($file->getRealPath(), 'r');
238
-
239
-        // Next, we will format the path of the file and store the file using a stream since
240
-        // they provide better performance than alternatives. Once we write the file this
241
-        // stream will get closed automatically by us so the developer doesn't have to.
242
-        $result = $this->put(
243
-            $path = trim($path.'/'.$name, '/'), $stream, $options
244
-        );
245
-
246
-        if (is_resource($stream)) {
247
-            fclose($stream);
248
-        }
249
-
250
-        return $result ? $path : false;
251
-    }
252
-
253
-    /**
254
-     * Get the visibility for the given path.
255
-     *
256
-     * @param  string  $path
257
-     * @return string
258
-     */
259
-    public function getVisibility($path)
260
-    {
261
-        if ($this->driver->getVisibility($path) == AdapterInterface::VISIBILITY_PUBLIC) {
262
-            return FilesystemContract::VISIBILITY_PUBLIC;
263
-        }
264
-
265
-        return FilesystemContract::VISIBILITY_PRIVATE;
266
-    }
267
-
268
-    /**
269
-     * Set the visibility for the given path.
270
-     *
271
-     * @param  string  $path
272
-     * @param  string  $visibility
273
-     * @return bool
274
-     */
275
-    public function setVisibility($path, $visibility)
276
-    {
277
-        return $this->driver->setVisibility($path, $this->parseVisibility($visibility));
278
-    }
279
-
280
-    /**
281
-     * Prepend to a file.
282
-     *
283
-     * @param  string  $path
284
-     * @param  string  $data
285
-     * @param  string  $separator
286
-     * @return bool
287
-     */
288
-    public function prepend($path, $data, $separator = PHP_EOL)
289
-    {
290
-        if ($this->exists($path)) {
291
-            return $this->put($path, $data.$separator.$this->get($path));
292
-        }
293
-
294
-        return $this->put($path, $data);
295
-    }
296
-
297
-    /**
298
-     * Append to a file.
299
-     *
300
-     * @param  string  $path
301
-     * @param  string  $data
302
-     * @param  string  $separator
303
-     * @return bool
304
-     */
305
-    public function append($path, $data, $separator = PHP_EOL)
306
-    {
307
-        if ($this->exists($path)) {
308
-            return $this->put($path, $this->get($path).$separator.$data);
309
-        }
310
-
311
-        return $this->put($path, $data);
312
-    }
313
-
314
-    /**
315
-     * Delete the file at a given path.
316
-     *
317
-     * @param  string|array  $paths
318
-     * @return bool
319
-     */
320
-    public function delete($paths)
321
-    {
322
-        $paths = is_array($paths) ? $paths : func_get_args();
323
-
324
-        $success = true;
325
-
326
-        foreach ($paths as $path) {
327
-            try {
328
-                if (! $this->driver->delete($path)) {
329
-                    $success = false;
330
-                }
331
-            } catch (FileNotFoundException $e) {
332
-                $success = false;
333
-            }
334
-        }
335
-
336
-        return $success;
337
-    }
338
-
339
-    /**
340
-     * Copy a file to a new location.
341
-     *
342
-     * @param  string  $from
343
-     * @param  string  $to
344
-     * @return bool
345
-     */
346
-    public function copy($from, $to)
347
-    {
348
-        return $this->driver->copy($from, $to);
349
-    }
350
-
351
-    /**
352
-     * Move a file to a new location.
353
-     *
354
-     * @param  string  $from
355
-     * @param  string  $to
356
-     * @return bool
357
-     */
358
-    public function move($from, $to)
359
-    {
360
-        return $this->driver->rename($from, $to);
361
-    }
362
-
363
-    /**
364
-     * Get the file size of a given file.
365
-     *
366
-     * @param  string  $path
367
-     * @return int
368
-     */
369
-    public function size($path)
370
-    {
371
-        return $this->driver->getSize($path);
372
-    }
373
-
374
-    /**
375
-     * Get the mime-type of a given file.
376
-     *
377
-     * @param  string  $path
378
-     * @return string|false
379
-     */
380
-    public function mimeType($path)
381
-    {
382
-        return $this->driver->getMimetype($path);
383
-    }
384
-
385
-    /**
386
-     * Get the file's last modification time.
387
-     *
388
-     * @param  string  $path
389
-     * @return int
390
-     */
391
-    public function lastModified($path)
392
-    {
393
-        return $this->driver->getTimestamp($path);
394
-    }
395
-
396
-    /**
397
-     * Get the URL for the file at the given path.
398
-     *
399
-     * @param  string  $path
400
-     * @return string
401
-     *
402
-     * @throws \RuntimeException
403
-     */
404
-    public function url($path)
405
-    {
406
-        $adapter = $this->driver->getAdapter();
407
-
408
-        if ($adapter instanceof CachedAdapter) {
409
-            $adapter = $adapter->getAdapter();
410
-        }
411
-
412
-        if (method_exists($adapter, 'getUrl')) {
413
-            return $adapter->getUrl($path);
414
-        } elseif (method_exists($this->driver, 'getUrl')) {
415
-            return $this->driver->getUrl($path);
416
-        } elseif ($adapter instanceof AwsS3Adapter) {
417
-            return $this->getAwsUrl($adapter, $path);
418
-        } elseif ($adapter instanceof RackspaceAdapter) {
419
-            return $this->getRackspaceUrl($adapter, $path);
420
-        } elseif ($adapter instanceof LocalAdapter) {
421
-            return $this->getLocalUrl($path);
422
-        } else {
423
-            throw new RuntimeException('This driver does not support retrieving URLs.');
424
-        }
425
-    }
426
-
427
-    /**
428
-     * {@inheritdoc}
429
-     */
430
-    public function readStream($path)
431
-    {
432
-        try {
433
-            return $this->driver->readStream($path) ?: null;
434
-        } catch (FileNotFoundException $e) {
435
-            throw new ContractFileNotFoundException($e->getMessage(), $e->getCode(), $e);
436
-        }
437
-    }
438
-
439
-    /**
440
-     * {@inheritdoc}
441
-     */
442
-    public function writeStream($path, $resource, array $options = [])
443
-    {
444
-        try {
445
-            return $this->driver->writeStream($path, $resource, $options);
446
-        } catch (FileExistsException $e) {
447
-            throw new ContractFileExistsException($e->getMessage(), $e->getCode(), $e);
448
-        }
449
-    }
450
-
451
-    /**
452
-     * Get the URL for the file at the given path.
453
-     *
454
-     * @param  \League\Flysystem\AwsS3v3\AwsS3Adapter  $adapter
455
-     * @param  string  $path
456
-     * @return string
457
-     */
458
-    protected function getAwsUrl($adapter, $path)
459
-    {
460
-        // If an explicit base URL has been set on the disk configuration then we will use
461
-        // it as the base URL instead of the default path. This allows the developer to
462
-        // have full control over the base path for this filesystem's generated URLs.
463
-        if (! is_null($url = $this->driver->getConfig()->get('url'))) {
464
-            return $this->concatPathToUrl($url, $adapter->getPathPrefix().$path);
465
-        }
466
-
467
-        return $adapter->getClient()->getObjectUrl(
468
-            $adapter->getBucket(), $adapter->getPathPrefix().$path
469
-        );
470
-    }
471
-
472
-    /**
473
-     * Get the URL for the file at the given path.
474
-     *
475
-     * @param  \League\Flysystem\Rackspace\RackspaceAdapter $adapter
476
-     * @param  string $path
477
-     * @return string
478
-     */
479
-    protected function getRackspaceUrl($adapter, $path)
480
-    {
481
-        return (string) $adapter->getContainer()->getObject($path)->getPublicUrl();
482
-    }
483
-
484
-    /**
485
-     * Get the URL for the file at the given path.
486
-     *
487
-     * @param  string  $path
488
-     * @return string
489
-     */
490
-    protected function getLocalUrl($path)
491
-    {
492
-        $config = $this->driver->getConfig();
493
-
494
-        // If an explicit base URL has been set on the disk configuration then we will use
495
-        // it as the base URL instead of the default path. This allows the developer to
496
-        // have full control over the base path for this filesystem's generated URLs.
497
-        if ($config->has('url')) {
498
-            return $this->concatPathToUrl($config->get('url'), $path);
499
-        }
500
-
501
-        $path = '/storage/'.$path;
502
-
503
-        // If the path contains "storage/public", it probably means the developer is using
504
-        // the default disk to generate the path instead of the "public" disk like they
505
-        // are really supposed to use. We will remove the public from this path here.
506
-        if (Str::contains($path, '/storage/public/')) {
507
-            return Str::replaceFirst('/public/', '/', $path);
508
-        }
509
-
510
-        return $path;
511
-    }
512
-
513
-    /**
514
-     * Get a temporary URL for the file at the given path.
515
-     *
516
-     * @param  string  $path
517
-     * @param  \DateTimeInterface  $expiration
518
-     * @param  array  $options
519
-     * @return string
520
-     *
521
-     * @throws \RuntimeException
522
-     */
523
-    public function temporaryUrl($path, $expiration, array $options = [])
524
-    {
525
-        $adapter = $this->driver->getAdapter();
526
-
527
-        if ($adapter instanceof CachedAdapter) {
528
-            $adapter = $adapter->getAdapter();
529
-        }
530
-
531
-        if (method_exists($adapter, 'getTemporaryUrl')) {
532
-            return $adapter->getTemporaryUrl($path, $expiration, $options);
533
-        } elseif ($adapter instanceof AwsS3Adapter) {
534
-            return $this->getAwsTemporaryUrl($adapter, $path, $expiration, $options);
535
-        } elseif ($adapter instanceof RackspaceAdapter) {
536
-            return $this->getRackspaceTemporaryUrl($adapter, $path, $expiration, $options);
537
-        } else {
538
-            throw new RuntimeException('This driver does not support creating temporary URLs.');
539
-        }
540
-    }
541
-
542
-    /**
543
-     * Get a temporary URL for the file at the given path.
544
-     *
545
-     * @param  \League\Flysystem\AwsS3v3\AwsS3Adapter  $adapter
546
-     * @param  string $path
547
-     * @param  \DateTimeInterface $expiration
548
-     * @param  array $options
549
-     * @return string
550
-     */
551
-    public function getAwsTemporaryUrl($adapter, $path, $expiration, $options)
552
-    {
553
-        $client = $adapter->getClient();
554
-
555
-        $command = $client->getCommand('GetObject', array_merge([
556
-            'Bucket' => $adapter->getBucket(),
557
-            'Key' => $adapter->getPathPrefix().$path,
558
-        ], $options));
559
-
560
-        return (string) $client->createPresignedRequest(
561
-            $command, $expiration
562
-        )->getUri();
563
-    }
564
-
565
-    /**
566
-     * Get a temporary URL for the file at the given path.
567
-     *
568
-     * @param  \League\Flysystem\Rackspace\RackspaceAdapter  $adapter
569
-     * @param  string  $path
570
-     * @param  \DateTimeInterface  $expiration
571
-     * @param  array  $options
572
-     * @return string
573
-     */
574
-    public function getRackspaceTemporaryUrl($adapter, $path, $expiration, $options)
575
-    {
576
-        return $adapter->getContainer()->getObject($path)->getTemporaryUrl(
577
-            Carbon::now()->diffInSeconds($expiration),
578
-            $options['method'] ?? 'GET',
579
-            $options['forcePublicUrl'] ?? true
580
-        );
581
-    }
582
-
583
-    /**
584
-     * Concatenate a path to a URL.
585
-     *
586
-     * @param  string $url
587
-     * @param  string $path
588
-     * @return string
589
-     */
590
-    protected function concatPathToUrl($url, $path)
591
-    {
592
-        return rtrim($url, '/').'/'.ltrim($path, '/');
593
-    }
594
-
595
-    /**
596
-     * Get an array of all files in a directory.
597
-     *
598
-     * @param  string|null  $directory
599
-     * @param  bool  $recursive
600
-     * @return array
601
-     */
602
-    public function files($directory = null, $recursive = false)
603
-    {
604
-        $contents = $this->driver->listContents($directory, $recursive);
605
-
606
-        return $this->filterContentsByType($contents, 'file');
607
-    }
608
-
609
-    /**
610
-     * Get all of the files from the given directory (recursive).
611
-     *
612
-     * @param  string|null  $directory
613
-     * @return array
614
-     */
615
-    public function allFiles($directory = null)
616
-    {
617
-        return $this->files($directory, true);
618
-    }
619
-
620
-    /**
621
-     * Get all of the directories within a given directory.
622
-     *
623
-     * @param  string|null  $directory
624
-     * @param  bool  $recursive
625
-     * @return array
626
-     */
627
-    public function directories($directory = null, $recursive = false)
628
-    {
629
-        $contents = $this->driver->listContents($directory, $recursive);
630
-
631
-        return $this->filterContentsByType($contents, 'dir');
632
-    }
633
-
634
-    /**
635
-     * Get all (recursive) of the directories within a given directory.
636
-     *
637
-     * @param  string|null  $directory
638
-     * @return array
639
-     */
640
-    public function allDirectories($directory = null)
641
-    {
642
-        return $this->directories($directory, true);
643
-    }
644
-
645
-    /**
646
-     * Create a directory.
647
-     *
648
-     * @param  string  $path
649
-     * @return bool
650
-     */
651
-    public function makeDirectory($path)
652
-    {
653
-        return $this->driver->createDir($path);
654
-    }
655
-
656
-    /**
657
-     * Recursively delete a directory.
658
-     *
659
-     * @param  string  $directory
660
-     * @return bool
661
-     */
662
-    public function deleteDirectory($directory)
663
-    {
664
-        return $this->driver->deleteDir($directory);
665
-    }
666
-
667
-    /**
668
-     * Flush the Flysystem cache.
669
-     *
670
-     * @return void
671
-     */
672
-    public function flushCache()
673
-    {
674
-        $adapter = $this->driver->getAdapter();
675
-
676
-        if ($adapter instanceof CachedAdapter) {
677
-            $adapter->getCache()->flush();
678
-        }
679
-    }
680
-
681
-    /**
682
-     * Get the Flysystem driver.
683
-     *
684
-     * @return \League\Flysystem\FilesystemInterface
685
-     */
686
-    public function getDriver()
687
-    {
688
-        return $this->driver;
689
-    }
690
-
691
-    /**
692
-     * Filter directory contents by type.
693
-     *
694
-     * @param  array  $contents
695
-     * @param  string  $type
696
-     * @return array
697
-     */
698
-    protected function filterContentsByType($contents, $type)
699
-    {
700
-        return Collection::make($contents)
701
-            ->where('type', $type)
702
-            ->pluck('path')
703
-            ->values()
704
-            ->all();
705
-    }
706
-
707
-    /**
708
-     * Parse the given visibility value.
709
-     *
710
-     * @param  string|null  $visibility
711
-     * @return string|null
712
-     *
713
-     * @throws \InvalidArgumentException
714
-     */
715
-    protected function parseVisibility($visibility)
716
-    {
717
-        if (is_null($visibility)) {
718
-            return;
719
-        }
720
-
721
-        switch ($visibility) {
722
-            case FilesystemContract::VISIBILITY_PUBLIC:
723
-                return AdapterInterface::VISIBILITY_PUBLIC;
724
-            case FilesystemContract::VISIBILITY_PRIVATE:
725
-                return AdapterInterface::VISIBILITY_PRIVATE;
726
-        }
727
-
728
-        throw new InvalidArgumentException("Unknown visibility: {$visibility}");
729
-    }
730
-
731
-    /**
732
-     * Pass dynamic methods call onto Flysystem.
733
-     *
734
-     * @param  string  $method
735
-     * @param  array  $parameters
736
-     * @return mixed
737
-     *
738
-     * @throws \BadMethodCallException
739
-     */
740
-    public function __call($method, array $parameters)
741
-    {
742
-        return call_user_func_array([$this->driver, $method], $parameters);
743
-    }
744
-}
Browse code

initial commit

Emmanuel ROY authored on 09/08/2019 08:39:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,744 @@
1
+<?php
2
+
3
+namespace Illuminate\Filesystem;
4
+
5
+use RuntimeException;
6
+use Illuminate\Http\File;
7
+use Illuminate\Support\Arr;
8
+use Illuminate\Support\Str;
9
+use InvalidArgumentException;
10
+use Illuminate\Support\Carbon;
11
+use Illuminate\Http\UploadedFile;
12
+use Illuminate\Support\Collection;
13
+use League\Flysystem\AdapterInterface;
14
+use PHPUnit\Framework\Assert as PHPUnit;
15
+use League\Flysystem\FileExistsException;
16
+use League\Flysystem\FilesystemInterface;
17
+use League\Flysystem\AwsS3v3\AwsS3Adapter;
18
+use League\Flysystem\Cached\CachedAdapter;
19
+use League\Flysystem\FileNotFoundException;
20
+use League\Flysystem\Rackspace\RackspaceAdapter;
21
+use League\Flysystem\Adapter\Local as LocalAdapter;
22
+use Symfony\Component\HttpFoundation\StreamedResponse;
23
+use Illuminate\Contracts\Filesystem\Cloud as CloudFilesystemContract;
24
+use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract;
25
+use Illuminate\Contracts\Filesystem\FileExistsException as ContractFileExistsException;
26
+use Illuminate\Contracts\Filesystem\FileNotFoundException as ContractFileNotFoundException;
27
+
28
+/**
29
+ * @mixin \League\Flysystem\FilesystemInterface
30
+ */
31
+class FilesystemAdapter implements FilesystemContract, CloudFilesystemContract
32
+{
33
+    /**
34
+     * The Flysystem filesystem implementation.
35
+     *
36
+     * @var \League\Flysystem\FilesystemInterface
37
+     */
38
+    protected $driver;
39
+
40
+    /**
41
+     * Create a new filesystem adapter instance.
42
+     *
43
+     * @param  \League\Flysystem\FilesystemInterface  $driver
44
+     * @return void
45
+     */
46
+    public function __construct(FilesystemInterface $driver)
47
+    {
48
+        $this->driver = $driver;
49
+    }
50
+
51
+    /**
52
+     * Assert that the given file exists.
53
+     *
54
+     * @param  string|array  $path
55
+     * @return $this
56
+     */
57
+    public function assertExists($path)
58
+    {
59
+        $paths = Arr::wrap($path);
60
+
61
+        foreach ($paths as $path) {
62
+            PHPUnit::assertTrue(
63
+                $this->exists($path), "Unable to find a file at path [{$path}]."
64
+            );
65
+        }
66
+
67
+        return $this;
68
+    }
69
+
70
+    /**
71
+     * Assert that the given file does not exist.
72
+     *
73
+     * @param  string|array  $path
74
+     * @return $this
75
+     */
76
+    public function assertMissing($path)
77
+    {
78
+        $paths = Arr::wrap($path);
79
+
80
+        foreach ($paths as $path) {
81
+            PHPUnit::assertFalse(
82
+                $this->exists($path), "Found unexpected file at path [{$path}]."
83
+            );
84
+        }
85
+
86
+        return $this;
87
+    }
88
+
89
+    /**
90
+     * Determine if a file exists.
91
+     *
92
+     * @param  string  $path
93
+     * @return bool
94
+     */
95
+    public function exists($path)
96
+    {
97
+        return $this->driver->has($path);
98
+    }
99
+
100
+    /**
101
+     * Get the full path for the file at the given "short" path.
102
+     *
103
+     * @param  string  $path
104
+     * @return string
105
+     */
106
+    public function path($path)
107
+    {
108
+        return $this->driver->getAdapter()->getPathPrefix().$path;
109
+    }
110
+
111
+    /**
112
+     * Get the contents of a file.
113
+     *
114
+     * @param  string  $path
115
+     * @return string
116
+     *
117
+     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
118
+     */
119
+    public function get($path)
120
+    {
121
+        try {
122
+            return $this->driver->read($path);
123
+        } catch (FileNotFoundException $e) {
124
+            throw new ContractFileNotFoundException($path, $e->getCode(), $e);
125
+        }
126
+    }
127
+
128
+    /**
129
+     * Create a streamed response for a given file.
130
+     *
131
+     * @param  string  $path
132
+     * @param  string|null  $name
133
+     * @param  array|null  $headers
134
+     * @param  string|null  $disposition
135
+     * @return \Symfony\Component\HttpFoundation\StreamedResponse
136
+     */
137
+    public function response($path, $name = null, array $headers = [], $disposition = 'inline')
138
+    {
139
+        $response = new StreamedResponse;
140
+
141
+        $filename = $name ?? basename($path);
142
+
143
+        $disposition = $response->headers->makeDisposition(
144
+            $disposition, $filename, $this->fallbackName($filename)
145
+        );
146
+
147
+        $response->headers->replace($headers + [
148
+            'Content-Type' => $this->mimeType($path),
149
+            'Content-Length' => $this->size($path),
150
+            'Content-Disposition' => $disposition,
151
+        ]);
152
+
153
+        $response->setCallback(function () use ($path) {
154
+            $stream = $this->readStream($path);
155
+            fpassthru($stream);
156
+            fclose($stream);
157
+        });
158
+
159
+        return $response;
160
+    }
161
+
162
+    /**
163
+     * Create a streamed download response for a given file.
164
+     *
165
+     * @param  string  $path
166
+     * @param  string|null  $name
167
+     * @param  array|null  $headers
168
+     * @return \Symfony\Component\HttpFoundation\StreamedResponse
169
+     */
170
+    public function download($path, $name = null, array $headers = [])
171
+    {
172
+        return $this->response($path, $name, $headers, 'attachment');
173
+    }
174
+
175
+    /**
176
+     * Convert the string to ASCII characters that are equivalent to the given name.
177
+     *
178
+     * @param  string  $name
179
+     * @return string
180
+     */
181
+    protected function fallbackName($name)
182
+    {
183
+        return str_replace('%', '', Str::ascii($name));
184
+    }
185
+
186
+    /**
187
+     * Write the contents of a file.
188
+     *
189
+     * @param  string  $path
190
+     * @param  string|resource  $contents
191
+     * @param  mixed  $options
192
+     * @return bool
193
+     */
194
+    public function put($path, $contents, $options = [])
195
+    {
196
+        $options = is_string($options)
197
+                     ? ['visibility' => $options]
198
+                     : (array) $options;
199
+
200
+        // If the given contents is actually a file or uploaded file instance than we will
201
+        // automatically store the file using a stream. This provides a convenient path
202
+        // for the developer to store streams without managing them manually in code.
203
+        if ($contents instanceof File ||
204
+            $contents instanceof UploadedFile) {
205
+            return $this->putFile($path, $contents, $options);
206
+        }
207
+
208
+        return is_resource($contents)
209
+                ? $this->driver->putStream($path, $contents, $options)
210
+                : $this->driver->put($path, $contents, $options);
211
+    }
212
+
213
+    /**
214
+     * Store the uploaded file on the disk.
215
+     *
216
+     * @param  string  $path
217
+     * @param  \Illuminate\Http\File|\Illuminate\Http\UploadedFile  $file
218
+     * @param  array  $options
219
+     * @return string|false
220
+     */
221
+    public function putFile($path, $file, $options = [])
222
+    {
223
+        return $this->putFileAs($path, $file, $file->hashName(), $options);
224
+    }
225
+
226
+    /**
227
+     * Store the uploaded file on the disk with a given name.
228
+     *
229
+     * @param  string  $path
230
+     * @param  \Illuminate\Http\File|\Illuminate\Http\UploadedFile  $file
231
+     * @param  string  $name
232
+     * @param  array  $options
233
+     * @return string|false
234
+     */
235
+    public function putFileAs($path, $file, $name, $options = [])
236
+    {
237
+        $stream = fopen($file->getRealPath(), 'r');
238
+
239
+        // Next, we will format the path of the file and store the file using a stream since
240
+        // they provide better performance than alternatives. Once we write the file this
241
+        // stream will get closed automatically by us so the developer doesn't have to.
242
+        $result = $this->put(
243
+            $path = trim($path.'/'.$name, '/'), $stream, $options
244
+        );
245
+
246
+        if (is_resource($stream)) {
247
+            fclose($stream);
248
+        }
249
+
250
+        return $result ? $path : false;
251
+    }
252
+
253
+    /**
254
+     * Get the visibility for the given path.
255
+     *
256
+     * @param  string  $path
257
+     * @return string
258
+     */
259
+    public function getVisibility($path)
260
+    {
261
+        if ($this->driver->getVisibility($path) == AdapterInterface::VISIBILITY_PUBLIC) {
262
+            return FilesystemContract::VISIBILITY_PUBLIC;
263
+        }
264
+
265
+        return FilesystemContract::VISIBILITY_PRIVATE;
266
+    }
267
+
268
+    /**
269
+     * Set the visibility for the given path.
270
+     *
271
+     * @param  string  $path
272
+     * @param  string  $visibility
273
+     * @return bool
274
+     */
275
+    public function setVisibility($path, $visibility)
276
+    {
277
+        return $this->driver->setVisibility($path, $this->parseVisibility($visibility));
278
+    }
279
+
280
+    /**
281
+     * Prepend to a file.
282
+     *
283
+     * @param  string  $path
284
+     * @param  string  $data
285
+     * @param  string  $separator
286
+     * @return bool
287
+     */
288
+    public function prepend($path, $data, $separator = PHP_EOL)
289
+    {
290
+        if ($this->exists($path)) {
291
+            return $this->put($path, $data.$separator.$this->get($path));
292
+        }
293
+
294
+        return $this->put($path, $data);
295
+    }
296
+
297
+    /**
298
+     * Append to a file.
299
+     *
300
+     * @param  string  $path
301
+     * @param  string  $data
302
+     * @param  string  $separator
303
+     * @return bool
304
+     */
305
+    public function append($path, $data, $separator = PHP_EOL)
306
+    {
307
+        if ($this->exists($path)) {
308
+            return $this->put($path, $this->get($path).$separator.$data);
309
+        }
310
+
311
+        return $this->put($path, $data);
312
+    }
313
+
314
+    /**
315
+     * Delete the file at a given path.
316
+     *
317
+     * @param  string|array  $paths
318
+     * @return bool
319
+     */
320
+    public function delete($paths)
321
+    {
322
+        $paths = is_array($paths) ? $paths : func_get_args();
323
+
324
+        $success = true;
325
+
326
+        foreach ($paths as $path) {
327
+            try {
328
+                if (! $this->driver->delete($path)) {
329
+                    $success = false;
330
+                }
331
+            } catch (FileNotFoundException $e) {
332
+                $success = false;
333
+            }
334
+        }
335
+
336
+        return $success;
337
+    }
338
+
339
+    /**
340
+     * Copy a file to a new location.
341
+     *
342
+     * @param  string  $from
343
+     * @param  string  $to
344
+     * @return bool
345
+     */
346
+    public function copy($from, $to)
347
+    {
348
+        return $this->driver->copy($from, $to);
349
+    }
350
+
351
+    /**
352
+     * Move a file to a new location.
353
+     *
354
+     * @param  string  $from
355
+     * @param  string  $to
356
+     * @return bool
357
+     */
358
+    public function move($from, $to)
359
+    {
360
+        return $this->driver->rename($from, $to);
361
+    }
362
+
363
+    /**
364
+     * Get the file size of a given file.
365
+     *
366
+     * @param  string  $path
367
+     * @return int
368
+     */
369
+    public function size($path)
370
+    {
371
+        return $this->driver->getSize($path);
372
+    }
373
+
374
+    /**
375
+     * Get the mime-type of a given file.
376
+     *
377
+     * @param  string  $path
378
+     * @return string|false
379
+     */
380
+    public function mimeType($path)
381
+    {
382
+        return $this->driver->getMimetype($path);
383
+    }
384
+
385
+    /**
386
+     * Get the file's last modification time.
387
+     *
388
+     * @param  string  $path
389
+     * @return int
390
+     */
391
+    public function lastModified($path)
392
+    {
393
+        return $this->driver->getTimestamp($path);
394
+    }
395
+
396
+    /**
397
+     * Get the URL for the file at the given path.
398
+     *
399
+     * @param  string  $path
400
+     * @return string
401
+     *
402
+     * @throws \RuntimeException
403
+     */
404
+    public function url($path)
405
+    {
406
+        $adapter = $this->driver->getAdapter();
407
+
408
+        if ($adapter instanceof CachedAdapter) {
409
+            $adapter = $adapter->getAdapter();
410
+        }
411
+
412
+        if (method_exists($adapter, 'getUrl')) {
413
+            return $adapter->getUrl($path);
414
+        } elseif (method_exists($this->driver, 'getUrl')) {
415
+            return $this->driver->getUrl($path);
416
+        } elseif ($adapter instanceof AwsS3Adapter) {
417
+            return $this->getAwsUrl($adapter, $path);
418
+        } elseif ($adapter instanceof RackspaceAdapter) {
419
+            return $this->getRackspaceUrl($adapter, $path);
420
+        } elseif ($adapter instanceof LocalAdapter) {
421
+            return $this->getLocalUrl($path);
422
+        } else {
423
+            throw new RuntimeException('This driver does not support retrieving URLs.');
424
+        }
425
+    }
426
+
427
+    /**
428
+     * {@inheritdoc}
429
+     */
430
+    public function readStream($path)
431
+    {
432
+        try {
433
+            return $this->driver->readStream($path) ?: null;
434
+        } catch (FileNotFoundException $e) {
435
+            throw new ContractFileNotFoundException($e->getMessage(), $e->getCode(), $e);
436
+        }
437
+    }
438
+
439
+    /**
440
+     * {@inheritdoc}
441
+     */
442
+    public function writeStream($path, $resource, array $options = [])
443
+    {
444
+        try {
445
+            return $this->driver->writeStream($path, $resource, $options);
446
+        } catch (FileExistsException $e) {
447
+            throw new ContractFileExistsException($e->getMessage(), $e->getCode(), $e);
448
+        }
449
+    }
450
+
451
+    /**
452
+     * Get the URL for the file at the given path.
453
+     *
454
+     * @param  \League\Flysystem\AwsS3v3\AwsS3Adapter  $adapter
455
+     * @param  string  $path
456
+     * @return string
457
+     */
458
+    protected function getAwsUrl($adapter, $path)
459
+    {
460
+        // If an explicit base URL has been set on the disk configuration then we will use
461
+        // it as the base URL instead of the default path. This allows the developer to
462
+        // have full control over the base path for this filesystem's generated URLs.
463
+        if (! is_null($url = $this->driver->getConfig()->get('url'))) {
464
+            return $this->concatPathToUrl($url, $adapter->getPathPrefix().$path);
465
+        }
466
+
467
+        return $adapter->getClient()->getObjectUrl(
468
+            $adapter->getBucket(), $adapter->getPathPrefix().$path
469
+        );
470
+    }
471
+
472
+    /**
473
+     * Get the URL for the file at the given path.
474
+     *
475
+     * @param  \League\Flysystem\Rackspace\RackspaceAdapter $adapter
476
+     * @param  string $path
477
+     * @return string
478
+     */
479
+    protected function getRackspaceUrl($adapter, $path)
480
+    {
481
+        return (string) $adapter->getContainer()->getObject($path)->getPublicUrl();
482
+    }
483
+
484
+    /**
485
+     * Get the URL for the file at the given path.
486
+     *
487
+     * @param  string  $path
488
+     * @return string
489
+     */
490
+    protected function getLocalUrl($path)
491
+    {
492
+        $config = $this->driver->getConfig();
493
+
494
+        // If an explicit base URL has been set on the disk configuration then we will use
495
+        // it as the base URL instead of the default path. This allows the developer to
496
+        // have full control over the base path for this filesystem's generated URLs.
497
+        if ($config->has('url')) {
498
+            return $this->concatPathToUrl($config->get('url'), $path);
499
+        }
500
+
501
+        $path = '/storage/'.$path;
502
+
503
+        // If the path contains "storage/public", it probably means the developer is using
504
+        // the default disk to generate the path instead of the "public" disk like they
505
+        // are really supposed to use. We will remove the public from this path here.
506
+        if (Str::contains($path, '/storage/public/')) {
507
+            return Str::replaceFirst('/public/', '/', $path);
508
+        }
509
+
510
+        return $path;
511
+    }
512
+
513
+    /**
514
+     * Get a temporary URL for the file at the given path.
515
+     *
516
+     * @param  string  $path
517
+     * @param  \DateTimeInterface  $expiration
518
+     * @param  array  $options
519
+     * @return string
520
+     *
521
+     * @throws \RuntimeException
522
+     */
523
+    public function temporaryUrl($path, $expiration, array $options = [])
524
+    {
525
+        $adapter = $this->driver->getAdapter();
526
+
527
+        if ($adapter instanceof CachedAdapter) {
528
+            $adapter = $adapter->getAdapter();
529
+        }
530
+
531
+        if (method_exists($adapter, 'getTemporaryUrl')) {
532
+            return $adapter->getTemporaryUrl($path, $expiration, $options);
533
+        } elseif ($adapter instanceof AwsS3Adapter) {
534
+            return $this->getAwsTemporaryUrl($adapter, $path, $expiration, $options);
535
+        } elseif ($adapter instanceof RackspaceAdapter) {
536
+            return $this->getRackspaceTemporaryUrl($adapter, $path, $expiration, $options);
537
+        } else {
538
+            throw new RuntimeException('This driver does not support creating temporary URLs.');
539
+        }
540
+    }
541
+
542
+    /**
543
+     * Get a temporary URL for the file at the given path.
544
+     *
545
+     * @param  \League\Flysystem\AwsS3v3\AwsS3Adapter  $adapter
546
+     * @param  string $path
547
+     * @param  \DateTimeInterface $expiration
548
+     * @param  array $options
549
+     * @return string
550
+     */
551
+    public function getAwsTemporaryUrl($adapter, $path, $expiration, $options)
552
+    {
553
+        $client = $adapter->getClient();
554
+
555
+        $command = $client->getCommand('GetObject', array_merge([
556
+            'Bucket' => $adapter->getBucket(),
557
+            'Key' => $adapter->getPathPrefix().$path,
558
+        ], $options));
559
+
560
+        return (string) $client->createPresignedRequest(
561
+            $command, $expiration
562
+        )->getUri();
563
+    }
564
+
565
+    /**
566
+     * Get a temporary URL for the file at the given path.
567
+     *
568
+     * @param  \League\Flysystem\Rackspace\RackspaceAdapter  $adapter
569
+     * @param  string  $path
570
+     * @param  \DateTimeInterface  $expiration
571
+     * @param  array  $options
572
+     * @return string
573
+     */
574
+    public function getRackspaceTemporaryUrl($adapter, $path, $expiration, $options)
575
+    {
576
+        return $adapter->getContainer()->getObject($path)->getTemporaryUrl(
577
+            Carbon::now()->diffInSeconds($expiration),
578
+            $options['method'] ?? 'GET',
579
+            $options['forcePublicUrl'] ?? true
580
+        );
581
+    }
582
+
583
+    /**
584
+     * Concatenate a path to a URL.
585
+     *
586
+     * @param  string $url
587
+     * @param  string $path
588
+     * @return string
589
+     */
590
+    protected function concatPathToUrl($url, $path)
591
+    {
592
+        return rtrim($url, '/').'/'.ltrim($path, '/');
593
+    }
594
+
595
+    /**
596
+     * Get an array of all files in a directory.
597
+     *
598
+     * @param  string|null  $directory
599
+     * @param  bool  $recursive
600
+     * @return array
601
+     */
602
+    public function files($directory = null, $recursive = false)
603
+    {
604
+        $contents = $this->driver->listContents($directory, $recursive);
605
+
606
+        return $this->filterContentsByType($contents, 'file');
607
+    }
608
+
609
+    /**
610
+     * Get all of the files from the given directory (recursive).
611
+     *
612
+     * @param  string|null  $directory
613
+     * @return array
614
+     */
615
+    public function allFiles($directory = null)
616
+    {
617
+        return $this->files($directory, true);
618
+    }
619
+
620
+    /**
621
+     * Get all of the directories within a given directory.
622
+     *
623
+     * @param  string|null  $directory
624
+     * @param  bool  $recursive
625
+     * @return array
626
+     */
627
+    public function directories($directory = null, $recursive = false)
628
+    {
629
+        $contents = $this->driver->listContents($directory, $recursive);
630
+
631
+        return $this->filterContentsByType($contents, 'dir');
632
+    }
633
+
634
+    /**
635
+     * Get all (recursive) of the directories within a given directory.
636
+     *
637
+     * @param  string|null  $directory
638
+     * @return array
639
+     */
640
+    public function allDirectories($directory = null)
641
+    {
642
+        return $this->directories($directory, true);
643
+    }
644
+
645
+    /**
646
+     * Create a directory.
647
+     *
648
+     * @param  string  $path
649
+     * @return bool
650
+     */
651
+    public function makeDirectory($path)
652
+    {
653
+        return $this->driver->createDir($path);
654
+    }
655
+
656
+    /**
657
+     * Recursively delete a directory.
658
+     *
659
+     * @param  string  $directory
660
+     * @return bool
661
+     */
662
+    public function deleteDirectory($directory)
663
+    {
664
+        return $this->driver->deleteDir($directory);
665
+    }
666
+
667
+    /**
668
+     * Flush the Flysystem cache.
669
+     *
670
+     * @return void
671
+     */
672
+    public function flushCache()
673
+    {
674
+        $adapter = $this->driver->getAdapter();
675
+
676
+        if ($adapter instanceof CachedAdapter) {
677
+            $adapter->getCache()->flush();
678
+        }
679
+    }
680
+
681
+    /**
682
+     * Get the Flysystem driver.
683
+     *
684
+     * @return \League\Flysystem\FilesystemInterface
685
+     */
686
+    public function getDriver()
687
+    {
688
+        return $this->driver;
689
+    }
690
+
691
+    /**
692
+     * Filter directory contents by type.
693
+     *
694
+     * @param  array  $contents
695
+     * @param  string  $type
696
+     * @return array
697
+     */
698
+    protected function filterContentsByType($contents, $type)
699
+    {
700
+        return Collection::make($contents)
701
+            ->where('type', $type)
702
+            ->pluck('path')
703
+            ->values()
704
+            ->all();
705
+    }
706
+
707
+    /**
708
+     * Parse the given visibility value.
709
+     *
710
+     * @param  string|null  $visibility
711
+     * @return string|null
712
+     *
713
+     * @throws \InvalidArgumentException
714
+     */
715
+    protected function parseVisibility($visibility)
716
+    {
717
+        if (is_null($visibility)) {
718
+            return;
719
+        }
720
+
721
+        switch ($visibility) {
722
+            case FilesystemContract::VISIBILITY_PUBLIC:
723
+                return AdapterInterface::VISIBILITY_PUBLIC;
724
+            case FilesystemContract::VISIBILITY_PRIVATE:
725
+                return AdapterInterface::VISIBILITY_PRIVATE;
726
+        }
727
+
728
+        throw new InvalidArgumentException("Unknown visibility: {$visibility}");
729
+    }
730
+
731
+    /**
732
+     * Pass dynamic methods call onto Flysystem.
733
+     *
734
+     * @param  string  $method
735
+     * @param  array  $parameters
736
+     * @return mixed
737
+     *
738
+     * @throws \BadMethodCallException
739
+     */
740
+    public function __call($method, array $parameters)
741
+    {
742
+        return call_user_func_array([$this->driver, $method], $parameters);
743
+    }
744
+}