Test Failed
Push — develop ( 50185e...a702bc )
by Florian
05:03
created

FileStorage::remove()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 15
ccs 0
cts 8
cp 0
crap 12
rs 10
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 InvalidArgumentException;
20
use League\Flysystem\AdapterInterface;
21
use League\Flysystem\Config;
22
use Phauthentic\Infrastructure\Storage\PathBuilder\PathBuilderInterface;
23
use Phauthentic\Infrastructure\Storage\Processor\Exception\VariantDoesNotExistException;
24
use Phauthentic\Infrastructure\Storage\Processor\Exception\VariantException;
25
use Phauthentic\Infrastructure\Storage\UrlBuilder\UrlBuilderInterface;
26
27
/**
28
 * File Storage
29
 */
30
class FileStorage implements FileStorageInterface
31
{
32
    /**
33
     * @var array
34
     */
35
    protected array $callbacks = [
36
        'beforeSave' => [],
37
        'afterSave' => [],
38
        'beforeRemove' => [],
39
        'afterRemove' => [],
40
    ];
41
42
    /**
43
     * @var \Phauthentic\Infrastructure\Storage\PathBuilder\PathBuilderInterface|null
44
     */
45
    protected ?PathBuilderInterface $pathBuilder;
46
47
    /**
48
     * @var \Phauthentic\Infrastructure\Storage\UrlBuilder\UrlBuilderInterface|null
49
     */
50
    protected ?UrlBuilderInterface $urlBuilder;
51
52
    /**
53
     * @var \Phauthentic\Infrastructure\Storage\StorageServiceInterface
54
     */
55
    protected StorageServiceInterface $storageService;
56
57
    /**
58
     * Constructor
59
     *
60
     * @param \Phauthentic\Infrastructure\Storage\StorageServiceInterface $storageService Storage Service
61
     * @param \Phauthentic\Infrastructure\Storage\PathBuilder\PathBuilderInterface|null $pathBuilder Path Builder
62
     * @param \Phauthentic\Infrastructure\Storage\UrlBuilder\UrlBuilderInterface|null $urlBuilder Path Builder
63
     */
64 1
    public function __construct(
65
        StorageServiceInterface $storageService,
66
        ?PathBuilderInterface $pathBuilder = null,
67
        ?UrlBuilderInterface $urlBuilder = null
68
    ) {
69 1
        $this->storageService = $storageService;
70 1
        $this->pathBuilder = $pathBuilder;
71 1
        $this->urlBuilder = $urlBuilder;
72 1
    }
73
74
    /**
75
     * @param string $name Name of the callback
76
     * @return void
77
     */
78
    protected function checkCallbackName(string $name): void
79 1
    {
80
        if (!array_key_exists($name, $this->callbacks)) {
81 1
            throw new InvalidArgumentException(sprintf(
82
                'Invalid callback `%s`, only %s are valid',
83
                $name,
84
                implode(', ', array_keys($this->callbacks))
85
            ));
86
        }
87
    }
88 1
89
    /**
90
     * Adds a callback
91
     *
92 1
     * @param string $name
93
     * @param callable $callable Callable
94
     * @return void
95
     */
96
    public function addCallback($name, callable $callable): void
97
    {
98 1
        $this->checkCallbackName($name);
99
        $this->callbacks[$name][] = $callable;
100 1
    }
101
102 1
    /**
103 1
     * @param string $name Name of the callback
104
     * @param \Phauthentic\Infrastructure\Storage\FileInterface $file File
105
     * @return \Phauthentic\Infrastructure\Storage\FileInterface
106 1
     */
107
    public function runCallbacks(string $name, FileInterface $file): FileInterface
108
    {
109
        $this->checkCallbackName($name);
110 1
111
        foreach ($this->callbacks[$name] as $callback) {
112 1
            $file = $callback($file);
113 1
        }
114
115 1
        return $file;
116
    }
117
118
    /**
119
     * @inheritDoc
120
     */
121 1
    public function store(FileInterface $file): FileInterface
122
    {
123 1
        $config = new Config();
124
125
        if ($this->pathBuilder !== null) {
126 1
            $file = $file->buildPath($this->pathBuilder);
127
        }
128
129
        if ($this->urlBuilder !== null) {
130
            $file = $file->buildUrl($this->urlBuilder);
131
        }
132
133 1
        $file = $this->runCallbacks('beforeSave', $file);
134
135 1
        $storage = $this->getStorage($file->storage());
136
        $storage->writeStream($file->path(), $file->resource(), $config);
137
138
        return $this->runCallbacks('afterSave', $file);
139
    }
140
141
    /**
142
     * @inheritDoc
143
     */
144
    public function remove(FileInterface $file): FileInterface
145
    {
146
        $file = $this->runCallbacks('beforeRemove', $file);
147
148
        // Delete all variants of the file
149
        foreach ($file->variants() as $variant) {
150
            if (!empty($variant['path'])) {
151
                $this->getStorage($file->storage())->delete($variant['path']);
152
            }
153
        }
154
155
        // Delete the file
156
        $this->getStorage($file->storage())->delete($file->path());
157
158
        return $this->runCallbacks('afterRemove', $file);
159
    }
160
161
    /**
162
     * @inheritDoc
163
     */
164
    public function removeVariant(FileInterface $file, string $name): FileInterface
165
    {
166
        if (!$file->hasVariant($name)) {
167
            throw VariantDoesNotExistException::withName($name);
168
        }
169 1
170
        $variant = $file->variant($name);
171 1
        if (empty($variant['path'])) {
172
            throw new VariantException(sprintf(
173
                'Variant `%s` is missing a path',
174
                $name
175
            ));
176
        }
177
178
        $this->getStorage($file->storage())->delete($variant['path']);
179
180
        $variants = $file->variants();
181
        unset($variants[$name]);
182
183
        return $file->withVariants($variants, false);
184
    }
185
186
    /**
187
     * Gets the storage abstraction to use
188
     *
189
     * @param string $storage Storage name to use
190
     * @return \League\Flysystem\AdapterInterface
191
     */
192
    public function getStorage(string $storage): AdapterInterface
193
    {
194
        return $this->storageService->adapter($storage);
195
    }
196
}
197