Completed
Push — develop ( a89061...54507c )
by Jaap
08:53
created

Application/Configuration/Factory/Version3.php (2 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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