Test Failed
Push — master ( 48ecae...80a31b )
by butschster
07:51
created

ScaffolderConfig::getDeclaration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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