StorageService::setAdapterConfigFromArray()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 5.9256

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 6
c 2
b 0
f 0
nc 4
nop 1
dl 0
loc 12
ccs 4
cts 6
cp 0.6667
crap 5.9256
rs 9.6111
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
     * @return void
126
     */
127
    public function addAdapterConfig(string $name, string $class, array $options)
128
    {
129
        $this->adapterConfig[$name] = [
130
            'class' => $class,
131
            'options' => $options
132
        ];
133
    }
134
135
    /**
136
     * Sets the adapter configuration to lazy load them later
137
     *
138
     * @param array $config Config
139
     * @return void
140 2
     */
141
    public function setAdapterConfigFromArray(array $config): void
142 2
    {
143 2
        foreach ($config as $name => $options) {
144
            if (!isset($options['class'])) {
145
                throw new RuntimeException('Adapter class or name is missing');
146
            }
147 2
148
            if (!isset($options['options']) || !is_array($options['options'])) {
149
                throw new RuntimeException('Adapter options must be an array');
150
            }
151 2
152
            $this->adapterConfig[$name] = $options;
153 2
        }
154
    }
155
156
    /**
157
     * @param \League\Flysystem\Config|null $config Config
158
     * @return \League\Flysystem\Config
159 1
     */
160
    protected function makeConfigIfNeeded(?Config $config)
161 1
    {
162 1
        if ($config === null) {
163
            $config = new Config();
164
        }
165 1
166
        return $config;
167
    }
168
169
    /**
170
     * @inheritDoc
171 1
     */
172
    public function storeResource(string $adapter, string $path, $resource, ?Config $config = null): array
173 1
    {
174 1
        $config = $this->makeConfigIfNeeded($config);
175
        $result = $this->adapter($adapter)->writeStream($path, $resource, $config);
176 1
177
        if ($result === false) {
178
            throw new StorageException(sprintf(
179
                'Failed to store resource stream to in `%s` with path `%s`',
180
                $adapter,
181
                $path
182
            ));
183
        }
184 1
185
        return $result;
186
    }
187
188
    /**
189
     * @inheritDoc
190 1
     */
191
    public function storeFile(string $adapter, string $path, string $file, ?Config $config = null): array
192 1
    {
193 1
        $config = $this->makeConfigIfNeeded($config);
194
        $result = $this->adapter($adapter)->write($path, file_get_contents($file), $config);
195 1
196
        if ($result === false) {
197
            throw new StorageException(sprintf(
198
                'Failed to store file `%s` in `%s` with path `%s`',
199
                $file,
200
                $adapter,
201
                $path
202
            ));
203
        }
204 1
205
        return $result;
206
    }
207
208
    /**
209
     * @param string $adapter Adapter
210
     * @param string $path Path
211
     * @return bool
212 1
     */
213
    public function fileExists(string $adapter, string $path): bool
214 1
    {
215
        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...
216
    }
217
218
    /**
219
     * @param string $adapter Name
220
     * @param string $path File to delete
221
     * @return bool
222 1
     */
223
    public function removeFile(string $adapter, string $path): bool
224 1
    {
225
        return $this->adapter($adapter)->delete($path);
226
    }
227
}
228