Test Failed
Push — master ( f6b24d...877a39 )
by Stephen
01:01 queued 10s
created

S3::list()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 17
nc 2
nop 0
dl 0
loc 23
rs 9.7
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A S3::autocompletePath() 0 17 1
1
<?php
2
3
namespace Sfneal\Helpers\Aws\S3\Utils;
4
5
use Closure;
6
use DateTimeInterface;
7
use Illuminate\Contracts\Filesystem\FileNotFoundException;
8
use Illuminate\Contracts\Filesystem\Filesystem;
9
use Illuminate\Filesystem\FilesystemAdapter;
10
use Illuminate\Support\Facades\Response;
11
use Illuminate\Support\Facades\Storage;
12
use Sfneal\Helpers\Aws\S3\Interfaces\S3Filesystem;
13
14
class S3 implements S3Filesystem
15
{
16
    /**
17
     * @var string
18
     */
19
    private $s3Key;
20
21
    /**
22
     * @var string
23
     */
24
    private $disk;
25
26
    /**
27
     * S3 constructor.
28
     *
29
     * @param string $s3_key
30
     */
31
    public function __construct(string $s3_key)
32
    {
33
        $this->s3Key = $s3_key;
34
        $this->disk = config('filesystem.cloud', 's3');
35
    }
36
37
    /**
38
     * Retrieve a Filesystem instance for the specified disk.
39
     *
40
     * @return Filesystem|FilesystemAdapter
41
     */
42
    private function storageDisk(): FilesystemAdapter
43
    {
44
        return Storage::disk($this->disk);
45
    }
46
47
    /**
48
     * Retrieve the S3 key (useful in conjunctions with `autocompletePath()` method).
49
     *
50
     * @return string
51
     */
52
    public function getKey(): string
53
    {
54
        return $this->s3Key;
55
    }
56
57
    /**
58
     * Set the filesystem disk.
59
     *
60
     * @param string $disk
61
     * @return $this
62
     */
63
    public function setDisk(string $disk): self
64
    {
65
        $this->disk = $disk;
66
67
        return $this;
68
    }
69
70
    /**
71
     * Return either an S3 file url.
72
     *
73
     * @return string
74
     */
75
    public function url(): string
76
    {
77
        return $this->storageDisk()->url($this->s3Key);
78
    }
79
80
    /**
81
     * Return either a temporary S3 file url.
82
     *
83
     * @param DateTimeInterface|null $expiration
84
     * @return string
85
     */
86
    public function urlTemp(DateTimeInterface $expiration = null): string
87
    {
88
        return $this->storageDisk()->temporaryUrl($this->s3Key, $expiration ?? now()->addMinutes(60));
89
    }
90
91
    /**
92
     * Upload a file to an S3 bucket.
93
     *
94
     * @param string $localFilePath
95
     * @param string|null $acl
96
     * @return self
97
     */
98
    public function upload(string $localFilePath, string $acl = null): self
99
    {
100
        return $this->uploadRaw(fopen($localFilePath, 'r+'), $acl);
101
    }
102
103
    /**
104
     * Upload raw file contents to an S3 bucket.
105
     *
106
     * @param $fileContents
107
     * @param string|null $acl
108
     * @return self
109
     */
110
    public function uploadRaw($fileContents, string $acl = null): self
111
    {
112
        $this->storageDisk()->put($this->s3Key, $fileContents, $acl);
113
114
        return $this;
115
    }
116
117
    /**
118
     * Download a file from an S3 bucket.
119
     *
120
     * @param string|null $fileName
121
     * @return \Illuminate\Http\Response
122
     * @throws FileNotFoundException|\League\Flysystem\FileNotFoundException
123
     */
124
    public function download(string $fileName = null): \Illuminate\Http\Response
125
    {
126
        if (is_null($fileName)) {
127
            $fileName = basename($this->s3Key);
128
        }
129
130
        $mime = $this->storageDisk()->getMimetype($this->s3Key);
131
        $size = $this->storageDisk()->getSize($this->s3Key);
132
133
        $response = [
134
            'Content-Type' => $mime,
135
            'Content-Length' => $size,
136
            'Content-Description' => 'File Transfer',
137
            'Content-Disposition' => "attachment; filename={$fileName}",
138
            'Content-Transfer-Encoding' => 'binary',
139
        ];
140
141
        return Response::make($this->storageDisk()->get($this->s3Key), 200, $response);
142
    }
143
144
    /**
145
     * Autocomplete an S3 path by providing the known start of a path.
146
     *
147
     * - once path autocompletion is resolved the $s3_key property is replaced with the found path
148
     *
149
     * @return $this
150
     */
151
    public function autocompletePath(): self
152
    {
153
        // Extract the known $base of the path & the $wildcard
154
        $directory = dirname($this->s3Key);
155
156
        // Get all of the folders in the base directory
157
        $folders = $this->storageDisk()->directories($directory);
158
159
        // Filter folders to find the wildcard path
160
        $folders = array_filter($folders, function ($value) {
161
            return str_starts_with($value, $this->s3Key);
162
        });
163
164
        // return the resolved path
165
        $this->s3Key = collect($folders)->values()->first();
166
167
        return $this;
168
    }
169
170
    /**
171
     * Retrieve an array of all files in a directory with an optional filtering closure.
172
     *
173
     * @param Closure|null $closure
174
     * @return array
175
     */
176
    public function allFiles(Closure $closure = null): array
177
    {
178
        // Create array of all files
179
        $allFiles = $this->storageDisk()->allFiles($this->s3Key);
180
181
        // Apply filtering closure
182
        if (isset($closure)) {
183
            return array_filter(array_values($allFiles), $closure);
184
        }
185
186
        return $allFiles;
187
    }
188
189
    /**
190
     * Retrieve an array of all directories within another directory with an optional filtering closure.
191
     *
192
     * @param Closure|null $closure
193
     * @return array
194
     */
195
    public function allDirectories(Closure $closure = null): array
196
    {
197
        // Create array of all directories
198
        $allDirectories = $this->storageDisk()->allDirectories($this->s3Key);
199
200
        // Apply filtering closure
201
        if (isset($closure)) {
202
            return array_filter(array_values($allDirectories), $closure);
203
        }
204
205
        return $allDirectories;
206
    }
207
}
208