Completed
Pull Request — master (#153)
by Juliette
03:18
created

NewFunctionParametersSniff::process()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 39
Code Lines 21

Duplication

Lines 39
Ratio 100 %

Importance

Changes 4
Bugs 1 Features 1
Metric Value
c 4
b 1
f 1
dl 39
loc 39
rs 8.439
cc 6
eloc 21
nc 6
nop 2
1
<?php
2
/**
3
 * PHPCompatibility_Sniffs_PHP_NewFunctionParametersSniff.
4
 *
5
 * @category  PHP
6
 * @package   PHPCompatibility
7
 * @author    Wim Godden <[email protected]>
8
 */
9
10
/**
11
 * PHPCompatibility_Sniffs_PHP_newFunctionParametersSniff.
12
 *
13
 * @category  PHP
14
 * @package   PHPCompatibility
15
 * @author    Wim Godden <[email protected]>
16
 */
17
class PHPCompatibility_Sniffs_PHP_NewFunctionParametersSniff extends PHPCompatibility_Sniff
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
18
{
19
20
    /**
21
     * If true, forbidden functions will be considered regular expressions.
22
     *
23
     * @var bool
24
     */
25
    protected $patternMatch = false;
26
27
    /**
28
     * A list of new functions, not present in older versions.
29
     *
30
     * The array lists : version number with false (not present) or true (present).
31
     * The index is the location of the parameter in the parameter list, starting at 0 !
32
     * If's sufficient to list the first version where the function appears.
33
     *
34
     * @var array
35
     */
36
    protected $newFunctionParameters = array(
37
                                        'dirname' => array(
38
                                            1 => array(
39
                                                'name' => 'depth',
40
                                                '5.6' => false,
41
                                                '7.0' => true
42
                                            ),
43
                                        ),
44
                                        'unserialize' => array(
45
                                            1 => array(
46
                                                'name' => 'options',
47
                                                '5.6' => false,
48
                                                '7.0' => true
49
                                            ),
50
                                        ),
51
                                        'session_start' => array(
52
                                            0 => array(
53
                                                'name' => 'options',
54
                                                '5.6' => false,
55
                                                '7.0' => true
56
                                            )
57
                                        ),
58
                                        'strstr' => array(
59
                                            2 => array(
60
                                                'name' => 'before_needle',
61
                                                '5.2' => false,
62
                                                '5.3' => true
63
                                            )
64
                                        )
65
                                    );
66
67
68
    /**
69
     *
70
     * @var array
71
     */
72
    private $newFunctionParametersNames;
73
74
75
    /**
76
     * Returns an array of tokens this test wants to listen for.
77
     *
78
     * @return array
79
     */
80 View Code Duplication
    public function register()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    {
82
        // Everyone has had a chance to figure out what forbidden functions
83
        // they want to check for, so now we can cache out the list.
84
        $this->newFunctionParametersNames = array_keys($this->newFunctionParameters);
85
86
        if ($this->patternMatch === true) {
87
            foreach ($this->newFunctionParametersNames as $i => $name) {
88
                $this->newFunctionParametersNames[$i] = '/'.$name.'/i';
89
            }
90
        }
91
92
        return array(T_STRING);
93
    }//end register()
94
95
    /**
96
     * Processes this test, when one of its tokens is encountered.
97
     *
98
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
99
     * @param int                  $stackPtr  The position of the current token in
100
     *                                        the stack passed in $tokens.
101
     *
102
     * @return void
103
     */
104 View Code Duplication
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
    {
106
        $tokens = $phpcsFile->getTokens();
107
108
        $ignore = array(
109
                T_DOUBLE_COLON,
110
                T_OBJECT_OPERATOR,
111
                T_FUNCTION,
112
                T_CONST,
113
        );
114
115
        $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
116
        if (in_array($tokens[$prevToken]['code'], $ignore) === true) {
117
            // Not a call to a PHP function.
118
            return;
119
        }
120
121
        $function = strtolower($tokens[$stackPtr]['content']);
122
123
        if (in_array($function, $this->newFunctionParametersNames) === false) {
124
            return;
125
        }
126
127
        $parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr);
128
        if ($parameterCount === 0) {
129
            return;
130
        }
131
132
        // If the parameter count returned > 0, we know there will be valid open parenthesis.
133
        $openParenthesis = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
134
        $parameterOffsetFound = $parameterCount - 1;
135
136
        foreach($this->newFunctionParameters[$function] as $offset => $parameterDetails) {
137
            if ($offset <= $parameterOffsetFound) {
138
                $this->addError($phpcsFile, $openParenthesis, $function, $offset);
0 ignored issues
show
Security Bug introduced by
It seems like $openParenthesis defined by $phpcsFile->findNext(\PH...null, true, null, true) on line 133 can also be of type false; however, PHPCompatibility_Sniffs_...metersSniff::addError() does only seem to accept integer, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
139
            }
140
        }
141
142
    }//end process()
143
144
145
    /**
146
     * Generates the error or warning for this sniff.
147
     *
148
     * @param PHP_CodeSniffer_File $phpcsFile         The file being scanned.
149
     * @param int                  $stackPtr          The position of the function
150
     *                                                in the token array.
151
     * @param string               $function          The name of the function.
152
     * @param int                  $parameterLocation The parameter position within the function call.
153
     *
154
     * @return void
155
     */
156 View Code Duplication
    protected function addError($phpcsFile, $stackPtr, $function, $parameterLocation)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
    {
158
        $error = '';
159
160
        $isError = false;
161
        foreach ($this->newFunctionParameters[$function][$parameterLocation] as $version => $present) {
162
            if ($version != 'name' && $this->supportsBelow($version)) {
163
                if ($present === false) {
164
                    $isError = true;
165
                    $error .= 'in PHP version ' . $version . ' or earlier';
166
                }
167
            }
168
        }
169
170
        if (strlen($error) > 0) {
171
            $error = 'The function ' . $function . ' does not have a parameter ' . $this->newFunctionParameters[$function][$parameterLocation]['name'] . ' ' . $error;
172
173
            if ($isError === true) {
174
                $phpcsFile->addError($error, $stackPtr);
175
            } else {
176
                $phpcsFile->addWarning($error, $stackPtr);
177
            }
178
        }
179
180
    }//end addError()
181
182
}//end class
183