Passed
Push — master ( 865ea9...f5a1ef )
by butschster
29:08 queued 21:20
created

ScaffolderConfig::declarationDirectory()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 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
        ],
26
    ];
27
28 27
    public function headerLines(): array
29
    {
30 27
        return $this->config['header'];
31
    }
32
33
    /**
34
     * @deprecated since v3.8.0.
35
     */
36
    public function baseDirectory(): string
37
    {
38
        return $this->config['directory'];
39
    }
40
41
    /**
42
     * @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 41
    public function declarationDirectory(string $element): string
45
    {
46 41
        $declaration = $this->getDeclaration($element);
47
48 41
        return !empty($declaration['directory']) ? $declaration['directory'] : $this->config['directory'];
49
    }
50
51
    /**
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 31
    public function className(string $element, string $name): string
55
    {
56 31
        ['name' => $name] = $this->parseName($name);
57
58 31
        $class = $this->classify($name);
59 31
        $postfix = $this->elementPostfix($element);
60
61 31
        return \str_ends_with($class, $postfix) ? $class : $class . $postfix;
62
    }
63
64
    /**
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
     */
67 20
    public function classNamespace(string $element, string $name = ''): string
68
    {
69 20
        $localNamespace = \trim($this->getOption($element, 'namespace', ''), '\\');
70 20
        ['namespace' => $namespace] = $this->parseName($name);
71
72 20
        if (!empty($namespace)) {
73 1
            $localNamespace .= '\\' . $this->classify($namespace);
74
        }
75
76 20
        if (empty($this->baseNamespace($element))) {
77
            return $localNamespace;
78
        }
79
80 20
        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 31
    public function classFilename(string $element, string $name, ?string $namespace = null): string
90
    {
91 31
        $elementNamespace = $namespace ?? $this->classNamespace($element, $name);
92 31
        $elementNamespace = \substr($elementNamespace, \strlen($this->baseNamespace($element)));
93
94 31
        return $this->joinPathChunks([
95 31
            $this->declarationDirectory($element),
96 31
            \str_replace('\\', '/', $elementNamespace),
97 31
            $this->className($element, $name) . '.php',
98 31
        ], '/');
99
    }
100
101
    /**
102
     * @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
     * @throws ScaffolderException
105
     */
106
    public function declarationClass(string $element): string
107
    {
108
        $class = $this->getOption($element, 'class');
109
110
        if (empty($class)) {
111
            throw new ScaffolderException(
112
                \sprintf("Unable to scaffold '%s', no declaration class found", $element)
113
            );
114
        }
115
116
        return $class;
117
    }
118
119
    /**
120
     * Declaration options.
121
     *
122
     * @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 30
    public function declarationOptions(string $element): array
125
    {
126 30
        return $this->getOption($element, 'options', []);
127
    }
128
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 31
    private function elementPostfix(string $element): string
133
    {
134 31
        return $this->getOption($element, 'postfix', '');
135
    }
136
137
    /**
138
     * @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 38
    private function getOption(string $element, string $section, mixed $default = null): mixed
142
    {
143 38
        $declaration = $this->getDeclaration($element);
144
145 38
        if ($declaration === []) {
146 1
            throw new ScaffolderException(\sprintf("Undefined declaration '%s'.", $element));
147
        }
148
149 37
        if (\array_key_exists($section, $declaration)) {
150 33
            return $declaration[$section];
151
        }
152
153 24
        return $default;
154
    }
155
156
    /**
157
     * 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
     *
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
     */
163 31
    private function parseName(string $name): array
164
    {
165 31
        $name = \str_replace('/', '\\', $name);
166
167 31
        if (str_contains($name, '\\')) {
168 1
            $names = \explode('\\', $name);
169 1
            $class = \array_pop($names);
170
171 1
            return ['namespace' => \implode('\\', $names), 'name' => $class];
172
        }
173
174
        //No user namespace
175 30
        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 33
    private function baseNamespace(string $element): string
182
    {
183 33
        $declaration = $this->getDeclaration($element);
184
185 33
        if (\array_key_exists('baseNamespace', $declaration)) {
186 1
            return \trim((string) $this->getOption($element, 'baseNamespace', ''), '\\');
187
        }
188
189 32
        return \trim($this->config['namespace'], '\\');
190
    }
191
192 31
    private function joinPathChunks(array $chunks, string $joint): string
193
    {
194 31
        $firstChunkIterated = false;
195 31
        $joinedPath = '';
196 31
        foreach ($chunks as $chunk) {
197 31
            if (!$firstChunkIterated) {
198 31
                $firstChunkIterated = true;
199 31
                $joinedPath = $chunk;
200
            } else {
201 31
                $joinedPath = \rtrim($joinedPath, $joint) . $joint . \ltrim($chunk, $joint);
202
            }
203
        }
204
205 31
        return $joinedPath;
206
    }
207
208 31
    private function classify(string $name): string
209
    {
210 31
        return ( new InflectorFactory() )
211 31
            ->build()
212 31
            ->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 49
    private function getDeclaration(string $element): array
219
    {
220 49
        $default = $this->config['defaults']['declarations'][$element] ?? [];
221 49
        $declaration = $this->config['declarations'][$element] ?? [];
222
223 49
        return $declaration + $default;
224
    }
225
}
226