Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * Drupal_Sniffs_NamingConventions_ValidFunctionNameSniff.
|
Chris@0
|
4 *
|
Chris@0
|
5 * @category PHP
|
Chris@0
|
6 * @package PHP_CodeSniffer
|
Chris@0
|
7 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Drupal_Sniffs_NamingConventions_ValidFunctionNameSniff.
|
Chris@0
|
12 *
|
Chris@0
|
13 * Extends Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff to also check
|
Chris@0
|
14 * global function names outside the scope of classes and to not allow methods
|
Chris@0
|
15 * beginning with an underscore.
|
Chris@0
|
16 *
|
Chris@0
|
17 * @category PHP
|
Chris@0
|
18 * @package PHP_CodeSniffer
|
Chris@0
|
19 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
20 */
|
Chris@0
|
21 class Drupal_Sniffs_NamingConventions_ValidFunctionNameSniff extends Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff
|
Chris@0
|
22 {
|
Chris@0
|
23
|
Chris@0
|
24
|
Chris@0
|
25 /**
|
Chris@0
|
26 * Processes the tokens within the scope.
|
Chris@0
|
27 *
|
Chris@0
|
28 * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
|
Chris@0
|
29 * @param int $stackPtr The position where this token was
|
Chris@0
|
30 * found.
|
Chris@0
|
31 * @param int $currScope The position of the current scope.
|
Chris@0
|
32 *
|
Chris@0
|
33 * @return void
|
Chris@0
|
34 */
|
Chris@0
|
35 protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
|
Chris@0
|
36 {
|
Chris@0
|
37 $methodName = $phpcsFile->getDeclarationName($stackPtr);
|
Chris@0
|
38 if ($methodName === null) {
|
Chris@0
|
39 // Ignore closures.
|
Chris@0
|
40 return;
|
Chris@0
|
41 }
|
Chris@0
|
42
|
Chris@0
|
43 $className = $phpcsFile->getDeclarationName($currScope);
|
Chris@0
|
44 $errorData = array($className.'::'.$methodName);
|
Chris@0
|
45
|
Chris@0
|
46 // Is this a magic method. i.e., is prefixed with "__" ?
|
Chris@0
|
47 if (preg_match('|^__|', $methodName) !== 0) {
|
Chris@0
|
48 $magicPart = strtolower(substr($methodName, 2));
|
Chris@0
|
49 if (isset($this->magicMethods[$magicPart]) === false
|
Chris@0
|
50 && isset($this->methodsDoubleUnderscore[$magicPart]) === false
|
Chris@0
|
51 ) {
|
Chris@0
|
52 $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
|
Chris@0
|
53 $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData);
|
Chris@0
|
54 }
|
Chris@0
|
55
|
Chris@0
|
56 return;
|
Chris@0
|
57 }
|
Chris@0
|
58
|
Chris@0
|
59 $methodProps = $phpcsFile->getMethodProperties($stackPtr);
|
Chris@0
|
60 if (PHP_CodeSniffer::isCamelCaps($methodName, false, true, $this->strict) === false) {
|
Chris@0
|
61 if ($methodProps['scope_specified'] === true) {
|
Chris@0
|
62 $error = '%s method name "%s" is not in lowerCamel format';
|
Chris@0
|
63 $data = array(
|
Chris@0
|
64 ucfirst($methodProps['scope']),
|
Chris@0
|
65 $errorData[0],
|
Chris@0
|
66 );
|
Chris@0
|
67 $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data);
|
Chris@0
|
68 } else {
|
Chris@0
|
69 $error = 'Method name "%s" is not in lowerCamel format';
|
Chris@0
|
70 $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
|
Chris@0
|
71 }
|
Chris@0
|
72
|
Chris@0
|
73 $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'no');
|
Chris@0
|
74 return;
|
Chris@0
|
75 } else {
|
Chris@0
|
76 $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
|
Chris@0
|
77 }
|
Chris@0
|
78
|
Chris@0
|
79 }//end processTokenWithinScope()
|
Chris@0
|
80
|
Chris@0
|
81
|
Chris@0
|
82 /**
|
Chris@0
|
83 * Processes the tokens outside the scope.
|
Chris@0
|
84 *
|
Chris@0
|
85 * @param PHP_CodeSniffer_File $phpcsFile The file being processed.
|
Chris@0
|
86 * @param int $stackPtr The position where this token was
|
Chris@0
|
87 * found.
|
Chris@0
|
88 *
|
Chris@0
|
89 * @return void
|
Chris@0
|
90 */
|
Chris@0
|
91 protected function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
Chris@0
|
92 {
|
Chris@0
|
93 $functionName = $phpcsFile->getDeclarationName($stackPtr);
|
Chris@0
|
94 if ($functionName === null) {
|
Chris@0
|
95 // Ignore closures.
|
Chris@0
|
96 return;
|
Chris@0
|
97 }
|
Chris@0
|
98
|
Chris@0
|
99 $isApiFile = substr($phpcsFile->getFilename(), -8) === '.api.php';
|
Chris@0
|
100 $isHookExample = substr($functionName, 0, 5) === 'hook_';
|
Chris@0
|
101 if ($isApiFile === true && $isHookExample === true) {
|
Chris@0
|
102 // Ignore for examaple hook_ENTITY_TYPE_insert() functions in .api.php
|
Chris@0
|
103 // files.
|
Chris@0
|
104 return;
|
Chris@0
|
105 }
|
Chris@0
|
106
|
Chris@0
|
107 if ($functionName !== strtolower($functionName)) {
|
Chris@0
|
108 $expected = strtolower(preg_replace('/([^_])([A-Z])/', '$1_$2', $functionName));
|
Chris@0
|
109 $error = 'Invalid function name, expected %s but found %s';
|
Chris@0
|
110 $data = array(
|
Chris@0
|
111 $expected,
|
Chris@0
|
112 $functionName,
|
Chris@0
|
113 );
|
Chris@0
|
114 $phpcsFile->addError($error, $stackPtr, 'InvalidName', $data);
|
Chris@0
|
115 }
|
Chris@0
|
116
|
Chris@0
|
117 }//end processTokenOutsideScope()
|
Chris@0
|
118
|
Chris@0
|
119
|
Chris@0
|
120 }//end class
|