Passed
Pull Request — master (#407)
by Kirill
06:33
created

FileSystemInfo   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 51
c 1
b 0
f 0
dl 0
loc 177
rs 10
wmc 19

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getResolverClass() 0 3 1
A getOptionType() 0 7 2
A validateOptionByType() 0 9 2
A __construct() 0 18 3
A getAdapterClass() 0 3 1
A getName() 0 3 1
A validateInfoSufficient() 0 11 3
A isAdvancedUsage() 0 9 3
A prepareOptions() 0 16 3
1
<?php
2
3
/**
4
 * This file is part of Spiral Framework package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Storage\Config\DTO\FileSystemInfo;
13
14
use Spiral\Storage\Exception\ConfigException;
15
use Spiral\Storage\Config\DTO\Traits\OptionsTrait;
16
use Spiral\Storage\Exception\StorageException;
17
use Spiral\Storage\Config\DTO\Traits\ClassBasedTrait;
18
19
abstract class FileSystemInfo implements FileSystemInfoInterface, ClassBasedInterface, OptionsBasedInterface
20
{
21
    use ClassBasedTrait;
22
    use OptionsTrait;
23
24
    protected const REQUIRED_OPTIONS = [];
25
26
    protected const ADDITIONAL_OPTIONS = [];
27
28
    protected const FILE_SYSTEM_INFO_TYPE = '';
29
30
    /**
31
     * @var string
32
     */
33
    protected $name;
34
35
    /**
36
     * @var string
37
     */
38
    protected $adapter;
39
40
    /**
41
     * @var string
42
     */
43
    protected $resolver;
44
45
    /**
46
     * @param string $name
47
     * @param array $info
48
     *
49
     * @throws StorageException
50
     */
51
    public function __construct(string $name, array $info)
52
    {
53
        $this->validateInfoSufficient($name, $info);
54
55
        $this->name = $name;
56
57
        $this->checkClass($info[static::ADAPTER_KEY], \sprintf('Filesystem %s adapter', $this->name));
58
        $this->adapter = $info[static::ADAPTER_KEY];
59
60
        if (array_key_exists(static::RESOLVER_KEY, $info)) {
61
            $this->checkClass($info[static::RESOLVER_KEY], \sprintf('Filesystem %s resolver', $this->name));
62
            $this->resolver = $info[static::RESOLVER_KEY];
63
        }
64
65
        $this->prepareOptions($info[OptionsBasedInterface::OPTIONS_KEY]);
66
67
        if ($this instanceof SpecificConfigurableFileSystemInfo) {
68
            $this->constructSpecific($info);
69
        }
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75
    public function getAdapterClass(): string
76
    {
77
        return $this->adapter;
78
    }
79
80
    /**
81
     * @inheritDoc
82
     */
83
    public function getResolverClass(): string
84
    {
85
        return $this->resolver;
86
    }
87
88
    /**
89
     * @inheritDoc
90
     */
91
    public function getName(): string
92
    {
93
        return $this->name;
94
    }
95
96
    /**
97
     * @inheritDoc
98
     */
99
    public function isAdvancedUsage(): bool
100
    {
101
        foreach (static::ADDITIONAL_OPTIONS as $optionalOption => $type) {
102
            if ($this->hasOption($optionalOption)) {
103
                return true;
104
            }
105
        }
106
107
        return false;
108
    }
109
110
    /**
111
     * Validate and prepare options
112
     *
113
     * @param array $options
114
     *
115
     * @throws ConfigException
116
     */
117
    protected function prepareOptions(array $options): void
118
    {
119
        $this->validateRequiredOptions(
120
            array_keys(static::REQUIRED_OPTIONS),
121
            $options,
122
            \sprintf(' for filesystem `%s`', $this->getName())
123
        );
124
125
        foreach ($options as $optionKey => $option) {
126
            if (($type = $this->getOptionType($optionKey)) === null) {
127
                continue;
128
            }
129
130
            $this->validateOptionByType($optionKey, $type, $option);
131
132
            $this->options[$optionKey] = $this->processOptionByType($option, $type);
133
        }
134
    }
135
136
    /**
137
     * Validate if description contains all required options
138
     *
139
     * @param string $fs
140
     * @param array $info
141
     *
142
     * @throws ConfigException
143
     */
144
    protected function validateInfoSufficient(string $fs, array $info): void
145
    {
146
        if (!array_key_exists(static::ADAPTER_KEY, $info)) {
147
            throw new ConfigException(
148
                \sprintf('Filesystem `%s` needs adapter class defined', $fs)
149
            );
150
        }
151
152
        if (!array_key_exists(OptionsBasedInterface::OPTIONS_KEY, $info)) {
153
            throw new ConfigException(
154
                \sprintf('Filesystem `%s` needs options defined', $fs)
155
            );
156
        }
157
    }
158
159
    /**
160
     * Validate option type is correct
161
     *
162
     * @param string $optionLabel
163
     * @param string $optionType
164
     * @param $optionVal
165
     *
166
     * @throws ConfigException
167
     */
168
    protected function validateOptionByType(string $optionLabel, string $optionType, $optionVal): void
169
    {
170
        if (!$this->isOptionHasRequiredType($optionLabel, $optionVal, $optionType)) {
171
            throw new ConfigException(
172
                \sprintf(
173
                    'Option `%s` defined in wrong format for filesystem `%s`, %s expected',
174
                    $optionLabel,
175
                    $this->getName(),
176
                    $optionType
177
                )
178
            );
179
        }
180
    }
181
182
    /**
183
     * Get expected option type by label
184
     *
185
     * @param string $option
186
     *
187
     * @return string|null
188
     */
189
    protected function getOptionType(string $option): ?string
190
    {
191
        if (array_key_exists($option, static::REQUIRED_OPTIONS)) {
192
            return static::REQUIRED_OPTIONS[$option];
193
        }
194
195
        return static::ADDITIONAL_OPTIONS[$option] ?? null;
196
    }
197
}
198