Passed
Push — master ( a4ef1c...1fb27f )
by Florian
12:17 queued 12s
created

File::create()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 32
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3.0021

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 15
c 1
b 0
f 0
nc 4
nop 10
dl 0
loc 32
ccs 15
cts 16
cp 0.9375
crap 3.0021
rs 9.7666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * Copyright (c) Florian Krämer (https://florian-kraemer.net)
5
 * Licensed under The MIT License
6
 * For full copyright and license information, please see the LICENSE.txt
7
 * Redistributions of files must retain the above copyright notice.
8
 *
9
 * @copyright Copyright (c) Florian Krämer (https://florian-kraemer.net)
10
 * @author    Florian Krämer
11
 * @link      https://github.com/Phauthentic
12
 * @license   https://opensource.org/licenses/MIT MIT License
13
 */
14
15
declare(strict_types=1);
16
17
namespace Phauthentic\Infrastructure\Storage;
18
19
use Phauthentic\Infrastructure\Storage\Exception\InvalidStreamResourceException;
20
use Phauthentic\Infrastructure\Storage\PathBuilder\PathBuilderInterface;
21
use Phauthentic\Infrastructure\Storage\Processor\Exception\VariantDoesNotExistException;
22
use Phauthentic\Infrastructure\Storage\Processor\Exception\VariantException;
23
use Phauthentic\Infrastructure\Storage\UrlBuilder\UrlBuilderInterface;
24
use RuntimeException;
25
26
/**
27
 * File
28
 */
29
class File implements FileInterface
30
{
31
    /**
32
     * @var int
33
     */
34
    protected int $id;
35
36
    /**
37
     * @var string
38
     */
39
    protected string $uuid;
40
41
    /**
42
     * @var string
43
     */
44
    protected string $filename;
45
46
    /**
47
     * @var int
48
     */
49
    protected int $filesize;
50
51
    /**
52
     * @var string
53
     */
54
    protected string $mimeType = '';
55
56
    /**
57
     * @var string|null
58
     */
59
    protected ?string $extension = null;
60
61
    /**
62
     * @var string
63
     */
64
    protected ?string $path = null;
65
66
    /**
67
     * @var string|null
68
     */
69
    protected ?string $collection = null;
70
71
    /**
72
     * @var string
73
     */
74
    protected string $storage = 'local';
75
76
    /**
77
     * @var array
78
     */
79
    protected array $metadata = [];
80
81
    /**
82
     * @var string|null
83
     */
84
    protected ?string $model = null;
85
86
    /**
87
     * @var string|null
88
     */
89
    protected ?string $modelId = null;
90
91
    /**
92
     * Source file to be stored in our system
93
     *
94
     * @var mixed
95
     */
96
    protected $sourceFile;
97
98
    /**
99
     * @var resource
100
     */
101
    protected $resource;
102
103
    /**
104
     * @var string
105
     */
106
    protected string $url = '';
107
108
    /**
109
     * @var array
110
     */
111
    protected array $variants = [];
112
113
    /**
114
     * Creates a new instance
115
     *
116
     * @param string $filename Filename
117
     * @param int $filesize Filesize
118
     * @param string $mimeType Mime Type
119
     * @param string $storage Storage config name
120
     * @param string|null $collection Collection name
121
     * @param string|null $model Model name
122
     * @param string|null $modelId Model id
123
     * @param array $variants Variants
124
     * @param array $metadata Meta data
125
     * @param resource|null $resource
126
     * @return self
127
     */
128 10
    public static function create(
129
        string $filename,
130
        int $filesize,
131
        string $mimeType,
132
        string $storage,
133
        ?string $collection = null,
134
        ?string $model = null,
135
        ?string $modelId = null,
136
        array $metadata = [],
137
        array $variants = [],
138
        $resource = null
139
    ): self {
140 10
        $that = new self();
141
142 10
        $that->filename = $filename;
143 10
        $that->filesize = $filesize;
144 10
        $that->mimeType = $mimeType;
145 10
        $that->storage = $storage;
146 10
        $that->model = $model;
147 10
        $that->modelId = $modelId;
148 10
        $that->collection = $collection;
149 10
        $that->variants = $variants;
150 10
        $that->metadata = $metadata;
151
152 10
        if ($resource !== null) {
153
            $that = $that->withResource($resource);
154
        }
155
156 10
        $extension = pathinfo($filename, PATHINFO_EXTENSION);
157 10
        $that->extension = empty($extension) ? null : (string)$extension;
158
159 10
        return $that;
160
    }
161
162
    /**
163
     * Storage name
164
     *
165
     * @return string
166
     */
167 1
    public function storage(): string
168
    {
169 1
        return $this->storage;
170
    }
171
172
    /**
173
     * UUID of the file
174
     *
175
     * @param string $uuid UUID string
176
     * @return self
177
     */
178 8
    public function withUuid(string $uuid): self
179
    {
180 8
        $that = clone $this;
181 8
        $that->uuid = $uuid;
182
183 8
        return $that;
184
    }
185
186
    /**
187
     * Stream resource that should be stored
188
     *
189
     * @return resource|null
190
     */
191 2
    public function resource()
192
    {
193 2
        return $this->resource;
194
    }
195
196
    /**
197
     * Same as withResource() but takes a file path
198
     *
199
     * @param string $file File
200
     * @return self
201
     */
202
    public function withFile(string $file): self
203
    {
204
        $resource = fopen($file, 'rb');
205
206
        return $this->withResource($resource);
207
    }
208
209
    /**
210
     * @param mixed $resource
211
     */
212 9
    protected function assertStreamResource($resource): void
213
    {
214
        if (
215 9
            !is_resource($resource)
216 9
            || get_resource_type($resource) !== 'stream'
217
        ) {
218
            throw InvalidStreamResourceException::create();
219
        }
220 9
    }
221
222
    /**
223
     * Stream resource of the file to be stored
224
     *
225
     * @param resource $resource Stream Resource
226
     * @return self
227
     */
228 9
    public function withResource($resource): self
229
    {
230 9
        $this->assertStreamResource($resource);
231
232 9
        $that = clone $this;
233 9
        $that->resource = $resource;
234
235 9
        return $that;
236
    }
237
238
    /**
239
     * Assign a model and model id to a file
240
     *
241
     * @param string $model Model
242
     * @param string|int $modelId Model ID, UUID string or integer
243
     * @return $this
244
     */
245 6
    public function belongsToModel(string $model, $modelId): self
246
    {
247 6
        $this->model = $model;
248 6
        $this->modelId = $modelId;
249
250 6
        return $this;
251
    }
252
253
    /**
254
     * Adds the file to a collection
255
     *
256
     * @param string $collection Collection
257
     * @return $this
258
     */
259 3
    public function addToCollection(string $collection): self
260
    {
261 3
        $this->collection = $collection;
262
263 3
        return $this;
264
    }
265
266
    /**
267
     * Sets the path, immutable
268
     *
269
     * @param string $path Path to the file
270
     * @return $this
271
     */
272 1
    public function withPath(string $path): self
273
    {
274 1
        $that = clone $this;
275 1
        $that->path = $path;
276
277 1
        return $that;
278
    }
279
280
    /**
281
     * Filename
282
     *
283
     * @param string $filename Filename
284
     * @return self
285
     */
286 2
    public function withFilename(string $filename): self
287
    {
288 2
        $that = clone $this;
289 2
        $that->filename = $filename;
290
291 2
        $extension = pathinfo($filename, PATHINFO_EXTENSION);
292 2
        $that->extension = empty($extension) ? null : (string)$extension;
293
294 2
        return $that;
295
    }
296
297
    /**
298
     * The collections name this file belongs into
299
     *
300
     * @return string|null
301
     */
302 7
    public function collection(): ?string
303
    {
304 7
        return $this->collection;
305
    }
306
307
    /**
308
     * Model name
309
     *
310
     * @return string|null
311
     */
312 8
    public function model(): ?string
313
    {
314 8
        return $this->model;
315
    }
316
317
    /**
318
     * Model ID
319
     *
320
     * @return string|null
321
     */
322 7
    public function modelId(): ?string
323
    {
324 7
        return $this->modelId;
325
    }
326
327
    /**
328
     * Size of the file in bytes
329
     *
330
     * @return int
331
     */
332 1
    public function filesize(): int
333
    {
334 1
        return $this->filesize;
335
    }
336
337
    /**
338
     * Returns a human readable file size
339
     *
340
     * @return string
341
     */
342 1
    public function readableSize(): string
343
    {
344 1
        $i = floor(log($this->filesize, 1024));
345 1
        $round = (string)round($this->filesize / (1024 ** $i), [0, 0, 2, 2, 3][$i]);
346
347 1
        return $round . ['B','kB','MB','GB','TB'][$i];
348
    }
349
350
    /**
351
     * @return string|null
352
     */
353 7
    public function extension(): ?string
354
    {
355 7
        return $this->extension;
356
    }
357
358
    /**
359
     * @return string
360
     */
361 7
    public function mimeType(): string
362
    {
363 7
        return $this->mimeType;
364
    }
365
366
    /**
367
     * @return string
368
     */
369 7
    public function filename(): string
370
    {
371 7
        return $this->filename;
372
    }
373
374
    /**
375
     * @return string
376
     */
377 7
    public function uuid(): string
378
    {
379 7
        return $this->uuid;
380
    }
381
382
    /**
383
     * @return string
384
     */
385 4
    public function path(): string
386
    {
387 4
        if ($this->path === null) {
388 1
            throw new RuntimeException(
389 1
                'Path has not been set'
390
            );
391
        }
392
393 3
        return $this->path;
394
    }
395
396
    /**
397
     * Builds the path for this file
398
     *
399
     * @param \Phauthentic\Infrastructure\Storage\PathBuilder\PathBuilderInterface $pathBuilder Path Builder
400
     * @return $this
401
     */
402 3
    public function buildPath(PathBuilderInterface $pathBuilder): self
403
    {
404 3
        $that = clone $this;
405 3
        $that->path = $pathBuilder->path($this);
406
407 3
        return $that;
408
    }
409
410
    /**
411
     * @param array $metadata Meta data
412
     * @return $this
413
     */
414 1
    public function withMetadata(array $metadata): self
415
    {
416 1
        $that = clone $this;
417 1
        $that->metadata = $metadata;
418
419 1
        return $that;
420
    }
421
422
    /**
423
     * @param string $name Name
424
     * @param mixed $data Data
425
     * @return $this
426
     */
427 2
    public function withMetadataKey(string $name, $data): self
428
    {
429 2
        $that = clone $this;
430 2
        $that->metadata[$name] = $data;
431
432 2
        return $that;
433
    }
434
435
    /**
436
     * @param string $name Name
437
     * @return $this
438
     */
439 1
    public function withoutMetadataKey(string $name): self
440
    {
441 1
        $that = clone $this;
442 1
        unset($that->metadata[$name]);
443
444 1
        return $that;
445
    }
446
447
    /**
448
     * @return $this
449
     */
450 1
    public function withoutMetadata(): self
451
    {
452 1
        $that = clone $this;
453 1
        $that->metadata = [];
454
455 1
        return $that;
456
    }
457
458
    /**
459
     * @return array
460
     */
461 1
    public function metadata(): array
462
    {
463 1
        return $this->metadata;
464
    }
465
466
    /**
467
     * @return bool
468
     */
469 1
    public function hasVariants(): bool
470
    {
471 1
        return !empty($this->variants);
472
    }
473
474
    /**
475
     * @param string $name Name
476
     * @return bool
477
     */
478 1
    public function hasVariant(string $name): bool
479
    {
480 1
        return isset($this->variants[$name]);
481
    }
482
483
    /**
484
     * @return array
485
     */
486 3
    public function variants(): array
487
    {
488 3
        return $this->variants;
489
    }
490
491
    /**
492
     * Returns a variant by name
493
     *
494
     * @param string $name Name
495
     * @return array
496
     */
497
    public function variant(string $name): array
498
    {
499
        if (!isset($this->variants[$name])) {
500
            throw VariantDoesNotExistException::withName($name);
501
        }
502
503
        return $this->variants[$name];
504
    }
505
506
    /**
507
     * Adds a variant
508
     *
509
     * @param string $name Name
510
     * @param array $data Data
511
     * @return $this
512
     */
513 1
    public function withVariant(string $name, array $data): self
514
    {
515 1
        $that = clone $this;
516 1
        $that->variants[$name] = $data;
517
518 1
        return $that;
519
    }
520
521
    /**
522
     * Gets the paths for all variants
523
     *
524
     * @return array
525
     */
526
    public function variantPaths(): array
527
    {
528
        $paths = [];
529
        foreach ($this->variants as $variant => $data) {
530
            if (isset($data['path'])) {
531
                $paths[$variant] = $data['path'];
532
            }
533
        }
534
535
        return $paths;
536
    }
537
538
    /**
539
     * Sets many variants at once
540
     *
541
     * @param array $variants Variants
542
     * @param bool $merge Merge Variants, default is true
543
     * @return $this
544
     */
545 2
    public function withVariants(array $variants, bool $merge = true): self
546
    {
547 2
        $that = clone $this;
548 2
        $that->variants = array_merge_recursive(
549 2
            $merge ? $that->variants : [],
550
            $variants
551
        );
552
553 2
        return $that;
554
    }
555
556
    /**
557
     * @inheritDoc
558
     */
559
    public function buildUrl(UrlBuilderInterface $urlBuilder): self
560
    {
561
        $this->url = $urlBuilder->url($this);
562
563
        return $this;
564
    }
565
566
    /**
567
     * @inheritDoc
568
     */
569
    public function url(): string
570
    {
571
        return $this->url;
572
    }
573
574
    /**
575
     * @inheritDoc
576
     */
577
    public function withUrl(string $url): self
578
    {
579
        $that = clone $this;
580
        $that->url = $url;
581
582
        return $that;
583
    }
584
585
    /**
586
     * @return array
587
     */
588 1
    public function toArray(): array
589
    {
590
        return [
591 1
            'uuid' => $this->uuid,
592 1
            'filename' => $this->filename,
593 1
            'filesize' => $this->filesize,
594 1
            'mimeType' => $this->mimeType,
595 1
            'extension' => $this->extension,
596 1
            'path' => $this->path,
597 1
            'model' => $this->model,
598 1
            'modelId' => $this->modelId,
599 1
            'collection' => $this->collection,
600 1
            'readableSize' => $this->readableSize(),
601 1
            'variants' => $this->variants,
602 1
            'metaData' => $this->metadata,
603 1
            'url' => $this->url
604
        ];
605
    }
606
607
    /**
608
     * @inheritDoc
609
     */
610 1
    public function jsonSerialize()
611
    {
612 1
        return $this->toArray();
613
    }
614
}
615