Completed
Push — master ( 570156...b64a33 )
by Alexander
02:47
created

ValidFunctionNameSniff::isExclusion()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 3
dl 0
loc 11
ccs 5
cts 5
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 37 and the first side effect is on line 18.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff.
4
 *
5
 * PHP version 5
6
 *
7
 * @category PHP
8
 * @package  PHP_CodeSniffer
9
 * @author   Greg Sherwood <[email protected]>
10
 * @author   Marc McIntyre <[email protected]>
11
 * @author   Alexander Obuhovich <[email protected]>
12
 * @license  https://github.com/aik099/CodingStandard/blob/master/LICENSE BSD 3-Clause
13
 * @link     https://github.com/aik099/CodingStandard
14
 */
15
16
// @codeCoverageIgnoreStart
17
if (class_exists('PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff', true) === false) {
18
    $error = 'Class PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff not found';
19
    throw new PHP_CodeSniffer_Exception($error);
20
}
21
// @codeCoverageIgnoreEnd
22
23
/**
24
 * CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff.
25
 *
26
 * Ensures method names are correct depending on whether they are public
27
 * or private, and that functions are named correctly.
28
 *
29
 * @category PHP
30
 * @package  PHP_CodeSniffer
31
 * @author   Greg Sherwood <[email protected]>
32
 * @author   Marc McIntyre <[email protected]>
33
 * @author   Alexander Obuhovich <[email protected]>
34
 * @license  https://github.com/aik099/CodingStandard/blob/master/LICENSE BSD 3-Clause
35
 * @link     https://github.com/aik099/CodingStandard
36
 */
37
class CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff extends
0 ignored issues
show
Coding Style introduced by
This class is not in CamelCase format.

Classes in PHP are usually named in CamelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.

Thus the name database provider becomes DatabaseProvider.

Loading history...
38
 PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff
39
{
40
41
    protected $exclusions = array(
42
        // Don't match to the end of class name to allow "SomeEventHandlerFeature" format.
43
        '/EventHandler/' => array(
44
            'SetCustomQuery',
45
            'CheckPermission',
46
            'BaseQuery',
47
            'ListPrepareQuery',
48
            'ItemPrepareQuery',
49
            'SetPagination',
50
            'SetSorting',
51
        ),
52
        // Don't match to the end of class name to allow "SomeTagProcessorFeature" format.
53
        '/TagProcessor/' => array(
54
            'PrepareListElementParams',
55
        ),
56
        '/Formatter$/' => array(
57
            'Format',
58
            'Parse',
59
            'PrepareOptions',
60
        ),
61
        '/Validator$/' => array(
62
            'GetErrorMsg',
63
            'CustomValidation',
64
            'SetError',
65
        ),
66
        '/ShippingQuoteEngine$/' => array(
67
            'GetShippingQuotes',
68
            'GetAvailableTypes',
69
            'GetEngineFields',
70
            'MakeOrder',
71
        ),
72
        '/Helper$/' => array(
73
            'Init',
74
            'InitHelper',
75
        ),
76
        '/Item$/' => array('*'),
77
        '/List$/' => array('*'),
78
        '/DBConnection/' => array('*'),
79
        '/DBLoadBalancer$/' => array('*'),
80
        '/Application$/' => array('*'),
81
    );
82
83
    /**
84
     * Processes the tokens within the scope.
85
     *
86
     * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
87
     * @param int                  $stackPtr  The position where this token was
88
     *                                        found.
89
     * @param int                  $currScope The position of the current scope.
90
     *
91
     * @return void
92
     */
93 1
    protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
94
    {
95 1
        $methodName = $phpcsFile->getDeclarationName($stackPtr);
96 1
        if ($methodName === null) {
97
            // Ignore closures.
98
            return;
99
        }
100
101 1
        $className = $phpcsFile->getDeclarationName($currScope);
102 1
        $errorData = array($className.'::'.$methodName);
103
104
        // Is this a magic method. i.e., is prefixed with "__" ?
105 1
        if (preg_match('|^__|', $methodName) !== 0) {
106 1
            $magicPart = strtolower(substr($methodName, 2));
107
108 1
            if (isset($this->magicMethods[$magicPart]) === false) {
109 1
                $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
110 1
                $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData);
111
            }
112
113 1
            return;
114
        }
115
116
        // PHP4 constructors are allowed to break our rules.
117 1
        if ($methodName === $className) {
118 1
            return;
119
        }
120
121
        // PHP4 destructors are allowed to break our rules.
122 1
        if ($methodName === '_'.$className) {
123 1
            return;
124
        }
125
126 1
        $methodProps    = $phpcsFile->getMethodProperties($stackPtr);
127 1
        $isPublic       = ($methodProps['scope'] === 'private') ? false : true;
128 1
        $scope          = $methodProps['scope'];
129 1
        $scopeSpecified = $methodProps['scope_specified'];
130
131
        // If it's a private method, it must have an underscore on the front.
132 1
        if ($isPublic === false) {
133 1
            if ($methodName{0} !== '_') {
134 1
                $error = 'Private method name "%s" must be prefixed with an underscore';
135 1
                $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData);
136
137 1
                if (isset($phpcsFile->fixer) === true) {
138 1
                    $phpcsFile->recordMetric($stackPtr, 'Private method prefixed with underscore', 'no');
139
                }
140
141 1
                return;
142
            } else {
143 1
                if (isset($phpcsFile->fixer) === true) {
144 1
                    $phpcsFile->recordMetric($stackPtr, 'Private method prefixed with underscore', 'yes');
145
                }
146
            }
147
        }
148
149
        // If it's not a private method, it must not have an underscore on the front.
150 1
        if ($isPublic === true && $scopeSpecified === true && $methodName{0} === '_') {
151 1
            $error = '%s method name "%s" must not be prefixed with an underscore';
152
            $data  = array(
153 1
                      ucfirst($scope),
154 1
                      $errorData[0],
155
                     );
156 1
            $phpcsFile->addError($error, $stackPtr, 'PublicUnderscore', $data);
157 1
            return;
158
        }
159
160
        // If the scope was specified on the method, then the method must be
161
        // camel caps and an underscore should be checked for. If it wasn't
162
        // specified, treat it like a public method and remove the underscore
163
        // prefix if there is one because we cant determine if it is private or
164
        // public.
165 1
        $testMethodName = $methodName;
166 1
        if ($scopeSpecified === false && $methodName{0} === '_') {
167 1
            $testMethodName = substr($methodName, 1);
168
        }
169
170 1
        $methodParams = $phpcsFile->getMethodParameters($stackPtr);
171
172 1
        if ($this->isExclusion($className, $methodName, $isPublic) === true
173 1
            || $this->isEventHandlerExclusion($className, $methodName, $methodParams) === true
174 1
            || $this->isTagProcessorExclusion($className, $methodName, $methodParams) === true
175
        ) {
176 1
            return;
177
        }
178
179 1
        if (PHP_CodeSniffer::isCamelCaps($testMethodName, false, $isPublic, false) === false) {
180 1
            if ($scopeSpecified === true) {
181 1
                $error = '%s method name "%s" is not in camel caps format';
182
                $data  = array(
183 1
                          ucfirst($scope),
184 1
                          $errorData[0],
185
                         );
186 1
                $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data);
187
            } else {
188 1
                $error = 'Method name "%s" is not in camel caps format';
189 1
                $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
190
            }
191
192 1
            return;
193
        }
194
195 1
    }//end processTokenWithinScope()
196
197
    /**
198
     * Determines if a method name shouldn't be checked for camelCaps format.
199
     *
200
     * @param string $className  Class name.
201
     * @param string $methodName Method name.
202
     * @param bool   $isPublic   Public.
203
     *
204
     * @return bool
205
     */
206 1
    protected function isExclusion($className, $methodName, $isPublic)
207
    {
208 1
        foreach ($this->exclusions as $classRegExp => $excludedMethods) {
209 1
            if (preg_match($classRegExp, $className)) {
210 1
                return ($excludedMethods[0] == '*' && $isPublic) || in_array($methodName, $excludedMethods);
211
            }
212
        }
213
214 1
        return false;
215
216
    }//end isExclusion()
217
218
    /**
219
     * Determines if a method is an event in the event handler class.
220
     *
221
     * @param string $className    Class name.
222
     * @param string $methodName   Method name.
223
     * @param array  $methodParams Method parameters.
224
     *
225
     * @return bool
226
     */
227 1
    protected function isEventHandlerExclusion($className, $methodName, array $methodParams)
228
    {
229 1
        if (strpos($className, 'EventHandler') === false) {
230
            // Not EventHandler class.
231 1
            return false;
232
        }
233
234 1
        return substr($methodName, 0, 2) == 'On' && count($methodParams) === 1 && $methodParams[0]['name'] === '$event';
235
236
    }//end isEventHandlerExclusion()
237
238
239
    /**
240
     * Determines if a method is an tag in the tag processor class.
241
     *
242
     * @param string $className    Class name.
243
     * @param string $methodName   Method name.
244
     * @param array  $methodParams Method parameters.
245
     *
246
     * @return bool
247
     */
248 1
    protected function isTagProcessorExclusion($className, $methodName, array $methodParams)
0 ignored issues
show
Unused Code introduced by
The parameter $methodName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
249
    {
250 1
        if (strpos($className, 'TagProcessor') === false) {
251
            // Not TagProcessor class.
252 1
            return false;
253
        }
254
255
        return count($methodParams) === 1 && $methodParams[0]['name'] === '$params';
256
257
    }//end isTagProcessorExclusion()
258
259
260
}//end class
261