Completed
Push — master ( c81f6c...1650a0 )
by mw
07:33
created

formats/math/SRF_Math.php (8 issues)

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
/**
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
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
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
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
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
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
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
		}
86
	}
87
88
	/**
89
	 * @param SMWQueryResult $res
90
	 *
91
	 * @return float[]
92
	 */
93 1
	private function getNumbers( SMWQueryResult $res ) {
94 1
		$numbers = [];
95
96 1
		while ( $row = $res->getNext() ) {
97 1
			foreach ( $row as $resultArray ) {
98 1
				foreach ( $resultArray->getContent() as $dataItem ) {
99 1
					self::addNumbersForDataItem( $dataItem, $numbers );
100
				}
101
			}
102
		}
103
104 1
		return $numbers;
105
	}
106
107
	/**
108
	 * @param SMWDataItem $dataItem
109
	 * @param float[] $numbers
110
	 */
111 1
	private function addNumbersForDataItem( SMWDataItem $dataItem, array &$numbers ) {
112 1
		switch ( $dataItem->getDIType() ) {
113 1
			case SMWDataItem::TYPE_NUMBER:
114 1
				$numbers[] = $dataItem->getNumber();
0 ignored issues
show
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...
115 1
				break;
116
			case SMWDataItem::TYPE_CONTAINER:
117
				foreach ( $dataItem->getDataItems() as $di ) {
0 ignored issues
show
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...
118
					self::addNumbersForDataItem( $di, $numbers );
119
				}
120
				break;
121
			default:
122
		}
123 1
	}
124
125
}
126