Completed
Push — develop ( 8fda15...dbbcf5 )
by Jaap
14s
created

Version3::buildApi()   C

Complexity

Conditions 7
Paths 48

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 18
nc 48
nop 1
dl 0
loc 27
ccs 15
cts 15
cp 1
crap 7
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright 2010-2015 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\Application\Configuration\Factory;
14
15
use phpDocumentor\DomainModel\Dsn;
16
use phpDocumentor\DomainModel\Path;
17
18
/**
19
 * phpDocumentor3 strategy for converting the configuration xml to an array.
20
 */
21
final class Version3 implements Strategy
22
{
23
    /**
24
     * The path to the xsd that is used for validation of the configuration file.
25
     *
26
     * @var string
27
     */
28
    private $schemaPath;
29
30
    /**
31
     * Initializes the PhpDocumentor3 strategy.
32
     */
33 9
    public function __construct(string $schemaPath)
34
    {
35 9
        $this->schemaPath = $schemaPath;
36 9
    }
37
38
    /**
39
     * @inheritdoc
40
     */
41 9
    public function convert(\SimpleXMLElement $phpDocumentor): array
42
    {
43 9
        $this->validate($phpDocumentor);
44
45 8
        $versions = [];
46 8
        $templates = [];
47
48 8
        foreach ($phpDocumentor->children() as $child) {
49 8
            switch ($child->getName()) {
50 8
                case 'version':
51 7
                    $versions[(string) $child->attributes()->number] = $this->buildVersion($child);
52 7
                    break;
53 8
                case 'template':
54 4
                    $templates[] = $this->buildTemplate($child);
55 4
                    break;
56
                default:
57 8
                    break;
58
            }
59
        }
60
61
        $phpdoc3Array = [
62 8
            'phpdocumentor' => [
63 8
                'use-cache' => $phpDocumentor->{'use-cache'} ?: true,
64
                'paths' => [
65 8
                    'output' => new Dsn(((string) $phpDocumentor->paths->output) ?: 'file://build/docs'),
66 8
                    'cache' => new Path(((string) $phpDocumentor->paths->cache) ?: '/tmp/phpdoc-doc-cache'),
67
                ],
68 8
                'versions' => ($versions) ?: $this->defaultVersions(),
69 8
                'templates' => ($templates) ?: [$this->defaultTemplate()],
70
            ],
71
        ];
72
73 8
        return $phpdoc3Array;
74
    }
75
76
    /**
77
     * @inheritdoc
78
     */
79 2
    public function match(\SimpleXMLElement $phpDocumentor): bool
80
    {
81 2
        return (string) $phpDocumentor->attributes()->version === '3';
82
    }
83
84
    public static function buildDefault()
85
    {
86
        return [
87
            'phpdocumentor' => [
88
                'title' => 'my docs',
89
                'use-cache' => true,
90
                'paths' => [
91
                    'output' => new Dsn('file://build/docs'),
92
                    'cache' => new Path('/tmp/phpdoc-doc-cache'),
93
                ],
94
                'versions' => static::defaultVersions(),
0 ignored issues
show
Comprehensibility introduced by Jaapio
Since phpDocumentor\Applicatio...ration\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...
95
                'templates' => [static::defaultTemplate()],
0 ignored issues
show
Comprehensibility introduced by Jaapio
Since phpDocumentor\Applicatio...ration\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...
96
            ],
97
        ];
98
    }
99
100
    /**
101
     * Builds the versions part of the array from the configuration xml.
102
     */
103 7
    private function buildVersion(\SimpleXMLElement $version): array
104
    {
105 7
        $apis = [];
106 7
        $guides = [];
107 7
        foreach ($version->children() as $child) {
108 7
            switch ($child->getName()) {
109 7
                case 'api':
110 5
                    $apis[] = $this->buildApi($child);
111 5
                    break;
112 7
                case 'guide':
113 4
                    $guides[] = $this->buildGuide($child);
114 4
                    break;
115
                default:
116 7
                    break;
117
            }
118
        }
119
120
        $version = [
121 7
            'folder' => (string) $version->folder,
122
        ];
123
124 7
        if (count($apis) > 0) {
125 5
            $version['api'] = $apis;
126
        }
127
128 7
        if (count($guides) > 0) {
129 4
            $version['guide'] = $guides;
130
        }
131
132 7
        return $version;
133
    }
134
135
    /**
136
     * Builds the api part of the array from the configuration xml.
137
     */
138 5
    private function buildApi(\SimpleXMLElement $api): array
139
    {
140 5
        $extensions = [];
141 5
        foreach ($api->extensions->children() as $extension) {
142 5
            if ((string) $extension !== '') {
143 5
                $extensions[] = (string) $extension;
144
            }
145
        }
146
147 5
        $ignoreHidden = filter_var($api->ignore->attributes()->hidden, FILTER_VALIDATE_BOOLEAN);
148
149
        return [
150 5
            'format' => ((string) $api->attributes()->format) ?: 'php',
151
            'source' => [
152 5
                'dsn' => ((string) $api->source->attributes()->dsn) ?: 'file://.',
153 5
                'paths' => ((array) $api->source->path) ?: ['.'],
154
            ],
155
            'ignore' => [
156 5
                'hidden' => $ignoreHidden,
157 5
                'paths' => (array) $api->ignore->path,
158
            ],
159 5
            'extensions' => $extensions,
160 5
            'visibility' => (array) $api->visibility,
161 5
            'default-package-name' => ((string) $api->{'default-package-name'}) ?: 'Default',
162 5
            'markers' => (array) $api->markers->children()->marker,
163
        ];
164
    }
165
166
    /**
167
     * Builds the guide part of the array from the configuration xml.
168
     */
169 4
    private function buildGuide(\SimpleXMLElement $guide): array
170
    {
171
        return [
172 4
            'format' => ((string) $guide->attributes()->format) ?: 'rst',
173
            'source' => [
174 4
                'dsn' => ((string) $guide->source->attributes()->dsn) ?: 'file://.',
175 4
                'paths' => ((array) $guide->source->path) ?: [''],
176
            ],
177
        ];
178
    }
179
180
    /**
181
     * Builds the template part of the array from the configuration xml.
182
     *
183
     *
184
     * @return array
185
     */
186 4
    private function buildTemplate(\SimpleXMLElement $template)
187
    {
188 4
        if ((array) $template === []) {
189 1
            return $this->defaultTemplate();
190
        }
191
192 3
        $attributes = [];
193 3
        foreach ($template->attributes() as $attribute) {
194 3
            $attributes[$attribute->getName()] = (string) $attribute;
195
        }
196
197 3
        return $attributes;
198
    }
199
200
    /**
201
     * Default versions part if none is found in the configuration.
202
     */
203 1
    private static function defaultVersions(): array
204
    {
205
        return [
206 1
            '1.0.0' => [
207 1
                'folder' => 'latest',
208
                'api' => [
209
                    0 => [
210 1
                        'format' => 'php',
211
                        'source' => [
212 1
                            'dsn' => new Dsn('file://.'),
213
                            'paths' => [
214 1
                                0 => new Path('src'),
215
                            ],
216
                        ],
217
                        'ignore' => [
218
                            'hidden' => true,
219
                            'paths' => [],
220
                        ],
221
                        'extensions' => [
222
                            0 => 'php',
223
                            1 => 'php3',
224
                            2 => 'phtml',
225
                        ],
226
                        'visibility' => ['public'],
227 1
                        'default-package-name' => 'Default',
228 1
                        'encoding' => 'utf8',
229
                        'ignore-tags' => [],
230
                        'validate' => false,
231
                        'markers' => [
232
                            0 => 'TODO',
233
                            1 => 'FIXME',
234
                        ],
235
                    ],
236
                ],
237
                'guide' => [
238
                    0 => [
239 1
                        'format' => 'rst',
240
                        'source' => [
241 1
                            'dsn' => new Dsn('file://.'),
242
                            'paths' => [
243 1
                                0 => new Path('docs'),
244
                            ],
245
                        ],
246
                    ],
247
                ],
248
            ],
249
        ];
250
    }
251
252
    /**
253
     * Default template part if none is found in the configuration.
254
     */
255 5
    private static function defaultTemplate(): array
256
    {
257
        return [
258 5
            'name' => 'clean',
259
        ];
260
    }
261
262
    /**
263
     * Validates the configuration xml structure against the schema defined in the schemaPath.
264
     *
265
     *
266
     * @throws \InvalidArgumentException if the xml structure is not valid.
267
     */
268 9
    private function validate(\SimpleXMLElement $phpDocumentor)
269
    {
270 9
        libxml_clear_errors();
271 9
        $priorSetting = libxml_use_internal_errors(true);
272
273 9
        $dom = new \DOMDocument();
274 9
        $domElement = dom_import_simplexml($phpDocumentor);
275 9
        $domElement = $dom->importNode($domElement, true);
276 9
        $dom->appendChild($domElement);
277
278 9
        $dom->schemaValidate($this->schemaPath);
279
280 9
        $error = libxml_get_last_error();
281
282 9
        if ($error !== false) {
283 1
            throw new \InvalidArgumentException(trim($error->message));
284
        }
285
286 8
        libxml_use_internal_errors($priorSetting);
287 8
    }
288
}
289