Completed
Push — master ( 3501bb...a54e8c )
by Karsten
06:34
created

MathFormats::product_function()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * Various mathematical functions - sum, product, average, min, max, median, variance, samplevariance, samplestandarddeviation, standarddeviation, range, quartillower, quartilupper, quartillower.exc, quartilupper.exc, interquartilerange, interquartilerange.exc, mode and interquartilemean
5
 *
6
 * @licence GNU GPL v3+
7
 *
8
 * @author Jeroen De Dauw < [email protected] >
9
 * @author Yaron Koren
10
 * @author Nathan Yergler
11
 * @author Florian Breitenlacher
12
 */
13
14
class MathFormats
15
{
16 1
	public static function max_function(array $numbers)
17
	{
18
		// result
19 1
		return max($numbers);
20
	}
21
22 1
	public static function min_function(array $numbers)
23
	{
24
		// result
25 1
		return min($numbers);
26
	}
27
28 1
	public static function sum_function(array $numbers)
29
	{
30
		// result
31 1
		return array_sum($numbers);
32
	}
33
34 1
	public static function product_function(array $numbers)
35
	{
36
		// result
37 1
		return array_product($numbers);
38
	}
39
40 1
	public static function average_function(array $numbers)
41
	{
42
		// result
43 1
		return array_sum($numbers) / count($numbers);
44
	}
45
46 1
	public static function median_function(array $numbers)
47
	{
48 1
		sort( $numbers, SORT_NUMERIC );
49
		// get position
50 1
		$position = (count($numbers) + 1 ) / 2 - 1;
51
		// result
52 1
		return ( $numbers[ceil($position)] + $numbers[floor($position)]) / 2;
53
	}
54
55 1
	public static function variance_function(array $numbers)
56
	{
57
		// average
58 1
		$average = MathFormats::average_function($numbers);
59
		// space
60 1
		$space = NULL;
61 1
		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...
62
		{
63 1
			$space += pow($numbers[$i], 2);
64
		}
65
		// result
66 1
		return ($space / count($numbers) - pow($average, 2));
67
	}
68
69 1
	public static function samplevariance_function(array $numbers)
70
	{
71
		// average
72 1
		$average = MathFormats::average_function($numbers);
73
		// space
74 1
		$space = NULL;
75 1
		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...
76
		{
77 1
			$space += pow(($numbers[$i] - $average), 2);
78
		}
79
		// result
80 1
		return ($space / (count($numbers) - 1));
81
	}
82
83 1
	public static function standarddeviation_function(array $numbers)
84
	{
85
		// average
86 1
		$average = MathFormats::average_function($numbers);
87
		// space
88 1
		$space = NULL;
89 1
		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 1
			$space += pow(($numbers[$i] - $average), 2);
92
		}
93
		// result
94 1
		return sqrt($space / (count($numbers) - 1));
95
	}
96
97 1
	public static function samplestandarddeviation_function(array $numbers)
98
	{
99
		// average
100 1
		$average = MathFormats::average_function($numbers);
101
		// space
102 1
		$space = NULL;
103 1
		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...
104
		{
105 1
			$space += pow($numbers[$i], 2);
106
		}
107
		// result
108 1
		return sqrt($space / count($numbers) - pow($average, 2));
109
	}
110
111 1
	public static function range_function(array $numbers)
112
	{
113
		// result
114 1
		return (max($numbers) - min($numbers));
115
	}
116
117 1
	public static function quartillower_inc_function(array $numbers)
118
	{
119 1
		sort($numbers, SORT_NUMERIC);
120
		// get position
121 1
		$Q1_position = ((sizeof($numbers) - 1) * 0.25);
122
		// check if position is between two numbers
123 1
		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...
124
		{
125 1
			$Q1_position_y = floor($Q1_position);
126 1
			$Q1_position_x = ceil($Q1_position);
127
			// result
128 1
			return ($numbers[$Q1_position_y] + ($numbers[$Q1_position_x] - $numbers[$Q1_position_y]) * 0.25);
129
		}
130
		else
131
		{
132
			// result
133
			return $numbers[$Q1_position];
134
		}
135
	}
136
137 1
	public static function quartilupper_inc_function(array $numbers)
138
	{
139 1
		sort($numbers, SORT_NUMERIC);
140
		// get position
141 1
		$Q3_position = ((sizeof($numbers) - 1) * 0.75);
142
		// check if position is between two numbers
143 1
		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...
144
		{
145 1
			$Q3_position_y = floor($Q3_position);
146 1
			$Q3_position_x = ceil($Q3_position);
147
			// result
148 1
			return ($numbers[$Q3_position_y] + ($numbers[$Q3_position_x] - $numbers[$Q3_position_y]) * 0.75);
149
		}
150
		else
151
		{
152
			// result
153
			return $numbers[$Q3_position];
154
		}
155
	}
156
157 1
	public static function quartillower_exc_function(array $numbers)
158
	{
159 1
		sort($numbers, SORT_NUMERIC);
160
		// get position
161 1
		$Q1_position = ((sizeof($numbers) + 1) * 0.25);
162
		// check if position is between two numbers
163 1
		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...
164
		{
165 1
			$Q1_position_y = floor($Q1_position)-1;
166 1
			$Q1_position_x = ceil($Q1_position)-1;
167
			// result
168 1
			return ($numbers[$Q1_position_y] + ($numbers[$Q1_position_x] - $numbers[$Q1_position_y]) * 0.75);
169
		}
170
		else
171
		{
172
			// result
173
			return $numbers[$Q1_position];
174
		}
175
	}
176
177 1
	public static function quartilupper_exc_function(array $numbers)
178
	{
179 1
		sort($numbers, SORT_NUMERIC);
180
		// get position
181 1
		$Q3_position = ((sizeof($numbers) + 1) * 0.75);
182
		// check if position is between two numbers
183 1
		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...
184
		{
185 1
			$Q3_position_y = floor($Q3_position)-1;
186 1
			$Q3_position_x = ceil($Q3_position)-1;
187
			// result
188 1
			return ($numbers[$Q3_position_y] + ($numbers[$Q3_position_x] - $numbers[$Q3_position_y]) * 0.25);
189
		}
190
		else
191
		{
192
			// result
193
			return $numbers[$Q3_position];
194
		}
195
	}
196
197 1
	public static function interquartilerange_inc_function(array $numbers)
198
	{
199
		// result
200 1
		return MathFormats::quartilupper_inc_function($numbers) - MathFormats::quartillower_inc_function($numbers);
201
	}
202
203 1
	public static function interquartilerange_exc_function(array $numbers)
204
	{
205
		// result
206 1
		return MathFormats::quartilupper_exc_function($numbers) - MathFormats::quartillower_exc_function($numbers);
207
	}
208
209 1
	public static function mode_function(array $numbers)
210
	{
211
		// array temp
212 1
		$array_temp = array();
213
		// convert array
214 1
		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...
215
		{
216 1
			$converted_value = strval($numbers[$i]);
217 1
			$array_temp += [$i => $converted_value];
218
		}
219 1
		$array_counted_values = array_count_values($array_temp);
220
		// max
221 1
		$max = max($array_counted_values);
222
		// count
223 1
		$count = NULL;
224
		// filter
225 1
		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...
226
		{
227 1
			if ($array_counted_values[array_keys($array_counted_values)[$i]] == $max)
228
			{
229 1
				$count += 1;
230
			}
231
		}
232
		// check if there are more than one max
233 1
		if($count == 1)
234
		{
235
			// result
236 1
			return $max;
237
		}
238
	}
239
240 1
	public static function interquartilemean_function(array $numbers)
241
	{
242
		// sort numbers
243 1
		sort($numbers,SORT_NUMERIC);
244
		// check if size of numbers is divisible by 4
245 1
		if(sizeof($numbers)%4 == 0)
246
		{
247
			// split array into 4 groups (2D array)
248 1
			$array_split = (array_chunk($numbers, sizeof($numbers)/4));
249
			// creating store_string
250 1
			$store_string = NULL;
251 1
			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...
252
			{
253 1
				$store_string += $array_split[1][$i];
254
			}
255 1
			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...
256
			{
257 1
				$store_string += $array_split[2][$i];
258
			}
259
			// result
260 1
			return $store_string/(sizeof($array_split[1])+sizeof($array_split[2]));
261
		}
262
		else
263
		{
264
			// get position of split
265 1
			$position = sizeof($numbers)/4;
266
			// remove values out of split
267 1
			for($i = 0; $i < floor($position); $i++)
268
			{
269 1
				unset($numbers[$i]);
270 1
				array_pop($numbers);
271
			}
272
			// reset array keys
273 1
			$store_array = array_merge($numbers);
274
			// add values
275 1
			$store_values = NULL;
276 1
			for($i = 1; $i < sizeof($store_array)-1; $i++)
277
			{
278 1
				$store_values += $store_array[$i];
279
			}
280
			// result
281 1
			return ($store_values + ((ceil($position) - $position) * ($store_array[0] + $store_array[sizeof($store_array)-1]))) / ($position*2);
282
		}
283
	}
284
}
285
286
class SRFMath extends SMWResultPrinter {
287
288
	/**
289
	 * (non-PHPdoc)
290
	 * @see SMWResultPrinter::getName()
291
	 */
292
	public function getName() {
293
		// Give grep a chance to find the usages:
294
		// srf_printername_max, srf_printername_min, srf_printername_sum,
295
		// srf_printername_product, srf_printername_average, srf_printername_median
296
		return wfMessage( 'srf_printername_' . $this->mFormat )->text();
297
	}
298
299
	/**
300
	 * @see SMWResultPrinter::buildResult
301
	 *
302
	 * @since 1.8
303
	 *
304
	 * @param SMWQueryResult $results
305
	 *
306
	 * @return string
307
	 */
308 1
	protected function buildResult( SMWQueryResult $results ) {
309
310 1
		$number = $this->getResultText( $results, SMW_OUTPUT_HTML );
311
312 1
		if ( count( $results->getPrintRequests() ) > 1 ) {
313
			$outputformat = $results->getPrintRequests()[1]->getOutputFormat();
314
		} else {
315
			// no mainlabel
316 1
			$outputformat = $results->getPrintRequests()[0]->getOutputFormat();
317
		}
318
319
		// if raw-format ("-") than skip formatNum()
320 1
		if ( $outputformat != "-" ) {
321 1
			$dataValue = \SMW\DataValueFactory::getInstance()->newDataValueByType( '_num' );
322 1
			$number = $dataValue->getLocalizedFormattedNumber( $number );
323
		}
324
325 1
		return (string)$number;
326
	}
327
328
	/**
329
	 * @see SMWResultPrinter::getResultText()
330
	 */
331 1
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
332 1
		$numbers = $this->getNumbers( $res );
333
334 1
		if ( count( $numbers ) == 0 ) {
335
			return $this->params['default'];
336
		}
337
338 1
		switch ( $this->mFormat ) {
339 1
			case 'max':
340 1
				return MathFormats::max_function($numbers);
341
				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...
342 1
			case 'min':
343 1
				return MathFormats::min_function($numbers);
344
				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...
345 1
			case 'sum':
346 1
				return MathFormats::sum_function($numbers);
347
				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...
348 1
			case 'product':
349 1
				return MathFormats::product_function($numbers);
350
				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...
351 1
			case 'average':
352 1
				return MathFormats::average_function($numbers);
353
				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...
354 1
			case 'median':
355 1
				return MathFormats::median_function($numbers);
356
				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...
357 1
			case 'variance':
358 1
				return MathFormats::variance_function($numbers);
359
				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...
360 1
			case 'samplevariance':
361 1
				return MathFormats::samplevariance_function($numbers);
362
				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...
363 1
			case 'samplestandarddeviation':
364 1
				return MathFormats::samplestandarddeviation_function($numbers);
365
				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...
366 1
			case 'standarddeviation':
367 1
				return MathFormats::standarddeviation_function($numbers);
368
				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...
369 1
			case 'range':
370 1
				return MathFormats::range_function($numbers);
371
				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...
372 1
			case 'quartillower':
373 1
				return MathFormats::quartillower_inc_function($numbers);
374
				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...
375 1
			case 'quartilupper';
376 1
				return MathFormats::quartilupper_inc_function($numbers);
377
				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...
378 1
			case 'quartillower.exc';
379 1
				return MathFormats::quartillower_exc_function($numbers);
380
				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...
381 1
			case 'quartilupper.exc';
382 1
				return MathFormats::quartilupper_exc_function($numbers);
383
				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...
384 1
			case 'interquartilerange':
385 1
				return MathFormats::interquartilerange_inc_function($numbers);
386
				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...
387 1
			case 'interquartilerange.exc';
388 1
				return MathFormats::interquartilerange_exc_function($numbers);
389
				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...
390 1
			case 'mode';
391 1
				return MathFormats::mode_function($numbers);
392
				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...
393 1
			case 'interquartilemean';
394 1
				return MathFormats::interquartilemean_function($numbers);
395
				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...
396
		}
397
	}
398
399
	/**
400
	 * @param SMWQueryResult $res
401
	 *
402
	 * @return float[]
403
	 */
404 1
	private function getNumbers( SMWQueryResult $res ) {
405 1
		$numbers = [];
406
407 1
		while ( $row = $res->getNext() ) {
408 1
			foreach ( $row as $resultArray ) {
409 1
				foreach ( $resultArray->getContent() as $dataItem ) {
410 1
					self::addNumbersForDataItem( $dataItem, $numbers );
411
				}
412
			}
413
		}
414
415 1
		return $numbers;
416
	}
417
418
	/**
419
	 * @param SMWDataItem $dataItem
420
	 * @param float[] $numbers
421
	 */
422 1
	private function addNumbersForDataItem( SMWDataItem $dataItem, array &$numbers ) {
423 1
		switch ( $dataItem->getDIType() ) {
424
			case SMWDataItem::TYPE_NUMBER:
425 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...
426 1
				break;
427
			case SMWDataItem::TYPE_CONTAINER:
428
				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...
429
					self::addNumbersForDataItem( $di, $numbers );
430
				}
431
				break;
432
			default:
433
		}
434 1
	}
435
436
}
437