Version3   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 258
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 258
rs 9.52
c 0
b 0
f 0
ccs 102
cts 102
cp 1
wmc 36
lcom 1
cbo 2

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B convert() 0 32 9
A supports() 0 4 1
A buildDefault() 0 15 1
B buildVersion() 0 31 6
B buildApi() 0 28 7
A buildGuide() 0 10 4
A buildTemplate() 0 13 3
A defaultVersions() 0 49 1
A defaultTemplate() 0 6 1
A validate() 0 20 2
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Configuration\Factory;
17
18
use InvalidArgumentException;
19
use phpDocumentor\Dsn;
20
use phpDocumentor\Path;
21
use SimpleXMLElement;
22
23
/**
24
 * phpDocumentor3 strategy for converting the configuration xml to an array.
25
 */
26
final class Version3 implements Strategy
27
{
28
    /**
29
     * The path to the xsd that is used for validation of the configuration file.
30
     *
31
     * @var string
32
     */
33
    private $schemaPath;
34
35
    /**
36
     * Initializes the PhpDocumentor3 strategy.
37
     */
38 8
    public function __construct(string $schemaPath)
39
    {
40 8
        $this->schemaPath = $schemaPath;
41 8
    }
42
43 8
    public function convert(SimpleXMLElement $phpDocumentor): array
44
    {
45 8
        $this->validate($phpDocumentor);
46
47 7
        $versions = [];
48 7
        $templates = [];
49
50 7
        foreach ($phpDocumentor->children() as $child) {
51 7
            switch ($child->getName()) {
52 7
                case 'version':
53 6
                    $versions[(string) $child->attributes()->number] = $this->buildVersion($child);
54 6
                    break;
55 7
                case 'template':
56 3
                    $templates[] = $this->buildTemplate($child);
57 3
                    break;
58
                default:
59 7
                    break;
60
            }
61
        }
62
63
        return [
64 7
            'phpdocumentor' => [
65 7
                'use-cache' => $phpDocumentor->{'use-cache'} ?: true,
66
                'paths' => [
67 7
                    'output' => new Dsn(((string) $phpDocumentor->paths->output) ?: 'file://build/docs'),
68 7
                    'cache' => new Path(((string) $phpDocumentor->paths->cache) ?: '/tmp/phpdoc-doc-cache'),
69
                ],
70 7
                'versions' => ($versions) ?: $this->defaultVersions(),
71 7
                'templates' => ($templates) ?: [$this->defaultTemplate()],
72
            ],
73
        ];
74
    }
75
76 1
    public function supports(SimpleXMLElement $phpDocumentor): bool
77
    {
78 1
        return (string) $phpDocumentor->attributes()->version === '3';
79
    }
80
81 1
    public static function buildDefault(): array
82
    {
83
        return [
84 1
            'phpdocumentor' => [
85 1
                'title' => 'my docs',
86
                'use-cache' => true,
87
                'paths' => [
88 1
                    'output' => new Dsn('file://build/docs'),
89 1
                    'cache' => new Path('/tmp/phpdoc-doc-cache'),
90
                ],
91 1
                'versions' => static::defaultVersions(),
0 ignored issues
show
Comprehensibility introduced by Jaapio
Since phpDocumentor\Configuration\Factory\Version3 is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
92 1
                'templates' => [static::defaultTemplate()],
0 ignored issues
show
Comprehensibility introduced by Jaapio
Since phpDocumentor\Configuration\Factory\Version3 is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
93
            ],
94
        ];
95
    }
96
97
    /**
98
     * Builds the versions part of the array from the configuration xml.
99
     */
100 6
    private function buildVersion(SimpleXMLElement $version): array
101
    {
102 6
        $apis = [];
103 6
        $guides = [];
104 6
        foreach ($version->children() as $child) {
105 6
            switch ($child->getName()) {
106 6
                case 'api':
107 4
                    $apis[] = $this->buildApi($child);
108 4
                    break;
109 6
                case 'guide':
110 3
                    $guides[] = $this->buildGuide($child);
111 3
                    break;
112
                default:
113 6
                    break;
114
            }
115
        }
116
117
        $version = [
118 6
            'folder' => (string) $version->folder,
119
        ];
120
121 6
        if (count($apis) > 0) {
122 4
            $version['api'] = $apis;
123
        }
124
125 6
        if (count($guides) > 0) {
126 3
            $version['guide'] = $guides;
127
        }
128
129 6
        return $version;
130
    }
131
132
    /**
133
     * Builds the api part of the array from the configuration xml.
134
     */
135 4
    private function buildApi(SimpleXMLElement $api): array
136
    {
137 4
        $extensions = [];
138 4
        foreach ($api->extensions->children() as $extension) {
139 4
            if ((string) $extension !== '') {
140 4
                $extensions[] = (string) $extension;
141
            }
142
        }
143
144 4
        $ignoreHidden = filter_var($api->ignore->attributes()->hidden, FILTER_VALIDATE_BOOLEAN);
145
146
        return [
147 4
            'format' => ((string) $api->attributes()->format) ?: 'php',
148
            'source' => [
149 4
                'dsn' => ((string) $api->source->attributes()->dsn) ?: 'file://.',
150 4
                'paths' => ((array) $api->source->path) ?: ['.'],
151
            ],
152
            'ignore' => [
153 4
                'hidden' => $ignoreHidden,
154 4
                'paths' => (array) $api->ignore->path,
155
            ],
156 4
            'extensions' => $extensions,
157 4
            'visibility' => (array) $api->visibility,
158 4
            'include-source' => ((string)$api->{'include-source'}) === 'true',
159 4
            'default-package-name' => ((string) $api->{'default-package-name'}) ?: 'Default',
160 4
            'markers' => (array) $api->markers->children()->marker,
161
        ];
162
    }
163
164
    /**
165
     * Builds the guide part of the array from the configuration xml.
166
     */
167 3
    private function buildGuide(SimpleXMLElement $guide): array
168
    {
169
        return [
170 3
            'format' => ((string) $guide->attributes()->format) ?: 'rst',
171
            'source' => [
172 3
                'dsn' => ((string) $guide->source->attributes()->dsn) ?: 'file://.',
173 3
                'paths' => ((array) $guide->source->path) ?: [''],
174
            ],
175
        ];
176
    }
177
178
    /**
179
     * Builds the template part of the array from the configuration xml.
180
     */
181 3
    private function buildTemplate(SimpleXMLElement $template): array
182
    {
183 3
        if ((array) $template === []) {
184 1
            return $this->defaultTemplate();
185
        }
186
187 2
        $attributes = [];
188 2
        foreach ($template->attributes() as $attribute) {
189 2
            $attributes[$attribute->getName()] = (string) $attribute;
190
        }
191
192 2
        return $attributes;
193
    }
194
195
    /**
196
     * Default versions part if none is found in the configuration.
197
     */
198 2
    private static function defaultVersions(): array
199
    {
200
        return [
201 2
            '1.0.0' => [
202 2
                'folder' => 'latest',
203
                'api' => [
204
                    0 => [
205 2
                        'format' => 'php',
206
                        'source' => [
207 2
                            'dsn' => new Dsn('file://.'),
208
                            'paths' => [
209 2
                                0 => new Path('src'),
210
                            ],
211
                        ],
212
                        'ignore' => [
213
                            'hidden' => true,
214
                            'paths' => [],
215
                        ],
216
                        'extensions' => [
217
                            0 => 'php',
218
                            1 => 'php3',
219
                            2 => 'phtml',
220
                        ],
221
                        'visibility' => ['public', 'protected', 'private'],
222
                        'include-source' => false,
223 2
                        'default-package-name' => 'Default',
224 2
                        'encoding' => 'utf8',
225
                        'ignore-tags' => [],
226
                        'validate' => false,
227
                        'markers' => [
228
                            0 => 'TODO',
229
                            1 => 'FIXME',
230
                        ],
231
                    ],
232
                ],
233
                'guide' => [
234
                    0 => [
235 2
                        'format' => 'rst',
236
                        'source' => [
237 2
                            'dsn' => new Dsn('file://.'),
238
                            'paths' => [
239 2
                                0 => new Path('docs'),
240
                            ],
241
                        ],
242
                    ],
243
                ],
244
            ],
245
        ];
246
    }
247
248
    /**
249
     * Default template part if none is found in the configuration.
250
     */
251 6
    private static function defaultTemplate(): array
252
    {
253
        return [
254 6
            'name' => 'clean',
255
        ];
256
    }
257
258
    /**
259
     * Validates the configuration xml structure against the schema defined in the schemaPath.
260
     *
261
     * @throws InvalidArgumentException if the xml structure is not valid.
262
     */
263 8
    private function validate(SimpleXMLElement $phpDocumentor): void
264
    {
265 8
        libxml_clear_errors();
266 8
        $priorSetting = libxml_use_internal_errors(true);
267
268 8
        $dom = new \DOMDocument();
269 8
        $domElement = dom_import_simplexml($phpDocumentor);
270 8
        $domElement = $dom->importNode($domElement, true);
271 8
        $dom->appendChild($domElement);
272
273 8
        $dom->schemaValidate($this->schemaPath);
274
275 8
        $error = libxml_get_last_error();
276
277 8
        if ($error !== false) {
278 1
            throw new InvalidArgumentException(trim($error->message));
279
        }
280
281 7
        libxml_use_internal_errors($priorSetting);
282 7
    }
283
}
284