• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPCSStandards / PHP_CodeSniffer / 11374498954

16 Oct 2024 09:58PM UTC coverage: 75.662% (-1.0%) from 76.652%
11374498954

Pull #631

github

web-flow
Merge 567e361af into 16c087f0e
Pull Request #631: GH Actions/remove labels: update lists of labels to auto-remove

23372 of 30890 relevant lines covered (75.66%)

61.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.14
/src/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php
1
<?php
2
/**
3
 * Ensures method and functions are named correctly.
4
 *
5
 * @author    Greg Sherwood <gsherwood@squiz.net>
6
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
7
 * @license   https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8
 */
9

10
namespace PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions;
11

12
use PHP_CodeSniffer\Files\File;
13
use PHP_CodeSniffer\Sniffs\AbstractScopeSniff;
14
use PHP_CodeSniffer\Util\Common;
15
use PHP_CodeSniffer\Util\Tokens;
16

17
class CamelCapsFunctionNameSniff extends AbstractScopeSniff
18
{
19

20
    /**
21
     * A list of all PHP magic methods.
22
     *
23
     * @var array
24
     */
25
    protected $magicMethods = [
26
        'construct'   => true,
27
        'destruct'    => true,
28
        'call'        => true,
29
        'callstatic'  => true,
30
        'get'         => true,
31
        'set'         => true,
32
        'isset'       => true,
33
        'unset'       => true,
34
        'sleep'       => true,
35
        'wakeup'      => true,
36
        'serialize'   => true,
37
        'unserialize' => true,
38
        'tostring'    => true,
39
        'invoke'      => true,
40
        'set_state'   => true,
41
        'clone'       => true,
42
        'debuginfo'   => true,
43
    ];
44

45
    /**
46
     * A list of all PHP non-magic methods starting with a double underscore.
47
     *
48
     * These come from PHP modules such as SOAPClient.
49
     *
50
     * @var array
51
     */
52
    protected $methodsDoubleUnderscore = [
53
        'dorequest'              => true,
54
        'getcookies'             => true,
55
        'getfunctions'           => true,
56
        'getlastrequest'         => true,
57
        'getlastrequestheaders'  => true,
58
        'getlastresponse'        => true,
59
        'getlastresponseheaders' => true,
60
        'gettypes'               => true,
61
        'setcookie'              => true,
62
        'setlocation'            => true,
63
        'setsoapheaders'         => true,
64
        'soapcall'               => true,
65
    ];
66

67
    /**
68
     * A list of all PHP magic functions.
69
     *
70
     * @var array
71
     */
72
    protected $magicFunctions = ['autoload' => true];
73

74
    /**
75
     * If TRUE, the string must not have two capital letters next to each other.
76
     *
77
     * @var boolean
78
     */
79
    public $strict = true;
80

81

82
    /**
83
     * Constructs a Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff.
84
     */
85
    public function __construct()
3✔
86
    {
87
        parent::__construct(Tokens::$ooScopeTokens, [T_FUNCTION], true);
3✔
88

89
    }//end __construct()
2✔
90

91

92
    /**
93
     * Processes the tokens within the scope.
94
     *
95
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being processed.
96
     * @param int                         $stackPtr  The position where this token was
97
     *                                               found.
98
     * @param int                         $currScope The position of the current scope.
99
     *
100
     * @return void
101
     */
102
    protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
3✔
103
    {
104
        $tokens = $phpcsFile->getTokens();
3✔
105

106
        // Determine if this is a function which needs to be examined.
107
        $conditions = $tokens[$stackPtr]['conditions'];
3✔
108
        end($conditions);
3✔
109
        $deepestScope = key($conditions);
3✔
110
        if ($deepestScope !== $currScope) {
3✔
111
            return;
3✔
112
        }
113

114
        $methodName = $phpcsFile->getDeclarationName($stackPtr);
3✔
115
        if ($methodName === null) {
3✔
116
            // Ignore closures.
117
            return;
×
118
        }
119

120
        $className = $phpcsFile->getDeclarationName($currScope);
3✔
121
        if (isset($className) === false) {
3✔
122
            $className = '[Anonymous Class]';
3✔
123
        }
1✔
124

125
        $errorData = [$className.'::'.$methodName];
3✔
126

127
        $methodNameLc = strtolower($methodName);
3✔
128
        $classNameLc  = strtolower($className);
3✔
129

130
        // Is this a magic method. i.e., is prefixed with "__" ?
131
        if (preg_match('|^__[^_]|', $methodName) !== 0) {
3✔
132
            $magicPart = substr($methodNameLc, 2);
3✔
133
            if (isset($this->magicMethods[$magicPart]) === true
3✔
134
                || isset($this->methodsDoubleUnderscore[$magicPart]) === true
3✔
135
            ) {
1✔
136
                return;
3✔
137
            }
138

139
            $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
3✔
140
            $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData);
3✔
141
        }
1✔
142

143
        // PHP4 constructors are allowed to break our rules.
144
        if ($methodNameLc === $classNameLc) {
3✔
145
            return;
3✔
146
        }
147

148
        // PHP4 destructors are allowed to break our rules.
149
        if ($methodNameLc === '_'.$classNameLc) {
3✔
150
            return;
3✔
151
        }
152

153
        // Ignore first underscore in methods prefixed with "_".
154
        $methodName = ltrim($methodName, '_');
3✔
155

156
        $methodProps = $phpcsFile->getMethodProperties($stackPtr);
3✔
157
        if (Common::isCamelCaps($methodName, false, true, $this->strict) === false) {
3✔
158
            if ($methodProps['scope_specified'] === true) {
3✔
159
                $error = '%s method name "%s" is not in camel caps format';
3✔
160
                $data  = [
1✔
161
                    ucfirst($methodProps['scope']),
3✔
162
                    $errorData[0],
3✔
163
                ];
2✔
164
                $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data);
3✔
165
            } else {
1✔
166
                $error = 'Method name "%s" is not in camel caps format';
3✔
167
                $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
3✔
168
            }
169

170
            $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'no');
3✔
171
            return;
3✔
172
        } else {
173
            $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
3✔
174
        }
175

176
    }//end processTokenWithinScope()
2✔
177

178

179
    /**
180
     * Processes the tokens outside the scope.
181
     *
182
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being processed.
183
     * @param int                         $stackPtr  The position where this token was
184
     *                                               found.
185
     *
186
     * @return void
187
     */
188
    protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
3✔
189
    {
190
        $functionName = $phpcsFile->getDeclarationName($stackPtr);
3✔
191
        if ($functionName === null) {
3✔
192
            // Ignore closures.
193
            return;
×
194
        }
195

196
        $errorData = [$functionName];
3✔
197

198
        // Is this a magic function. i.e., it is prefixed with "__".
199
        if (preg_match('|^__[^_]|', $functionName) !== 0) {
3✔
200
            $magicPart = strtolower(substr($functionName, 2));
3✔
201
            if (isset($this->magicFunctions[$magicPart]) === true) {
3✔
202
                return;
3✔
203
            }
204

205
            $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
3✔
206
            $phpcsFile->addError($error, $stackPtr, 'FunctionDoubleUnderscore', $errorData);
3✔
207
        }
1✔
208

209
        // Ignore first underscore in functions prefixed with "_".
210
        $functionName = ltrim($functionName, '_');
3✔
211

212
        if (Common::isCamelCaps($functionName, false, true, $this->strict) === false) {
3✔
213
            $error = 'Function name "%s" is not in camel caps format';
3✔
214
            $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
3✔
215
            $phpcsFile->recordMetric($stackPtr, 'CamelCase function name', 'no');
3✔
216
        } else {
1✔
217
            $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
3✔
218
        }
219

220
    }//end processTokenOutsideScope()
2✔
221

222

223
}//end class
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc