AbstractPlugin::getLineStart()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Abstract Plugin
5
 *
6
 * PHP Version 5.3.0
7
 *
8
 * Copyright (c) 2007-2010, Mayflower GmbH
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 *
15
 *   * Redistributions of source code must retain the above copyright
16
 *     notice, this list of conditions and the following disclaimer.
17
 *
18
 *   * Redistributions in binary form must reproduce the above copyright
19
 *     notice, this list of conditions and the following disclaimer in
20
 *     the documentation and/or other materials provided with the
21
 *     distribution.
22
 *
23
 *   * Neither the name of Mayflower GmbH nor the names of his
24
 *     contributors may be used to endorse or promote products derived
25
 *     from this software without specific prior written permission.
26
 *
27
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
 * POSSIBILITY OF SUCH DAMAGE.
39
 *
40
 * @category PHP_CodeBrowser
41
 *
42
 * @author Elger Thiele <[email protected]>
43
 * @author Michel Hartmann <[email protected]>
44
 *
45
 * @copyright 2007-2010 Mayflower GmbH
46
 *
47
 * @license http://www.opensource.org/licenses/bsd-license.php  BSD License
48
 *
49
 * @version SVN: $Id$
50
 *
51
 * @link http://www.phpunit.de/
52
 *
53
 * @since File available since  0.1.0
54
 */
55
56
namespace PHPCodeBrowser;
57
58
use DOMElement;
59
use DOMNodeList;
60
61
/**
62
 * AbstractPlugin
63
 *
64
 * @category PHP_CodeBrowser
65
 *
66
 * @author Elger Thiele <[email protected]>
67
 * @author Michel Hartmann <[email protected]>
68
 *
69
 * @copyright 2007-2010 Mayflower GmbH
70
 *
71
 * @license http://www.opensource.org/licenses/bsd-license.php  BSD License
72
 *
73
 * @version Release: @package_version@
74
 *
75
 * @link http://www.phpunit.de/
76
 *
77
 * @since Class available since  0.1.0
78
 */
79
abstract class AbstractPlugin
80
{
81
    /**
82
     * The name of the plugin.
83
     * This should be the name that is written to the XML error files by
84
     * cruisecontrol.
85
     *
86
     * @var string
87
     */
88
    protected $pluginName;
89
90
    /**
91
     * The IssueXML object
92
     *
93
     * @var IssueXML
94
     */
95
    protected $issueXml;
96
97
    /**
98
     * Name of the attribute that holds the number of the first line
99
     * of the issue.
100
     *
101
     * @var string
102
     */
103
    protected $lineStartAttr;
104
105
    /**
106
     * Name of the attribute that holds the number of the last line
107
     * of the issue.
108
     *
109
     * @var string
110
     */
111
    protected $lineEndAttr;
112
113
    /**
114
     * Name of the attribute that holds message of the issue.
115
     *
116
     * @var string
117
     */
118
    protected $descriptionAttr;
119
120
    /**
121
     * Name of the attribute that holds severity of the issue.
122
     *
123
     * @var string
124
     */
125
    protected $severityAttr;
126
127
    /**
128
     * Default string to use as source for issue.
129
     *
130
     * @var string
131
     */
132
    protected $source;
133
134
    /**
135
     * Plugin-specific options.
136
     *
137
     * @var array
138
     */
139
    protected $options;
140
141
    /**
142
     * Default Constructor
143
     *
144
     * @param IssueXML $issueXml The cc XML document.
145
     * @param array    $options  Optional plugin-specific options.
146
     */
147
    public function __construct(IssueXML $issueXml, array $options = [])
148
    {
149
        $this->issueXml = $issueXml;
150
        $this->options  = $options;
151
    }
152
153
    /**
154
     * Gets a list of File objects, including their issues.
155
     *
156
     * @return array<File> List of files with issues.
157
     */
158
    public function getFileList(): array
159
    {
160
        $files = [];
161
162
        foreach ($this->getFilesWithIssues() as $name) {
163
            $files[] = new File($name, $this->getIssuesByFile($name));
164
        }
165
166
        return $files;
167
    }
168
169
    /**
170
     * Parse the cc XML file for defined error type, e.g. "pmd" and map this
171
     * error to the Issue objects format.
172
     *
173
     * @param string $filename Name of the file to parse the errors for.
174
     *
175
     * @return array
176
     */
177
    public function getIssuesByFile(string $filename): array
178
    {
179
        $issues = [];
180
181
        foreach ($this->getIssueNodes($filename) as $issueNode) {
182
            $issues = \array_merge(
183
                $issues,
184
                $this->mapIssues($issueNode, $filename)
185
            );
186
        }
187
188
        return $issues;
189
    }
190
191
    /**
192
     * Get an array with all files that have issues.
193
     *
194
     * @return array
195
     */
196
    public function getFilesWithIssues(): array
197
    {
198
        $fileNames  = [];
199
        $issueNodes = $this->issueXml->query(
200
            \sprintf('/*/%s/file[@name]', $this->pluginName)
201
        );
202
203
        foreach ($issueNodes as $node) {
204
            if (!($node instanceof DOMElement)) {
205
                continue;
206
            }
207
208
            $fileNames[] = $node->getAttribute('name');
209
        }
210
211
        return \array_unique($fileNames);
212
    }
213
214
    /**
215
     * The detailed mapper method for each single plugin, returning an array
216
     * of issue objects.
217
     * This method provides a default behaviour an can be overloaded to
218
     * implement special behavior for other plugins.
219
     *
220
     * @param \DOMNode $element  The XML plugin node with its errors
221
     * @param string   $filename Name of the file to return issues for.
222
     *
223
     * @return array<Issue>
224
     */
225
    public function mapIssues(\DOMNode $element, string $filename): array
226
    {
227
        $errorList = [];
228
229
        foreach ($element->childNodes as $child) {
230
            if (!($child instanceof DOMElement)) {
231
                continue;
232
            }
233
234
            $errorList[] = new Issue(
235
                $filename,
236
                $this->getLineStart($child),
237
                $this->getLineEnd($child),
238
                $this->getSource(),
239
                $this->getDescription($child),
240
                $this->getSeverity($child)
241
            );
242
        }
243
244
        return $errorList;
245
    }
246
247
    /**
248
     * Get all DOMNodes that represent issues for a specific file.
249
     *
250
     * @param string $filename Name of the file to get nodes for.
251
     *
252
     * @return DOMNodeList
253
     */
254
    protected function getIssueNodes(string $filename): DOMNodeList
255
    {
256
        return $this->issueXml->query(
257
            \sprintf('/*/%s/file[@name="%s"]', $this->pluginName, $filename)
258
        );
259
    }
260
261
    /**
262
     * Default method for retrieving the first line of an issue.
263
     *
264
     * @see self::mapIssues
265
     *
266
     * @param DOMElement $element
267
     *
268
     * @return int
269
     */
270
    protected function getLineStart(DOMElement $element): int
271
    {
272
        return (int) $element->getAttribute($this->lineStartAttr);
273
    }
274
275
    /**
276
     * Default method for retrieving the last line of an issue.
277
     *
278
     * @see self::mapIssues
279
     *
280
     * @param DOMElement $element
281
     *
282
     * @return int
283
     */
284
    protected function getLineEnd(DOMElement $element): int
285
    {
286
        return (int) $element->getAttribute($this->lineEndAttr);
287
    }
288
289
    /**
290
     * Default method for retrieving the source of an issue.
291
     *
292
     * @see self::mapIssues
293
     *
294
     * @return string
295
     */
296
    protected function getSource(): string
297
    {
298
        return $this->source;
299
    }
300
301
    /**
302
     * Default method for retrieving the description of an issue.
303
     *
304
     * @see self::mapIssues
305
     *
306
     * @param DOMElement $element
307
     *
308
     * @return string
309
     */
310
    protected function getDescription(DOMElement $element): string
311
    {
312
        return \htmlentities($element->getAttribute($this->descriptionAttr), ENT_COMPAT);
313
    }
314
315
    /**
316
     * Default method for retrieving the severity of an issue.
317
     *
318
     * @see self::mapIssues
319
     *
320
     * @param DOMElement $element
321
     *
322
     * @return string
323
     */
324
    protected function getSeverity(DOMElement $element): string
325
    {
326
        return \htmlentities($element->getAttribute($this->severityAttr), ENT_COMPAT);
327
    }
328
}
329