File   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 39
dl 0
loc 185
rs 10
c 1
b 0
f 0
wmc 20

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getWarningCount() 0 3 1
A mergeWith() 0 9 2
A getErrorCount() 0 13 3
A internalSort() 0 19 4
A getIssues() 0 3 1
A addIssue() 0 9 2
A name() 0 3 1
A basename() 0 3 1
A __construct() 0 8 2
A getIssueCount() 0 3 1
A sort() 0 3 1
A dirName() 0 3 1
1
<?php
2
3
/**
4
 * File
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 Simon Kohlmeyer <[email protected]>
43
 *
44
 * @copyright 2007-2010 Mayflower GmbH
45
 *
46
 * @license http://www.opensource.org/licenses/bsd-license.php  BSD License
47
 *
48
 * @version SVN: $Id$
49
 *
50
 * @link http://www.phpunit.de/
51
 *
52
 * @since File available since 0.2.0
53
 */
54
55
namespace PHPCodeBrowser;
56
57
use PHPCodeBrowser\Helper\IOHelper;
58
59
/**
60
 * File
61
 *
62
 * An object of this class represents a single source file
63
 * with it's issues, if any.
64
 *
65
 * @category PHP_CodeBrowser
66
 *
67
 * @author Simon Kohlmeyer <[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://github.com/mayflowergmbh
76
 *
77
 * @since Class available since 0.2.0
78
 */
79
class File
80
{
81
    /**
82
     * Filename.
83
     *
84
     * @var string
85
     */
86
    private $name;
87
88
    /**
89
     * Issues associated with this file.
90
     *
91
     * @var array<Issue>
92
     */
93
    private $issues;
94
95
    /**
96
     * Default constructor.
97
     *
98
     * @param string       $name   The name of the file.
99
     * @param array<Issue> $issues
100
     */
101
    public function __construct(string $name, array $issues = [])
102
    {
103
        if (DIRECTORY_SEPARATOR !== '/') {
104
            $name = \str_replace('/', DIRECTORY_SEPARATOR, $name);
105
        }
106
107
        $this->name   = $name;
108
        $this->issues = $issues;
109
    }
110
111
    /**
112
     * Add an issue for this file.
113
     *
114
     * @param Issue $issue The issue to add.
115
     *
116
     * @throws \InvalidArgumentException
117
     */
118
    public function addIssue(Issue $issue): void
119
    {
120
        if ($issue->getFileName() !== $this->name) {
121
            throw new \InvalidArgumentException(
122
                'Tried to add issue to wrong file.'
123
            );
124
        }
125
126
        $this->issues[] = $issue;
127
    }
128
129
    /**
130
     * Gets an array containing the issues for this file.
131
     *
132
     * @return array<Issue> The issues.
133
     */
134
    public function getIssues(): array
135
    {
136
        return $this->issues;
137
    }
138
139
    /**
140
     * Returns the absolute name of this file.
141
     *
142
     * @return string
143
     */
144
    public function name(): string
145
    {
146
        return $this->name;
147
    }
148
149
    /**
150
     * Returns the basename of this file.
151
     *
152
     * @return string
153
     */
154
    public function basename(): string
155
    {
156
        return \basename($this->name);
157
    }
158
159
    /**
160
     * Returns the dirName of this file.
161
     *
162
     * @return string
163
     */
164
    public function dirName(): string
165
    {
166
        return \dirname($this->name);
167
    }
168
169
    /**
170
     * Returns the number of issues this file has.
171
     *
172
     * @return int
173
     */
174
    public function getIssueCount(): int
175
    {
176
        return \count($this->issues);
177
    }
178
179
    /**
180
     * Returns the number of errors this file has.
181
     *
182
     * @return int
183
     */
184
    public function getErrorCount(): int
185
    {
186
        $count = 0;
187
188
        foreach ($this->issues as $issue) {
189
            if (\strcasecmp($issue->getSeverity(), 'error') !== 0) {
190
                continue;
191
            }
192
193
            ++$count;
194
        }
195
196
        return $count;
197
    }
198
199
    /**
200
     * Returns the number of issues this file has that are not errors.
201
     *
202
     * @return int
203
     */
204
    public function getWarningCount(): int
205
    {
206
        return $this->getIssueCount() - $this->getErrorCount();
207
    }
208
209
    /**
210
     * Merges the issues from two file objects representing the same file.
211
     *
212
     * @param File $file The file to merge with.
213
     *
214
     * @throws \InvalidArgumentException
215
     */
216
    public function mergeWith(File $file): void
217
    {
218
        if ($this->name !== $file->name) {
219
            throw new \InvalidArgumentException(
220
                'Tried to merge different files'
221
            );
222
        }
223
224
        $this->issues = \array_merge($this->issues, $file->issues);
225
    }
226
227
    /**
228
     * Sorts an array of Files. Key value association will be preserved.
229
     *
230
     * @param array<File> $files The files to sort.
231
     */
232
    public static function sort(array &$files): void
233
    {
234
        \uasort($files, 'PHPCodeBrowser\File::internalSort');
235
    }
236
237
    /**
238
     * Sorting function used in File::sort()
239
     *
240
     * @param File $first
241
     * @param File $second
242
     *
243
     * @return int
244
     */
245
    protected static function internalSort(File $first, File $second): int
246
    {
247
        $firstName  = $first->name();
248
        $secondName = $second->name();
249
250
        $prefix       = IOHelper::getCommonPathPrefix([$firstName, $secondName]);
251
        $prefixLength = \strlen($prefix);
252
253
        $firstSubName  = \substr($firstName, $prefixLength);
254
        $secondSubName = \substr($secondName, $prefixLength);
255
256
        $firstIsInSubDir  = (\str_contains($firstSubName, DIRECTORY_SEPARATOR));
257
        $secondIsInSubDir = (\str_contains($secondSubName, DIRECTORY_SEPARATOR));
258
259
        if ($firstIsInSubDir) {
260
            return $secondIsInSubDir ? \strcmp($firstSubName, $secondSubName) : -1;
261
        }
262
263
        return $secondIsInSubDir ? 1 : \strcmp($firstSubName, $secondSubName);
264
    }
265
}
266