Failed Conditions
Pull Request — master (#4)
by Florian
02:57 queued 12s
created

StorageService::storeFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0932

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 15
ccs 5
cts 7
cp 0.7143
crap 2.0932
rs 9.9666
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 League\Flysystem\AdapterInterface;
20
use League\Flysystem\Config;
21
use Phauthentic\Infrastructure\Storage\Exception\StorageException;
22
use Phauthentic\Infrastructure\Storage\Factories\Exception\FactoryNotFoundException;
23
use RuntimeException;
24
25
/**
26
 * StorageFactory - Manages and instantiates storage engine adapters.
27
 *
28
 * @author Florian Krämer
29
 * @copyright 2012 - 2020 Florian Krämer
30
 * @license MIT
31
 */
32
class StorageService implements StorageServiceInterface
33
{
34
    /**
35
     * @var array
36
     */
37
    protected array $adapterConfig = [];
38
39
    /**
40
     * @var \Phauthentic\Infrastructure\Storage\AdapterCollectionInterface
41
     */
42
    protected AdapterCollectionInterface $adapterCollection;
43
44
    /**
45
     * @var \Phauthentic\Infrastructure\Storage\StorageAdapterFactoryInterface
46
     */
47
    protected StorageAdapterFactoryInterface $adapterFactory;
48
49
    /**
50
     * Constructor
51
     *
52
     * @param \Phauthentic\Infrastructure\Storage\StorageAdapterFactoryInterface $adapterFactory Adapter Factory
53
     * @param \Phauthentic\Infrastructure\Storage\AdapterCollectionInterface|null $factoryCollection Factory Collection
54
     */
55 2
    public function __construct(
56
        StorageAdapterFactoryInterface $adapterFactory,
57
        ?AdapterCollectionInterface $factoryCollection = null
58
    ) {
59 2
        $this->adapterFactory = $adapterFactory;
60 2
        $this->adapterCollection = $factoryCollection ?? new AdapterCollection();
61 2
    }
62
63
    /**
64
     * Adapter Factory
65
     *
66
     * @return \Phauthentic\Infrastructure\Storage\StorageAdapterFactoryInterface
67
     */
68 1
    public function adapterFactory(): StorageAdapterFactoryInterface
69
    {
70 1
        return $this->adapterFactory;
71
    }
72
73
    /**
74
     * @inheritDoc
75
     */
76 1
    public function adapters(): AdapterCollectionInterface
77
    {
78 1
        return $this->adapterCollection;
79
    }
80
81
    /**
82
     * @inheritDoc
83
     */
84 2
    public function adapter(string $name): AdapterInterface
85
    {
86 2
        if ($this->adapterCollection->has($name)) {
87 2
            return $this->adapterCollection->get($name);
88
        }
89
90 2
        if (!isset($this->adapterConfig[$name])) {
91
            throw FactoryNotFoundException::withName($name);
92
        }
93
94 2
        $options = $this->adapterConfig[$name];
95
96 2
        return $this->loadAdapter($name, $options['class'], $options['options']);
97
    }
98
99
    /**
100
     * Loads an adapter instance using the factory
101
     *
102
     * @param string $name Name
103
     * @param string $adapter Adapter
104
     * @param array $options
105
     * @return \League\Flysystem\AdapterInterface
106
     */
107 2
    public function loadAdapter(string $name, string $adapter, array $options): AdapterInterface
108
    {
109 2
        $adapter = $this->adapterFactory->buildStorageAdapter(
110 2
            $adapter,
111
            $options
112
        );
113
114 2
        $this->adapterCollection->add($name, $adapter);
115
116 2
        return $adapter;
117
    }
118
119
    /**
120
     * Adds an adapter config
121
     *
122
     * @param string $name
123
     * @param string $class
124
     * @param array $options
125
     */
126
    public function addAdapterConfig(string $name, string $class, array $options)
127
    {
128
        $this->adapterConfig[$name] = [
129
            'class' => $class,
130
            'options' => $options
131
        ];
132
    }
133
134
    /**
135
     * Sets the adapter configuration to lazy load them later
136
     *
137
     * @param array $config Config
138
     * @return void
139
     */
140 2
    public function setAdapterConfigFromArray(array $config): void
141
    {
142 2
        foreach ($config as $name => $options) {
143 2
            if (!isset($options['class'])) {
144
                throw new RuntimeException('Adapter class or name is missing');
145
            }
146
147 2
            if (!isset($options['options']) || !is_array($options['options'])) {
148
                throw new RuntimeException('Adapter options must be an array');
149
            }
150
151 2
            $this->adapterConfig[$name] = $options;
152
        }
153 2
    }
154
155
    /**
156
     * @param \League\Flysystem\Config|null $config Config
157
     * @return \League\Flysystem\Config
158
     */
159 1
    protected function makeConfigIfNeeded(?Config $config)
160
    {
161 1
        if ($config === null) {
162 1
            $config = new Config();
163
        }
164
165 1
        return $config;
166
    }
167
168
    /**
169
     * @inheritDoc
170
     */
171 1
    public function storeResource(string $adapter, string $path, $resource, ?Config $config = null): array
172
    {
173 1
        $config = $this->makeConfigIfNeeded($config);
174 1
        $result = $this->adapter($adapter)->writeStream($path, $resource, $config);
175
176 1
        if ($result === false) {
177
            throw new StorageException(sprintf(
178
                'Failed to store resource stream to in `%s` with path `%s`',
179
                $adapter,
180
                $path
181
            ));
182
        }
183
184 1
        return $result;
185
    }
186
187
    /**
188
     * @inheritDoc
189
     */
190 1
    public function storeFile(string $adapter, string $path, string $file, ?Config $config = null): array
191
    {
192 1
        $config = $this->makeConfigIfNeeded($config);
193 1
        $result = $this->adapter($adapter)->write($path, file_get_contents($file), $config);
194
195 1
        if ($result === false) {
196
            throw new StorageException(sprintf(
197
                'Failed to store file `%s` in `%s` with path `%s`',
198
                $file,
199
                $adapter,
200
                $path
201
            ));
202
        }
203
204 1
        return $result;
205
    }
206
207
    /**
208
     * @param string $adapter Adapter
209
     * @param string $path Path
210
     * @return bool
211
     */
212 1
    public function fileExists(string $adapter, string $path): bool
213
    {
214 1
        return $this->adapter($adapter)->has($path);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->adapter($adapter)->has($path) could return the type array|null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
215
    }
216
217
    /**
218
     * @param string $adapter Name
219
     * @param string $path File to delete
220
     * @return bool
221
     */
222 1
    public function removeFile(string $adapter, string $path): bool
223
    {
224 1
        return $this->adapter($adapter)->delete($path);
225
    }
226
}
227