AbstractStorage::write()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 17
nc 3
nop 2
dl 0
loc 31
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\Media\Domain\Storage;
6
7
use Assert\Assert;
8
use Damax\Media\Domain\Exception\FileAlreadyExists;
9
use Damax\Media\Domain\Exception\InvalidFile;
10
use Damax\Media\Domain\Exception\StorageFailure;
11
use Damax\Media\Domain\Model\File;
12
use Damax\Media\Domain\Model\FileInfo;
13
use Damax\Media\Domain\Model\Media;
14
use Damax\Media\Domain\Storage\Keys\Keys;
15
use Damax\Media\Type\Types;
16
17
abstract class AbstractStorage implements Storage
18
{
19
    private $types;
20
    private $keys;
21
22
    public function __construct(Types $types, Keys $keys)
23
    {
24
        $this->types = $types;
25
        $this->keys = $keys;
26
    }
27
28
    public function read(Media $media): string
29
    {
30
        return $this->readFile($media->file());
31
    }
32
33
    public function streamTo(Media $media, $stream): void
34
    {
35
        stream_copy_to_stream($this->streamFile($media->file()), $stream);
36
    }
37
38
    public function dump(Media $media, string $filename): void
39
    {
40
        file_put_contents($filename, $this->read($media));
41
    }
42
43
    public function delete(Media $media): void
44
    {
45
        if ($media->uploaded()) {
46
            $this->deleteFile($media->file());
47
        }
48
    }
49
50
    public function write(Media $media, $context = []): File
51
    {
52
        Assert::that($context)
53
            ->keyIsset('mime_type')
54
            ->keyIsset('file_size')
55
            ->keyIsset('stream')
56
        ;
57
58
        $info = FileInfo::fromArray($context);
59
60
        if (!$media->matchesInfo($info)) {
61
            throw InvalidFile::unmatchedInfo();
62
        }
63
64
        if ($media->uploaded()) {
65
            throw new FileAlreadyExists();
66
        }
67
68
        $key = $this->keys->nextKey([
69
            'prefix' => $media->type(),
70
            'mime_type' => $info->mimeType(),
71
        ]);
72
73
        $storage = $this->types
74
            ->definition($media->type())
75
            ->storage()
76
        ;
77
78
        $this->writeFile($key, $storage, $context['stream']);
79
80
        return new File($key, $storage, $info);
81
    }
82
83
    abstract protected function readFile(File $file): string;
84
85
    /**
86
     * @return resource
87
     */
88
    abstract protected function streamFile(File $file);
89
90
    abstract protected function deleteFile(File $file): void;
91
92
    /**
93
     * @throws StorageFailure
94
     */
95
    abstract protected function writeFile(string $key, string $storage, $stream): void;
96
}
97