Completed
Pull Request — master (#604)
by
unknown
05:24
created

SRFMath   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 354
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 21.97%

Importance

Changes 0
Metric Value
wmc 54
lcom 1
cbo 3
dl 0
loc 354
ccs 38
cts 173
cp 0.2197
rs 6.4799
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 6 1
A buildResult() 0 19 3
F getResultText() 0 270 42
A getNumbers() 0 13 4
A addNumbersForDataItem() 0 13 4

How to fix   Complexity   

Complex Class

Complex classes like SRFMath often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SRFMath, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Various mathematical functions - sum, product, average, min and max.
5
 *
6
 * @licence GNU GPL v3+
7
 *
8
 * @author Jeroen De Dauw < [email protected] >
9
 * @author Yaron Koren
10
 * @author Nathan Yergler
11
 */
12
class SRFMath extends SMWResultPrinter {
13
14
	/**
15
	 * (non-PHPdoc)
16
	 * @see SMWResultPrinter::getName()
17
	 */
18
	public function getName() {
19
		// Give grep a chance to find the usages:
20
		// srf_printername_max, srf_printername_min, srf_printername_sum,
21
		// srf_printername_product, srf_printername_average, srf_printername_median
22
		return wfMessage( 'srf_printername_' . $this->mFormat )->text();
23
	}
24
25
	/**
26
	 * @see SMWResultPrinter::buildResult
27
	 *
28
	 * @since 1.8
29
	 *
30
	 * @param SMWQueryResult $results
31
	 *
32
	 * @return string
33
	 */
34 1
	protected function buildResult( SMWQueryResult $results ) {
35
36 1
		$number = $this->getResultText( $results, SMW_OUTPUT_HTML );
37
38 1
		if ( count( $results->getPrintRequests() ) > 1 ) {
39
			$outputformat = $results->getPrintRequests()[1]->getOutputFormat();
40
		} else {
41
			// no mainlabel
42 1
			$outputformat = $results->getPrintRequests()[0]->getOutputFormat();
43
		}
44
45
		// if raw-format ("-") than skip formatNum()
46 1
		if ( $outputformat != "-" ) {
47 1
			$dataValue = \SMW\DataValueFactory::getInstance()->newDataValueByType( '_num' );
48 1
			$number = $dataValue->getLocalizedFormattedNumber( $number );
49
		}
50
51 1
		return (string)$number;
52
	}
53
54
	/**
55
	 * @see SMWResultPrinter::getResultText()
56
	 */
57 1
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
58 1
		$numbers = $this->getNumbers( $res );
59
60 1
		if ( count( $numbers ) == 0 ) {
61
			return $this->params['default'];
62
		}
63
64 1
		switch ( $this->mFormat ) {
65 1
			case 'max':
66 1
				return max( $numbers );
67
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
68 1
			case 'min':
69 1
				return min( $numbers );
70
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
71 1
			case 'sum':
72 1
				return array_sum( $numbers );
73
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
74 1
			case 'product':
75 1
				return array_product( $numbers );
76
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
77 1
			case 'average':
78 1
				return array_sum( $numbers ) / count( $numbers );
79
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
80 1
			case 'median':
81 1
				sort( $numbers, SORT_NUMERIC );
82 1
				$position = ( count( $numbers ) + 1 ) / 2 - 1;
83 1
				return ( $numbers[ceil( $position )] + $numbers[floor( $position )] ) / 2;
84
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
85
			case 'variance':
86
				$average = array_sum($numbers) / count($numbers);
87
				// create space to store values
88
				$space = NULL;
89
				for($i = 0; $i < count($numbers); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
90
				{
91
					$space += pow($numbers[$i], 2);
92
				}
93
				$result = ($space / count($numbers) - pow($average, 2));
94
				return $result;
95
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
96
			case 'samplevariance':
97
				$average = array_sum($numbers) / count($numbers);
98
				// create space to store values
99
				$space = NULL;
100
				for($i = 0; $i < count($numbers); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
101
				{
102
					$space += pow(($numbers[$i] - $average), 2);
103
				}
104
				$result = ($space / (count($numbers) - 1));
105
				return $result;
106
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
107
			case 'samplestandarddeviation':
108
				$average = array_sum($numbers) / count($numbers);
109
				// create space to store values
110
				$space = NULL;
111
				for($i = 0; $i < count($numbers); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
112
				{
113
					$space += pow(($numbers[$i] - $average), 2);
114
				}
115
				$result = sqrt($space / (count($numbers) - 1));
116
				return $result;
117
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
118
			case 'standarddeviation':
119
				$average = array_sum($numbers) / count($numbers);
120
				// create space to store values
121
				$space = NULL;
122
				for($i = 0; $i < count($numbers); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
123
				{
124
					$space += pow($numbers[$i], 2);
125
				}
126
				$result = sqrt($space / count($numbers) - pow($average, 2));
127
				return $result;
128
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
129
			case 'range':
130
				return (max($numbers) - min($numbers));
131
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
132
			case 'quartillower':
133
				sort($numbers, SORT_NUMERIC);
134
				// get position
135
				$Q1_position = ((sizeof($numbers) - 1) * 0.25);
136
				// check if position is between two numbers
137
				if(is_float($Q1_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
138
				{
139
					$Q1_position_y = floor($Q1_position);
140
					$Q1_position_x = ceil($Q1_position);
141
					return ($numbers[$Q1_position_y] + ($numbers[$Q1_position_x] - $numbers[$Q1_position_y]) * 0.25);
142
				}
143
				else
144
				{
145
					return $numbers[$Q1_position];
146
				}
147
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
148
			case 'quartilupper';
149
				sort($numbers, SORT_NUMERIC);
150
				// get position
151
				$Q3_position = ((sizeof($numbers) - 1) * 0.75);
152
				// check if position is between two numbers
153
				if(is_float($Q3_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
154
				{
155
					$Q3_position_y = floor($Q3_position);
156
					$Q3_position_x = ceil($Q3_position);
157
					return ($numbers[$Q3_position_y] + ($numbers[$Q3_position_x] - $numbers[$Q3_position_y]) * 0.75);
158
				}
159
				else
160
				{
161
					return $numbers[$Q3_position];
162
				}
163
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
164
			case 'quartillower.exc';
165
				sort($numbers, SORT_NUMERIC);
166
				// get position
167
				$Q1_position = ((sizeof($numbers) + 1) * 0.25);
168
				// check if position is between two numbers
169
				if(is_float($Q1_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
170
				{
171
					$Q1_position_y = floor($Q1_position)-1;
172
					$Q1_position_x = ceil($Q1_position)-1;
173
					return ($numbers[$Q1_position_y] + ($numbers[$Q1_position_x] - $numbers[$Q1_position_y]) * 0.75);
174
				}
175
				else
176
				{
177
					return $numbers[$Q1_position];
178
				}
179
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
180
			case 'quartilupper.exc';
181
				sort($numbers, SORT_NUMERIC);
182
				// get position
183
				$Q3_position = ((sizeof($numbers) + 1) * 0.75);
184
				// check if position is between two numbers
185
				if(is_float($Q3_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
186
				{
187
					$Q3_position_y = floor($Q3_position)-1;
188
					$Q3_position_x = ceil($Q3_position)-1;
189
					return ($numbers[$Q3_position_y] + ($numbers[$Q3_position_x] - $numbers[$Q3_position_y]) * 0.25);
190
				}
191
				else
192
				{
193
					return $numbers[$Q3_position];
194
				}
195
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
196
			case 'interquartilerange':
197
				sort($numbers, SORT_NUMERIC);
198
				// get position of Q1
199
				$Q1_position = ((sizeof($numbers) - 1) * 0.25);
200
				// check if position is between two numbers
201
				if(is_float($Q1_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
202
				{
203
					$Q1_position_y = floor($Q1_position);
204
					$Q1_position_x = ceil($Q1_position);
205
					$Q1 = ($numbers[$Q1_position_y] + ($numbers[$Q1_position_x] - $numbers[$Q1_position_y]) * 0.25);
206
				}
207
				else
208
				{
209
					$Q1 = $numbers[$Q1_position];
210
				}
211
				// get position of Q3
212
				$Q3_position = ((sizeof($numbers) - 1) * 0.75);
213
				// check if position is between two numbers
214
				if(is_float($Q3_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
215
				{
216
					$Q3_position_y = floor($Q3_position);
217
					$Q3_position_x = ceil($Q3_position);
218
					$Q3 = ($numbers[$Q3_position_y] + ($numbers[$Q3_position_x] - $numbers[$Q3_position_y]) * 0.75);
219
				}
220
				else
221
				{
222
					$Q3 = $numbers[$Q3_position];
223
				}
224
				return ($Q3 - $Q1);
225
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
226
			case 'interquartilerange.exc';
227
				sort($numbers, SORT_NUMERIC);
228
				// get position of Q1
229
				$Q1_position = ((sizeof($numbers) + 1) * 0.25);
230
				// check if position is between two numbers
231
				if(is_float($Q1_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
232
				{
233
					$Q1_position_y = floor($Q1_position)-1;
234
					$Q1_position_x = ceil($Q1_position)-1;
235
					$Q1 = ($numbers[$Q1_position_y] + ($numbers[$Q1_position_x] - $numbers[$Q1_position_y]) * 0.75);
236
				}
237
				else
238
				{
239
					$Q1 = $numbers[$Q1_position];
240
				}
241
				// get position of Q3
242
				$Q3_position = ((sizeof($numbers) + 1) * 0.75);
243
				// check if position is between two numbers
244
				if(is_float($Q3_position) == TRUE)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
245
				{
246
					$Q3_position_y = floor($Q3_position)-1;
247
					$Q3_position_x = ceil($Q3_position)-1;
248
					$Q3 = ($numbers[$Q3_position_y] + ($numbers[$Q3_position_x] - $numbers[$Q3_position_y]) * 0.25);
249
				}
250
				else
251
				{
252
					$Q3 = $numbers[$Q3_position];
253
				}
254
				return ($Q3 - $Q1);
255
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
256
			case 'mode';
257
				// array temp
258
				$array_temp = array();
259
				// convert array
260
				for($i = 0; $i < sizeof($numbers); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
261
				{
262
					$converted_value = strval($numbers[$i]);
263
					$array_temp += [$i => $converted_value];
264
				}
265
				$array_counted_values = array_count_values($array_temp);
266
				// max
267
				$max = max($array_counted_values);
268
				// count
269
				$count = NULL;
270
				// filter
271
				for($i = 0; $i < sizeof($array_counted_values); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
272
				{
273
					if ($array_counted_values[array_keys($array_counted_values)[$i]] == $max)
274
					{
275
						$count += 1;
276
					}
277
				}
278
				// check if there are more than one max
279
				if($count == 1)
280
				{
281
					return $max;
282
				}
283
				break;
284
			case 'interquartilemean';
285
				// sort numbers
286
				sort($numbers,SORT_NUMERIC);
287
					// check if size of numbers is divisble by 4
288
					if(sizeof($numbers)%4 == 0)
289
					{
290
						// split array into 4 groups (2D array)
291
						$array_split = (array_chunk($numbers, sizeof($numbers)/4));
292
						// creating store_string
293
						$store_string = NULL;
294
						for($i = 0; $i < sizeof($array_split[1]); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
295
						{
296
							$store_string += $array_split[1][$i];
297
						}
298
						for($i = 0; $i < sizeof($array_split[2]); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
299
						{
300
							$store_string += $array_split[2][$i];
301
						}
302
						return $store_string/(sizeof($array_split[1])+sizeof($array_split[2]));
303
					}
304
					else
305
					{
306
						// get positon of split
307
						$position = sizeof($numbers)/4;
308
						// remove values out of split
309
						for($i = 0; $i < floor($position); $i++)
310
						{
311
							unset($numbers[$i]);
312
							array_pop($numbers);
313
						}
314
						// reset array keys
315
						$store_array = array_merge($numbers);
316
						// add values
317
						$store_values = NULL;
318
						for($i = 1; $i < sizeof($store_array)-1; $i++)
319
						{
320
							$store_values += $store_array[$i];
321
						}
322
						return ($store_values + ((ceil($position) - $position) * ($store_array[0] + $store_array[sizeof($store_array)-1]))) / ($position*2);
323
					}
324
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
325
		}
326
	}
327
328
	/**
329
	 * @param SMWQueryResult $res
330
	 *
331
	 * @return float[]
332
	 */
333 1
	private function getNumbers( SMWQueryResult $res ) {
334 1
		$numbers = [];
335
336 1
		while ( $row = $res->getNext() ) {
337 1
			foreach ( $row as $resultArray ) {
338 1
				foreach ( $resultArray->getContent() as $dataItem ) {
339 1
					self::addNumbersForDataItem( $dataItem, $numbers );
340
				}
341
			}
342
		}
343
344 1
		return $numbers;
345
	}
346
347
	/**
348
	 * @param SMWDataItem $dataItem
349
	 * @param float[] $numbers
350
	 */
351 1
	private function addNumbersForDataItem( SMWDataItem $dataItem, array &$numbers ) {
352 1
		switch ( $dataItem->getDIType() ) {
353
			case SMWDataItem::TYPE_NUMBER:
354 1
				$numbers[] = $dataItem->getNumber();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SMWDataItem as the method getNumber() does only exist in the following sub-classes of SMWDataItem: SMWDINumber. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
355 1
				break;
356
			case SMWDataItem::TYPE_CONTAINER:
357
				foreach ( $dataItem->getDataItems() as $di ) {
0 ignored issues
show
Bug introduced by
The method getDataItems() does not seem to exist on object<SMWDataItem>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
358
					self::addNumbersForDataItem( $di, $numbers );
359
				}
360
				break;
361
			default:
362
		}
363 1
	}
364
365
}
366