Passed
Push — master ( 2c5fa0...a9240d )
by Filippo
05:55 queued 39s
created

Chunk::store()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Jobtech\LaravelChunky;
4
5
use Illuminate\Container\Container;
6
use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
7
use Illuminate\Contracts\Filesystem\Filesystem;
8
use Illuminate\Contracts\Support\Arrayable;
9
use Illuminate\Contracts\Support\Jsonable;
10
use Illuminate\Contracts\Support\Responsable;
11
use Illuminate\Http\Response;
12
use Illuminate\Http\UploadedFile;
13
use Illuminate\Support\Arr;
14
use Illuminate\Support\Str;
15
use Illuminate\Support\Traits\ForwardsCalls;
16
use Jobtech\LaravelChunky\Exceptions\ChunkyException;
17
use Jobtech\LaravelChunky\Http\Resources\ChunkResource;
18
use Symfony\Component\HttpFoundation\File\File;
19
20
class Chunk implements Arrayable, Jsonable, Responsable
21
{
22
    use ForwardsCalls;
23
24
    /** @var bool */
25
    private $show_file_info = true;
26
27
    /** @var int */
28
    private $index;
29
30
    /** @var \Symfony\Component\HttpFoundation\File\File|string */
31
    private $path;
32
33
    /** @var string|null */
34
    private $disk;
35
36
    /** @var bool */
37
    private $last;
38
39
    public function __construct(int $index, $path, $disk = null, $last = false)
40
    {
41
        $this->index = $index;
42
        $this->path = $path;
43
        $this->disk = $disk;
44
        $this->last = $last;
45
    }
46
47
    private function sanitizeName(int $index)
48
    {
49
        return $index.'_'.Str::slug($this->getName()).'.'.$this->guessExtension();
50
    }
51
52
    /**
53
     * Retrieve the chunk index.
54
     *
55
     * @return int
56
     */
57
    public function getIndex(): int
58
    {
59
        return $this->index;
60
    }
61
62
    /**
63
     * Retrieve the chunk file path.
64
     *
65
     * @return \Symfony\Component\HttpFoundation\File\File|string
66
     */
67
    public function getPath(): string
68
    {
69
        if ($this->path instanceof File) {
70
            return $this->path->getRealPath();
71
        }
72
73
        return $this->path;
74
    }
75
76
    public function getFilename($suffix = null): string
77
    {
78
        if ($this->path instanceof UploadedFile) {
79
            return basename($this->path->getClientOriginalName(), $suffix);
80
        } elseif ($this->path instanceof File) {
81
            return $this->path->getBasename($suffix);
82
        }
83
84
        return basename($this->path, $suffix);
85
    }
86
87
    public function getName(): string
88
    {
89
        return pathinfo(
90
            $this->getFilename($this->guessExtension()),
91
            PATHINFO_FILENAME
92
        );
93
    }
94
95
    public function guessExtension()
96
    {
97
        if ($this->path instanceof File) {
98
            return $this->path->guessExtension();
99
        }
100
101
        return pathinfo($this->getFilename(), PATHINFO_EXTENSION);
102
    }
103
104
    /**
105
     * Retrieve the chunk file disk.
106
     *
107
     * @return string|null
108
     */
109
    public function getDisk(): ?string
110
    {
111
        return $this->disk;
112
    }
113
114
    /**
115
     * Set the chunk file disk.
116
     *
117
     * @param string|null $disk
118
     */
119
    public function setDisk($disk = null)
120
    {
121
        $this->disk = $disk;
122
    }
123
124
    /**
125
     * @return bool
126
     */
127
    public function isLast(): bool
128
    {
129
        return $this->last;
130
    }
131
132
    /**
133
     * @param bool $last
134
     */
135
    public function setLast(bool $last): void
136
    {
137
        $this->last = $last;
138
    }
139
140
    /**
141
     * Retrive file contents.
142
     *
143
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
144
     *
145
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
146
     */
147
    public function getFile()
148
    {
149
        if ($this->path instanceof File) {
150
            return $this->path;
151
        }
152
153
        $this->filesystem()
154
            ->get($this->path);
155
    }
156
157
    /**
158
     * Retrieve the chunk's filesystem and disk.
159
     *
160
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
161
     *
162
     * @return \Illuminate\Contracts\Filesystem\Filesystem
163
     */
164
    public function filesystem(): Filesystem
165
    {
166
        return Container::getInstance()->make(FilesystemFactory::class)
167
            ->disk($this->getDisk());
168
    }
169
170
    /**
171
     * If this method is called, when a chunk is turned to array, the file path and real path
172
     * will be omitted.
173
     *
174
     * @return $this
175
     */
176
    public function hideFileInfo()
177
    {
178
        $this->show_file_info = false;
179
180
        return $this;
181
    }
182
183
    /**
184
     * If this method is called, when a chunk is turned to array, the file path and real path
185
     * will be included.
186
     *
187
     * @return $this
188
     */
189
    public function showFileInfo()
190
    {
191
        $this->show_file_info = true;
192
193
        return $this;
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function toArray(): array
200
    {
201
        $extension = $this->guessExtension();
202
203
        $data = [
204
            'name'      => $this->getName(),
205
            'extension' => $extension,
206
            'index'     => $this->getIndex(),
207
            'last'      => $this->isLast(),
208
        ];
209
210
        if ($this->show_file_info) {
211
            $data['file'] = $this->getFilename();
212
            $data['path'] = $this->getPath();
213
        }
214
215
        return $data;
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function toJson($options = 0): string
222
    {
223
        return json_encode($this->toArray(), $options);
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     */
229
    public function toResponse($request)
230
    {
231
        if ($request->wantsJson()) {
232
            return $this->toResource();
233
        }
234
235
        return new Response(
236
            $this->toJson(),
237
            Response::HTTP_CREATED
238
        );
239
    }
240
241
    /**
242
     * Transforms the current model into a json resource.
243
     */
244
    public function toResource()
245
    {
246
        /** @var \Illuminate\Http\Resources\Json\JsonResource $resource */
247
        $resource = config('chunky.resource', ChunkResource::class);
248
249
        return new $resource($this);
250
    }
251
252
    /**
253
     * Store the chunk into filesystem.
254
     *
255
     * @param string $folder
256
     * @param array $options
257
     *
258
     * @return Chunk
259
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
260
     */
261
    public function store(string $folder, $options = []): Chunk
262
    {
263
        if (! $this->path instanceof File) {
264
            throw new ChunkyException('Path must be a file');
265
        }
266
267
        $chunk_name = $this->sanitizeName($this->index);
268
269
        $path = $this->filesystem()
270
            ->putFileAs($folder, $this->path, $chunk_name, $options);
271
272
        return new static($this->getIndex(), $path, $this->getDisk(), $this->isLast());
273
    }
274
275
    /**
276
     * Store and return a new chunk instance.
277
     *
278
     * @param \Symfony\Component\HttpFoundation\File\File $file
279
     * @param string                                      $folder
280
     * @param int                                         $index
281
     * @param array                                       $options
282
     *
283
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
284
     *
285
     * @return \Jobtech\LaravelChunky\Chunk
286
     */
287
    public static function storeFrom(File $file, string $folder, int $index, $options = [])
288
    {
289
        $chunk = new static($index, $file, Arr::pull($options, 'disk'));
290
291
        return $chunk->store($folder, $options);
292
    }
293
}
294