Factory::targetByKey()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
c 1
b 0
f 0
dl 0
loc 20
ccs 12
cts 12
cp 1
rs 9.2222
cc 6
nc 6
nop 2
crap 6
1
<?php
2
3
namespace kalanis\kw_storage\Access;
4
5
6
use kalanis\kw_storage\Interfaces;
7
use kalanis\kw_storage\Interfaces\IStorage;
8
use kalanis\kw_storage\Storage;
9
use kalanis\kw_storage\Storage\Key;
10
use kalanis\kw_storage\Storage\Target;
11
use kalanis\kw_storage\StorageException;
12
use kalanis\kw_storage\Traits\TLang;
13
use ReflectionClass;
14
use ReflectionException;
15
16
17
/**
18
 * Class Factory
19
 * @package kalanis\kw_storage\Access
20
 */
21
class Factory
22
{
23
    use TLang;
24
25
    /** @var array<string|int, class-string> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string|int, class-string> at position 6 could not be parsed: Unknown type name 'class-string' at position 6 in array<string|int, class-string>.
Loading history...
26
    protected array $targetMap = [
27
        10 => Target\Memory::class,
28
        20 => Target\Volume::class,
29
        22 => Target\VolumeTargetFlat::class,
30
        'mem' => Target\Memory::class,
31
        'memory' => Target\Memory::class,
32
        'vol' => Target\Volume::class,
33
        'volume' => Target\Volume::class,
34
        'volume::local' => Target\Volume::class,
35
        'local' => Target\Volume::class,
36
        'volume::flat' => Target\VolumeTargetFlat::class,
37
    ];
38
39 34
    public function __construct(?Interfaces\IStTranslations $lang = null)
40
    {
41 34
        $this->setStLang($lang);
42
    }
43
44
    /**
45
     * @param mixed $params
46
     * @throws StorageException
47
     * @return IStorage
48
     */
49 32
    public function getStorage($params): IStorage
50
    {
51 32
        $key = $target = null;
52 32
        if (is_object($params)) {
53
            // IStorage -> thru
54
            // IKey -> select storage, return combination
55
            // ITarget -> select key, return combination
56
57 8
            if ($params instanceof IStorage) {
58 1
                return $params;
59
60 7
            } elseif ($params instanceof Interfaces\Target\IKey) {
61 5
                $key = $params;
62 5
                $target = $this->targetByKey($key);
63
64 2
            } elseif ($params instanceof Interfaces\Target\ITarget) {
65 1
                $target = $params;
66 6
                $key = new Key\DefaultKey();
67
            }
68
69 24
        } elseif (is_string($params)) {
70
            // string -> key as path prefix, target is always volume
71 1
            $key = $this->whichKey(['storage_key' => $params]);
72 1
            $target = new Target\Volume($this->getStLang());
73
74 23
        } elseif (is_array($params)) {
75 20
            if (isset($params['storage'])) {
76 1
                return $this->getStorage($params['storage']);
77
            }
78
            // array -> params decide which storage library will be initialized
79 20
            $key = $this->whichKey($params);
80 19
            $target = $this->targetByKey($key, $params);
81
82
        }
83
        // int, bool, etc. -> exception
84
85 29
        if ($key && $target) {
86 25
            if ($target instanceof Interfaces\Target\ITargetVolume) {
87 17
                return new Storage\StorageDirs($key, $target);
88
            }
89 9
            return new Storage\Storage($key, $target);
90
        }
91 4
        throw new StorageException($this->getStLang()->stConfigurationUnavailable());
92
    }
93
94
    /**
95
     * @param Interfaces\Target\IKey $key
96
     * @param array<string|int, string|int|float|object|bool|array<string|int|float|object>> $params
97
     * @throws StorageException
98
     * @return Interfaces\Target\ITarget
99
     */
100 24
    protected function targetByKey(Interfaces\Target\IKey $key, array $params = []): Interfaces\Target\ITarget
101
    {
102
        try {
103 24
            return $this->whichTarget($params);
104 18
        } catch (StorageException $ex) {
105
            // nothing found - use this
106
        }
107 18
        if ($key instanceof Key\ArrayKey) {
108 11
            return new Target\Volume($this->getStLang());
109
        }
110 7
        if ($key instanceof Key\DirKey) {
111 2
            return new Target\Volume($this->getStLang());
112
        }
113 5
        if ($key instanceof Key\StaticPrefixKey) {
114 1
            return new Target\Volume($this->getStLang());
115
        }
116 4
        if ($key instanceof Key\DefaultKey) {
117 3
            return new Target\Memory($this->getStLang());
118
        }
119 1
        throw new StorageException($this->getStLang()->stConfigurationUnavailable());
120
    }
121
122
    /**
123
     * @param array<string|int, string|int|float|object|bool|array<string|int|float|object>> $params
124
     * @throws StorageException
125
     * @return Interfaces\Target\IKey
126
     */
127 21
    protected function whichKey(array $params): Interfaces\Target\IKey
128
    {
129 21
        if (isset($params['storage_key'])) {
130 21
            if (is_object($params['storage_key'])) {
131 2
                if ($params['storage_key'] instanceof Interfaces\Target\IKey) {
132 1
                    return $params['storage_key'];
133
                }
134 1
                throw new StorageException($this->getStLang()->stConfigurationUnavailable());
135
            }
136 19
            if (is_array($params['storage_key'])) {
137 16
                $separator = DIRECTORY_SEPARATOR;
138 16
                if (isset($params['storage_delimiter'])) {
139 1
                    $separator = strval($params['storage_delimiter']);
140
                }
141 16
                $strArr = array_map('strval', $params['storage_key']);
142 16
                return new Key\ArrayKey($strArr, $separator);
143
            }
144 3
            if (is_string($params['storage_key']) && ($pt = realpath($params['storage_key']))) {
145 2
                return new Key\DirKey($pt . DIRECTORY_SEPARATOR);
146
            }
147
        }
148 1
        return new Key\DefaultKey();
149
    }
150
151
    /**
152
     * @param array<string|int, string|int|float|object|bool|array<string|int|float|object>> $params
153
     * @throws StorageException
154
     * @return Interfaces\Target\ITarget
155
     */
156 24
    protected function whichTarget(array $params): Interfaces\Target\ITarget
157
    {
158 24
        if (isset($params['storage_target'])) {
159 14
            if (is_object($params['storage_target'])) {
160 2
                if ($params['storage_target'] instanceof Interfaces\Target\ITarget) {
161 1
                    return $params['storage_target'];
162
                }
163 1
                throw new StorageException($this->getStLang()->stConfigurationUnavailable());
164
            }
165 12
            if (is_string($params['storage_target']) || is_int($params['storage_target'])) {
166 12
                if (isset($this->targetMap[$params['storage_target']])) {
167
                    try {
168 9
                        $reflection = new ReflectionClass($this->targetMap[$params['storage_target']]);
169 8
                        $class = $reflection->newInstance($this->getStLang());
170 3
                    } catch (ReflectionException $ex) {
171 3
                        throw new StorageException($ex->getMessage(), $ex->getCode(), $ex);
172
                    }
173 6
                    if ($class instanceof Interfaces\Target\ITarget) {
174 5
                        return $class;
175
                    } else {
176 1
                        throw new StorageException($this->getStLang()->stConfigurationUnavailable());
177
                    }
178
                }
179
            }
180
        }
181 13
        throw new StorageException($this->getStLang()->stConfigurationUnavailable());
182
    }
183
}
184