3
* PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff.
8
* @package PHP_CodeSniffer
9
* @author Greg Sherwood <gsherwood@squiz.net>
10
* @author Marc McIntyre <mmcintyre@squiz.net>
11
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
12
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
13
* @version CVS: $Id: ValidFunctionNameSniff.php,v 1.18 2008/01/22 23:50:23 squiz Exp $
14
* @link http://pear.php.net/package/PHP_CodeSniffer
17
if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) {
18
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found');
22
* PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff.
24
* Ensures method names are correct depending on whether they are public
25
* or private, and that functions are named correctly.
28
* @package PHP_CodeSniffer
29
* @author Greg Sherwood <gsherwood@squiz.net>
30
* @author Marc McIntyre <mmcintyre@squiz.net>
31
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
32
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
33
* @version Release: 1.0.1
34
* @link http://pear.php.net/package/PHP_CodeSniffer
36
class PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff
40
* A list of all PHP magic methods.
44
private $_magicMethods = array(
61
* A list of all PHP magic functions.
65
private $_magicFunctions = array(
71
* Constructs a PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff.
73
public function __construct()
75
parent::__construct(array(T_CLASS, T_INTERFACE), array(T_FUNCTION), true);
81
* Processes the tokens within the scope.
83
* @param PHP_CodeSniffer_File $phpcsFile The file being processed.
84
* @param int $stackPtr The position where this token was
86
* @param int $currScope The position of the current scope.
90
protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
92
$className = $phpcsFile->getDeclarationName($currScope);
93
$methodName = $phpcsFile->getDeclarationName($stackPtr);
95
// Is this a magic method. IE. is prefixed with "__".
96
if (preg_match('|^__|', $methodName) !== 0) {
97
$magicPart = substr($methodName, 2);
98
if (in_array($magicPart, $this->_magicMethods) === false) {
99
$error = "Method name \"$className::$methodName\" is invalid; only PHP magic methods should be prefixed with a double underscore";
100
$phpcsFile->addError($error, $stackPtr);
106
// PHP4 constructors are allowed to break our rules.
107
if ($methodName === $className) {
111
// PHP4 destructors are allowed to break our rules.
112
if ($methodName === '_'.$className) {
116
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
117
$isPublic = ($methodProps['scope'] === 'private') ? false : true;
118
$scope = $methodProps['scope'];
119
$scopeSpecified = $methodProps['scope_specified'];
121
// If it's a private method, it must have an underscore on the front.
122
if ($isPublic === false && $methodName{0} !== '_') {
123
$error = "Private method name \"$className::$methodName\" must be prefixed with an underscore";
124
$phpcsFile->addError($error, $stackPtr);
128
// If it's not a private method, it must not have an underscore on the front.
129
if ($isPublic === true && $scopeSpecified === true && $methodName{0} === '_') {
130
$error = ucfirst($scope)." method name \"$className::$methodName\" must not be prefixed with an underscore";
131
$phpcsFile->addError($error, $stackPtr);
135
// If the scope was specified on the method, then the method must be
136
// camel caps and an underscore should be checked for. If it wasn't
137
// specified, treat it like a public method and remove the underscore
138
// prefix if there is one because we cant determine if it is private or
140
$testMethodName = $methodName;
141
if ($scopeSpecified === false && $methodName{0} === '_') {
142
$testMethodName = substr($methodName, 1);
145
if (PHP_CodeSniffer::isCamelCaps($testMethodName, false, $isPublic, false) === false) {
146
if ($scopeSpecified === true) {
147
$error = ucfirst($scope)." method name \"$className::$methodName\" is not in camel caps format";
149
$error = "Method name \"$className::$methodName\" is not in camel caps format";
152
$phpcsFile->addError($error, $stackPtr);
156
}//end processTokenWithinScope()
160
* Processes the tokens outside the scope.
162
* @param PHP_CodeSniffer_File $phpcsFile The file being processed.
163
* @param int $stackPtr The position where this token was
168
protected function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
170
$functionName = $phpcsFile->getDeclarationName($stackPtr);
172
// Is this a magic function. IE. is prefixed with "__".
173
if (preg_match('|^__|', $functionName) !== 0) {
174
$magicPart = substr($functionName, 2);
175
if (in_array($magicPart, $this->_magicFunctions) === false) {
176
$error = "Function name \"$functionName\" is invalid; only PHP magic methods should be prefixed with a double underscore";
177
$phpcsFile->addError($error, $stackPtr);
183
// Function names can be in two parts; the package name and
184
// the function name.
187
$underscorePos = strrpos($functionName, '_');
188
if ($underscorePos === false) {
189
$camelCapsPart = $functionName;
191
$packagePart = substr($functionName, 0, $underscorePos);
192
$camelCapsPart = substr($functionName, ($underscorePos + 1));
194
// We don't care about _'s on the front.
195
$packagePart = ltrim($packagePart, '_');
198
// If it has a package part, make sure the first letter is a capital.
199
if ($packagePart !== '') {
200
if ($functionName{0} === '_') {
201
$error = "Function name \"$functionName\" is invalid; only private methods should be prefixed with an underscore";
202
$phpcsFile->addError($error, $stackPtr);
206
if ($functionName{0} !== strtoupper($functionName{0})) {
207
$error = "Function name \"$functionName\" is prefixed with a package name but does not begin with a capital letter";
208
$phpcsFile->addError($error, $stackPtr);
213
// If it doesn't have a camel caps part, it's not valid.
214
if (trim($camelCapsPart) === '') {
215
$error = "Function name \"$functionName\" is not valid; name appears incomplete";
216
$phpcsFile->addError($error, $stackPtr);
221
$newPackagePart = $packagePart;
222
$newCamelCapsPart = $camelCapsPart;
224
// Every function must have a camel caps part, so check that first.
225
if (PHP_CodeSniffer::isCamelCaps($camelCapsPart, false, true, false) === false) {
227
$newCamelCapsPart = strtolower($camelCapsPart{0}).substr($camelCapsPart, 1);
230
if ($packagePart !== '') {
231
// Check that each new word starts with a capital.
232
$nameBits = explode('_', $packagePart);
233
foreach ($nameBits as $bit) {
234
if ($bit{0} !== strtoupper($bit{0})) {
235
$newPackagePart = '';
236
foreach ($nameBits as $bit) {
237
$newPackagePart .= strtoupper($bit{0}).substr($bit, 1).'_';
246
if ($validName === false) {
247
$newName = rtrim($newPackagePart, '_').'_'.$newCamelCapsPart;
248
if ($newPackagePart === '') {
249
$newName = $newCamelCapsPart;
251
$newName = rtrim($newPackagePart, '_').'_'.$newCamelCapsPart;
254
$error = "Function name \"$functionName\" is invalid; consider \"$newName\" instead";
255
$phpcsFile->addError($error, $stackPtr);
258
}//end processTokenOutsideScope()