Test Failed
Pull Request — master (#925)
by butschster
16:57 queued 09:14
created

ScaffolderConfig   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Test Coverage

Coverage 86.36%

Importance

Changes 0
Metric Value
wmc 26
eloc 69
dl 0
loc 210
ccs 57
cts 66
cp 0.8636
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A headerLines() 0 3 1
A declarationDirectory() 0 5 2
A classNamespace() 0 14 3
A getDeclaration() 0 6 1
A declarationClass() 0 11 2
A elementPostfix() 0 3 1
A declarationOptions() 0 3 1
A classFilename() 0 10 1
A baseNamespace() 0 9 2
A parseName() 0 13 2
A baseDirectory() 0 3 1
A joinPathChunks() 0 14 3
A getOption() 0 13 3
A classify() 0 5 1
A className() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Scaffolder\Config;
6
7
use Doctrine\Inflector\Rules\English\InflectorFactory;
8
use Spiral\Core\InjectableConfig;
9
use Spiral\Scaffolder\Exception\ScaffolderException;
10
11
/**
12
 * Configuration for default scaffolder namespaces and other rendering options.
13
 */
14
class ScaffolderConfig extends InjectableConfig
15
{
16
    public const CONFIG = 'scaffolder';
17
18
    protected array $config = [
19
        'header'       => [],
20
        'directory'    => '',
21
        'namespace'    => '',
22
        'declarations' => [],
23
        'defaults'     => [
24
            'declarations' => [],
25 21
        ],
26
    ];
27 21
28
    public function headerLines(): array
29
    {
30 21
        return $this->config['header'];
31
    }
32 21
33
    /**
34
     * @deprecated since v3.8.0.
35 21
     */
36
    public function baseDirectory(): string
37 21
    {
38
        return $this->config['directory'];
39 21
    }
40 21
41
    /**
42 21
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
43
     */
44
    public function declarationDirectory(string $element): string
45 15
    {
46
        $declaration = $this->getDeclaration($element);
47 15
48 15
        return !empty($declaration['directory']) ? $declaration['directory'] : $this->config['directory'];
49
    }
50 15
51 1
    /**
52
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
53
     */
54 15
    public function className(string $element, string $name): string
55
    {
56
        ['name' => $name] = $this->parseName($name);
57
58 15
        $class = $this->classify($name);
59
        $postfix = $this->elementPostfix($element);
60
61 21
        return \str_ends_with($class, $postfix) ? $class : $class . $postfix;
62
    }
63 21
64 21
    /**
65
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
66 21
     */
67 21
    public function classNamespace(string $element, string $name = ''): string
68 21
    {
69 21
        $localNamespace = \trim($this->getOption($element, 'namespace', ''), '\\');
70 21
        ['namespace' => $namespace] = $this->parseName($name);
71
72
        if (!empty($namespace)) {
73
            $localNamespace .= '\\' . $this->classify($namespace);
74
        }
75
76
        if (empty($this->baseNamespace($element))) {
77
            return $localNamespace;
78
        }
79
80
        return \trim($this->baseNamespace($element) . '\\' . $localNamespace, '\\');
81
    }
82
83
    /**
84
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
85
     * @param non-empty-string $name
86
     *
87
     * @return non-empty-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
88
     */
89
    public function classFilename(string $element, string $name, ?string $namespace = null): string
90
    {
91
        $elementNamespace = $namespace ?? $this->classNamespace($element, $name);
92 21
        $elementNamespace = \substr($elementNamespace, \strlen($this->baseNamespace($element)));
93
94 21
        return $this->joinPathChunks([
95
            $this->declarationDirectory($element),
96
            \str_replace('\\', '/', $elementNamespace),
97 21
            $this->className($element, $name) . '.php',
98
        ], '/');
99 21
    }
100
101
    /**
102 22
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
103
     *
104 22
     * @throws ScaffolderException
105
     */
106
    public function declarationClass(string $element): string
107
    {
108 22
        $class = $this->getOption($element, 'class');
109 22
110
        if (empty($class)) {
111
            throw new ScaffolderException(
112 14
                \sprintf("Unable to scaffold '%s', no declaration class found", $element)
113
            );
114
        }
115
116
        return $class;
117
    }
118
119
    /**
120 21
     * Declaration options.
121
     *
122 21
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
123
     */
124 21
    public function declarationOptions(string $element): array
125 1
    {
126 1
        return $this->getOption($element, 'options', []);
127
    }
128 1
129
    /**
130
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
131
     */
132 20
    private function elementPostfix(string $element): string
133
    {
134
        return $this->getOption($element, 'postfix', '');
135 23
    }
136
137 23
    /**
138 1
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
139
     * @param non-empty-string $section
140
     */
141 22
    private function getOption(string $element, string $section, mixed $default = null): mixed
142
    {
143
        $declaration = $this->getDeclaration($element);
144 21
145
        if ($declaration === []) {
146 21
            throw new ScaffolderException(\sprintf("Undefined declaration '%s'.", $element));
147 21
        }
148 21
149 21
        if (\array_key_exists($section, $declaration)) {
150 21
            return $declaration[$section];
151 21
        }
152
153 21
        return $default;
154
    }
155
156
    /**
157 21
     * Split user name into namespace and class name.
158
     *
159
     * @param non-empty-string $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
160 21
     *
161
     * @return array{namespace: string, name: non-empty-string}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{namespace: string, name: non-empty-string} at position 8 could not be parsed: Unknown type name 'non-empty-string' at position 8 in array{namespace: string, name: non-empty-string}.
Loading history...
162 21
     */
163 21
    private function parseName(string $name): array
164 21
    {
165
        $name = \str_replace('/', '\\', $name);
166
167
        if (str_contains($name, '\\')) {
168
            $names = \explode('\\', $name);
169
            $class = \array_pop($names);
170
171
            return ['namespace' => \implode('\\', $names), 'name' => $class];
172
        }
173
174
        //No user namespace
175
        return ['namespace' => '', 'name' => $name];
176
    }
177
178
    /**
179
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
180
     */
181
    private function baseNamespace(string $element): string
182
    {
183
        $declaration = $this->getDeclaration($element);
184
185
        if (\array_key_exists('baseNamespace', $declaration)) {
186
            return \trim((string) $this->getOption($element, 'baseNamespace', ''), '\\');
187
        }
188
189
        return \trim($this->config['namespace'], '\\');
190
    }
191
192
    private function joinPathChunks(array $chunks, string $joint): string
193
    {
194
        $firstChunkIterated = false;
195
        $joinedPath = '';
196
        foreach ($chunks as $chunk) {
197
            if (!$firstChunkIterated) {
198
                $firstChunkIterated = true;
199
                $joinedPath = $chunk;
200
            } else {
201
                $joinedPath = \rtrim($joinedPath, $joint) . $joint . \ltrim($chunk, $joint);
202
            }
203
        }
204
205
        return $joinedPath;
206
    }
207
208
    private function classify(string $name): string
209
    {
210
        return ( new InflectorFactory() )
211
            ->build()
212
            ->classify($name);
213
    }
214
215
    /**
216
     * @param non-empty-string $element
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
217
     */
218
    private function getDeclaration(string $element): array
219
    {
220
        $default = $this->config['defaults']['declarations'][$element] ?? [];
221
        $declaration = $this->config['declarations'][$element] ?? [];
222
223
        return $declaration + $default;
224
    }
225
}
226