Completed
Pull Request — master (#291)
by Juliette
02:26
created

process()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 55
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 55
rs 7.2446
c 0
b 0
f 0
cc 9
eloc 26
nc 9
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * PHPCompatibility_Sniffs_PHP_RemovedExtensionsSniff.
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  PHP
8
 * @package   PHPCompatibility
9
 * @author    Wim Godden <[email protected]>
10
 * @copyright 2012 Cu.be Solutions bvba
11
 */
12
13
/**
14
 * PHPCompatibility_Sniffs_PHP_RemovedExtensionsSniff.
15
 *
16
 * Discourages the use of removed extensions. Suggests alternative extensions if available
17
 *
18
 * @category  PHP
19
 * @package   PHPCompatibility
20
 * @author    Wim Godden <[email protected]>
21
 * @copyright 2012 Cu.be Solutions bvba
22
 */
23
class PHPCompatibility_Sniffs_PHP_RemovedExtensionsSniff
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...
24
    extends PHPCompatibility_AbstractRemovedFeatureSniff
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
25
{
26
    /**
27
     * A list of functions to whitelist, if any.
28
     *
29
     * This is intended for projects using functions which start with the same
30
     * prefix as one of the removed extensions.
31
     *
32
     * This property can be set from the ruleset, like so:
33
     * <rule ref="PHPCompatibility.PHP.RemovedExtensions">
34
     *   <properties>
35
     *     <property name="functionWhitelist" type="array" value="mysql_to_rfc3339,mysql_another_function" />
36
     *   </properties>
37
     * </rule>
38
     *
39
     * @var array
40
     */
41
    public $functionWhitelist;
42
43
    /**
44
     * A list of removed extensions with their alternative, if any
45
     *
46
     * The array lists : version number with false (deprecated) and true (removed).
47
     * If's sufficient to list the first version where the extension was deprecated/removed.
48
     *
49
     * @var array(string|null)
50
     */
51
    protected $removedExtensions = array(
52
        'activescript' => array(
53
                '5.1' => true,
54
                'alternative' => 'pecl/activescript'
55
        ),
56
        'cpdf' => array(
57
                '5.1' => true,
58
                'alternative' => 'pecl/pdflib'
59
        ),
60
        'dbase' => array(
61
                '5.3' => true,
62
                'alternative' => null
63
        ),
64
        'dbx' => array(
65
                '5.1' => true,
66
                'alternative' => 'pecl/dbx'
67
        ),
68
        'dio' => array(
69
                '5.1' => true,
70
                'alternative' => 'pecl/dio'
71
        ),
72
        'ereg' => array(
73
                '5.3' => false,
74
                '7.0' => true,
75
                'alternative' => 'pcre'
76
        ),
77
        'fam' => array(
78
                '5.1' => true,
79
                'alternative' => null
80
        ),
81
        'fbsql' => array(
82
                '5.3' => true,
83
                'alternative' => null
84
        ),
85
        'fdf' => array(
86
                '5.3' => true,
87
                'alternative' => 'pecl/fdf'
88
        ),
89
        'filepro' => array(
90
                '5.2' => true,
91
                'alternative' => null
92
        ),
93
        'hw_api' => array(
94
                '5.2' => true,
95
                'alternative' => null
96
        ),
97
        'ingres' => array(
98
                '5.1' => true,
99
                'alternative' => 'pecl/ingres'
100
        ),
101
        'ircg' => array(
102
                '5.1' => true,
103
                'alternative' => null
104
        ),
105
        'mcrypt' => array(
106
                '7.1' => false,
107
                'alternative' => 'openssl (preferred) or pecl/mcrypt once available'
108
        ),
109
        'mcve' => array(
110
                '5.1' => true,
111
                'alternative' => 'pecl/mvce'
112
        ),
113
        'ming' => array(
114
                '5.3' => true,
115
                'alternative' => 'pecl/ming'
116
        ),
117
        'mnogosearch' => array(
118
                '5.1' => true,
119
                'alternative' => null
120
        ),
121
        'msql' => array(
122
                '5.3' => true,
123
                'alternative' => null
124
        ),
125
        'mssql' => array(
126
                '7.0' => true,
127
                'alternative' => null
128
        ),
129
        'mysql_' => array(
130
                '5.5' => false,
131
                '7.0' => true,
132
                'alternative' => 'mysqli',
133
        ),
134
        'ncurses' => array(
135
                '5.3' => true,
136
                'alternative' => 'pecl/ncurses'
137
        ),
138
        'oracle' => array(
139
                '5.1' => true,
140
                'alternative' => 'oci8 or pdo_oci'
141
        ),
142
        'ovrimos' => array(
143
                '5.1' => true,
144
                'alternative' => null
145
        ),
146
        'pfpro' => array(
147
                '5.3' => true,
148
                'alternative' => null
149
        ),
150
        'sqlite' => array(
151
                '5.4' => true,
152
                'alternative' => null
153
        ),
154
        // Has to be before `sybase` as otherwise it will never match.
155
        'sybase_ct' => array(
156
                '7.0' => true,
157
                'alternative' => null
158
        ),
159
        'sybase' => array(
160
                '5.3' => true,
161
                'alternative' => 'sybase_ct'
162
        ),
163
        'w32api' => array(
164
                '5.1' => true,
165
                'alternative' => 'pecl/ffi'
166
        ),
167
        'yp' => array(
168
                '5.1' => true,
169
                'alternative' => null
170
        ),
171
    );
172
173
    /**
174
     * Returns an array of tokens this test wants to listen for.
175
     *
176
     * @return array
177
     */
178
    public function register()
179
    {
180
        // Handle case-insensitivity of function names.
181
        $this->removedExtensions = $this->arrayKeysToLowercase($this->removedExtensions);
182
183
        return array(T_STRING);
184
185
    }//end register()
186
187
    /**
188
     * Processes this test, when one of its tokens is encountered.
189
     *
190
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
191
     * @param int                  $stackPtr  The position of the current token in the
192
     *                                        stack passed in $tokens.
193
     *
194
     * @return void
195
     */
196
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
197
    {
198
        $tokens = $phpcsFile->getTokens();
199
200
        // Find the next non-empty token.
201
        $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true);
202
203
        if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
204
            // Not a function call.
205
            return;
206
        }
207
208
        if (isset($tokens[$openBracket]['parenthesis_closer']) === false) {
209
            // Not a function call.
210
            return;
211
        }
212
213
        // Find the previous non-empty token.
214
        $search   = PHP_CodeSniffer_Tokens::$emptyTokens;
215
        $search[] = T_BITWISE_AND;
216
        $previous = $phpcsFile->findPrevious($search, ($stackPtr - 1), null, true);
217
        if ($tokens[$previous]['code'] === T_FUNCTION) {
218
            // It's a function definition, not a function call.
219
            return;
220
        }
221
222
        if ($tokens[$previous]['code'] === T_NEW) {
223
            // We are creating an object, not calling a function.
224
            return;
225
        }
226
227
        if ( $tokens[$previous]['code'] === T_OBJECT_OPERATOR ) {
228
            // We are calling a method of an object
229
            return;
230
        }
231
232
        $function   = $tokens[$stackPtr]['content'];
233
        $functionLc = strtolower($function);
234
235
        if($this->isWhiteListed($functionLc) === true){
236
            // Function is whitelisted.
237
            return;
238
        }
239
240
        foreach ($this->removedExtensions as $extension => $versionList) {
241
            if (strpos($functionLc, $extension) === 0) {
242
                $itemInfo = array(
243
                    'name'   => $extension,
244
                );
245
                $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
246
                break;
247
            }
248
        }
249
250
    }//end process()
251
252
253
    /**
254
     * Is the current function being checked whitelisted ?
255
     *
256
     * Parsing the list late as it may be provided as a property, but also inline.
257
     *
258
     * @param string $content Content of the current token.
259
     *
260
     * @return bool
261
     */
262
    protected function isWhiteListed($content) {
263
        if (isset($this->functionWhitelist) === false) {
264
            return false;
265
        }
266
267
        if (is_string($this->functionWhitelist) === true) {
268
            if (strpos($this->functionWhitelist, ',') !== false) {
269
                $this->functionWhitelist = explode(',', $this->functionWhitelist);
270
            } else {
271
                $this->functionWhitelist = (array) $this->functionWhitelist;
272
            }
273
        }
274
275
        if (is_array($this->functionWhitelist) === true) {
276
            $this->functionWhitelist = array_map('strtolower',$this->functionWhitelist);
277
            return in_array($content, $this->functionWhitelist, true);
278
        }
279
280
        return false;
281
282
    }//end isWhiteListed()
283
284
285
    /**
286
     * Get the relevant sub-array for a specific item from a multi-dimensional array.
287
     *
288
     * @param array $itemInfo Base information about the item.
289
     *
290
     * @return array Version and other information about the item.
291
     */
292
    public function getItemArray(array $itemInfo)
293
    {
294
        return $this->removedExtensions[$itemInfo['name']];
295
    }
296
297
298
    /**
299
     * Get the error message template for this sniff.
300
     *
301
     * @return string
302
     */
303
    protected function getErrorMsgTemplate()
304
    {
305
        return "Extension '%s' is ";
306
    }
307
308
309
}//end class
310